项目:调查问卷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{
width: 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;
width: 60px;
height: 30px;
margin-left: 10px;
cursor: pointer;
font-size: 14px;
}
</style>