项目:调查问卷WebApp 。
描述:制作一个简单的调查问卷HTML 5 小应用,每页有一道题目,题目可以是单选题、多
选题、填写题等。
说明:每一页可以通过v -show 或v-if 在切换步骤时显示,点击重置,当前页的控件还原到初始状态。要对每页的数据进行校验,比如单选题必须要选择,多选题最少选择2 项,最多选择3项,文本框输入不能少于100 字,若当前页不满足验证要求,则下一步的按钮置灰,不可点击。
要求: 按钮要制作成组件,可以控制颜色、状态(禁用),点击后传递一个自定义事件on-cl ick 。
解答:
Q:
每一页可以通过v -show 或v-if 在切换步骤时显示
A
给每一页添加show数据,默认显示第一页,其他页面隐藏
当点击 第一页的下一步按钮后,设置所有页面的show为false,再设置p2的show为true
当点击 第二页的下一步按钮后,设置所有页面的show为false,再设置p3的show为true
当点击 第二页的上一步按钮后,设置所有页面的show为false,再设置p1的show为true
Q:
点击重置,当前页的控件还原到初始状态
A
监听组件的自定义事件 on-click,监听到事件后,再调用本地handler,恢复当前页面每一项的默认值
Q:
要对每页的数据进行校验,比如单选题必须要选择,多选题最少j制幸2 项,最多选择3项,文本框输入不能少于100 字,若当前页不满足验证要求,则下一步的按钮置灰,不可点击
A:
Watch页面每一项的数据,如未满足要求,则传递给按钮的disabled属性为false
留意,需用v-model绑定每一控件的数据,以方便检测
Q:
要求: 按钮要制作成组件,可以控制颜色、状态(禁用),点击后传递一个自定义事件on-cl ick 。
A
使用props,传递一个classObject对象给组件,用来控制按钮的颜色(字体和背景,等等)
传递 isDisabled,控制按钮的状态(禁用/开启)
当按钮被点击后,使用$emit传递自定义事件on-click,当父组件监听到此自定义事件,调用父组件handler,进行相应操作(切换show的真假值,重置当前页面内容,等等)
项目构成:App.vue, buttons.vue
app.vue源码:
<template> <div id="app"> <div class="page" v-show="show[0].isShow"> <div class="question"> <p>1.请问您的性别是:</p> <input type="radio" v-model="picked" value="male" id="male"> <label for="male">男</label> <input type="radio" v-model="picked" value="female" id="female"> <label for="female">女</label> <input type="radio" v-model="picked" value="secret" id="secret"> <label for="secret">保密</label> </div> <buttons :classObject="classObject" :isDisabled="isp1Disabled" @on-click="handlecustomClick(1)" >下一步</buttons> <buttons :classObject="classObject" @on-click="handleReset(0)" >重置</buttons> </div> <div class="page" v-show="show[1].isShow"> <div class="question"> <p>2.请选择您的兴趣爱好:</p> <input type="checkbox" v-model="checked" value="read" id="read"> <label for="read">看书</label> <br/> <input type="checkbox" v-model="checked" value="swim" id="swim"> <label for="swim">游泳</label> <br/> <input type="checkbox" v-model="checked" value="run" id="run"> <label for="run">跑步</label> <br/> <input type="checkbox" v-model="checked" value="movie" id="movie"> <label for="movie">看电影</label> <br/> <input type="checkbox" v-model="checked" value="music" id="music"> <label for="music">听音乐</label> <br/> </div> <buttons :classObject="classObject" :isDisabled="isp2Disabled" @on-click="handlecustomClick(2)" >下一步</buttons> <buttons :classObject="classObject" :isDisabled="isp2Disabled" @on-click="handlecustomClick(0)" >上一步</buttons> <buttons :classObject="classObject" @on-click="handleReset(1)" >重置</buttons> </div> <div class="page" v-show="show[2].isShow"> <div class="question"> <p>3.请介绍一下自己:</p> <textarea v-model="message" placeholder="不少于100字"></textarea> </div> <buttons :classObject="classObject" :isDisabled="isp3Disabled">提交</buttons> <buttons :classObject="classObject" :isDisabled="isp3Disabled" @on-click="handlecustomClick(1)" >上一步</buttons> <buttons :classObject="classObject" @on-click="handleReset(2)" >重置</buttons> </div> </div> </template> <script> import buttons from './components/buttons'; export default { components:{ buttons }, data(){ return{ show:[ {isShow:true}, {isShow:false}, {isShow:false} ], message:'', picked:'', checked:[], isp1Disabled:true, isp2Disabled:true, isp3Disabled:true, classObject:{ colorbackground:true } } }, methods:{ handlecustomClick(count){ for(var i=0;i<this.show.length;i++) this.show[i].isShow=false; this.show[count].isShow=true; }, handleReset(count){ switch(count){ case 0: this.picked=''; this.isp1Disabled=true; break; case 1: this.checked=[]; if(this.checked.length===2){ this.isp2Disabled=true; } break; case 2: this.message=''; this.isp3Disabled=true; break; } } }, watch:{ picked(){ if(this.picked){ this.isp1Disabled = false; }else{ this.isp1Disabled=true; } }, checked(){ if(this.checked.length>=2){ this.isp2Disabled=false; }else{ this.isp2Disabled=true; } }, message(){ var len=0; for(var i=0;i<this.message.length;i++) len += /[^x00-xff]/g.test(this.message.charAt(i)) ? 1 : 0.5; if(len >= 100){ this.isp3Disabled=false; }else{ this.isp3Disabled=true; } } } } </script> <style scoped> .page{ 300px; height: 500px; background: #fff; border: 1px solid #d0d0d0; border-radius: 5px; margin: 10px; padding-top: 5px; } .question{ height: 450px; } .colorbackground{ } </style>
buttons.vue源码:
<template> <button @click="handleClick" :class="classObject" :disabled="isDisabled" > <slot></slot> </button> </template> <script> export default { props:{ classObject:{ type:Object, default:null }, isDisabled:{ type:Boolean, default:false } }, methods:{ handleClick(){ this.$emit('on-click'); } } } </script> <style scoped> button{ border: 0; 60px; height: 30px; margin-left: 10px; cursor: pointer; font-size: 14px; } </style>