《Vue.j实战》一书 p131 调查问卷 WebApp 试做

项目:调查问卷WebApp 。
描述:制作一个简单的调查问卷HTML 5 小应用,每页有一道题目,题目可以是单选题、多
选题、填写题等。

说明:每一页可以通过v -show 或v-if 在切换步骤时显示,点击重置,当前页的控件还原到初始状态。要对每页的数据进行校验,比如单选题必须要选择,多选题最少选择2 项,最多选择3项,文本框输入不能少于100 字,若当前页不满足验证要求,则下一步的按钮置灰,不可点击。

要求: 按钮要制作成组件,可以控制颜色、状态(禁用),点击后传递一个自定义事件on-cl ick 。

Demo在线效果浏览

解答:

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>

 

posted @ 2019-08-15 16:07  sx00xs  阅读(804)  评论(0编辑  收藏  举报