美文网首页vue.js调查问卷
Vue2.0 完成调查问卷WebApp

Vue2.0 完成调查问卷WebApp

作者: yancolin | 来源:发表于2018-04-26 17:28 被阅读1762次

最近一直在看vue.js实战,里面有一个项目实践,需求与效果如下:


效果
需求

我现在把此项目分成index.html,question.js,index.js以及style.css四个文件(其中说到的按钮制作成组件,可以自己实现,我这里就没做)。

注:此处是手机端,请调整到手机调试下跑该项目。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app" v-cloak>
    <question v-model="page"></question>
</div>
<script src="question.js"></script>
<script src="index.js"></script>
</body>
</html>

index.html 注意:v-model是双向绑定的数据,其实这里用v-bind也可以,它与v-model的区别是v-bind是单向数据流,而v-model是双向数据流。也就是子组件可以通过$emit来传递数据回父组件,而v-bind只能是从父组件传递数据到子组件。

question.js

Vue.component('question',{
    props:['value'],
    template: '<div><div style="height:100%" v-if="this.page == 1"><span>1.请问您的性别是:</span>'
        + '<div class="options" v-for="(item,index) in sex_list">'
        + '<input :value="item.name" type="radio" @change="radio_change($event,index)" name="sexy" :checked="item.checked">{{item.name}}'
        + '</div>'
        + '<div class="step_bottom">'
        + '<button :disabled="disabledOne" :class="[{disabledColor: disabledOne},buttonone,greycolor]" @click="nextQuestionTwo">下一步</button>'
        + '<button @click="restartQuestionOne" :class="[buttonone]">重置</button>'
        + '</div></div>'
        + '<div v-else-if="this.page == 2"><span>2.请选择您的兴趣爱好:</span>'
        + '<div class="options" v-for="(item,index) in hobbies">'
        + '<input type="checkbox" name="hobbies" value="item.name" @change="checkboxChange($event,index)" :checked="item.checked">{{item.name}}<br>'
        + '</div>'
        + '<div class="step_bottom second_quesiton">'
        + '<button :disabled="disabledTwo" :class="[greycolor,{disabledColor: disabledTwo}]" @click="nextQuestionThree">下一步</button>'
        + '<button @click="lastStepOne">上一步</button>'
        + '<button @click="restartQuestionTwo">重置</button>'
        + '</div></div>'
        + '<div v-else><span>3.请介绍一下自己:</span>'
        + '<div><textarea name="introduction" autofocus rows="10" cols="40" @blur="checkLength" :value="text"></textarea></div>'
        + '<div class="step_bottom second_quesiton">'
        + '<button :disabled="disabledThree" :class="[greycolor,{disabledColor: disabledThree}]" @click="submit">提交</button>'
        + '<button class="" @click="lastStepTwo">上一步</button>'
        + '<button class="" @click="restartQuestionThree">重置</button>'
        + '</div></div></div>',
    data:function () {
        return{
            sex_list:[
                {name:'男'},
                {name:'女'},
                {name:'保密'}
            ],
            hobbies: [
                {name:'看书'},
                {name:'游泳'},
                {name:'跑步'},
                {name:'看电影'},
                {name:'听音乐'}
            ],
            disabledOne: true,
            disabledTwo: true,
            disabledThree: true,
            buttonone:'buttonOne',
            greycolor:'greyColor',
            text:'',
            page: this.value,
            user_data:{
            }
        }
    },
    methods:{
        radio_change: function (el,index) {
            var radio_value = el.target.value;
            if( typeof radio_value != 'undefined' && radio_value != '' ){
                this.disabledOne = false;
                this.sex_list[index].checked = true;
            }else{
                this.disabledOne = true;
            }
        },
        checkboxChange: function (el,index) {
            var boxvalue = el.target.checked;
            var count = 0;
            if( boxvalue == true ){
                this.hobbies[index].checked = true;
            }else{
                this.hobbies[index].checked = false;
            }

            this.hobbies.forEach(function (item) {
                if( item.checked == true ){
                    count ++;
                }
            });

            if( count >=2 ){
                this.disabledTwo = false;
            }else {
                this.disabledTwo = true;
            }
        },
        checkLength:function (el) {
            var value = el.target.value;
            var length = value.length;
            if( length >= 10 ){
                this.disabledThree = false;
            }else{
                this.disabledThree = true;
            }
            this.text = value;
        },
        restartQuestionOne:function () {
            this.sex_list.forEach(function (item) {
                item.checked = false;
            });
            this.disabledOne = true;
        },
        restartQuestionTwo:function () {
            this.hobbies.forEach(function (item) {
                item.checked = false;
            });
            this.disabledTwo = true;
        },
        restartQuestionThree:function () {
            this.text = '';
            this.disabledThree = true;
        },
        nextQuestionTwo:function () {
            this.page ++;
            var obj = {};
            this.sex_list.forEach(function (item) {
                if( item.checked ){
                    obj.sex = item.name;
                }
            });
            this.user_data = obj;
        },
        nextQuestionThree:function () {
            var count = 0;
            var obj = this.user_data;
            obj.hobbies = [];
            this.hobbies.forEach(function (item) {
                if( item.checked == true ){
                    obj.hobbies.push(item.name);
                    count ++;
                }
            });
            this.user_data = obj;
            if(count > 3){
                alert('不得超过三项,请重新选择');
            }else{
                this.page ++;
            }
        },
        lastStepOne:function () {
            this.user_data = {};
            this.hobbies.forEach(function (item) {
                item.checked = false;
            });
            this.page --;
        },
        lastStepTwo:function () {
            this.text = '';
            if( typeof this.user_data.introduction != 'undefined' ) delete this.user_data.introduction;
            this.page --;
        },
        submit:function () {
            var obj = this.user_data;
            obj.introduction = this.text;
            this.user_data = obj;
            console.log(this.user_data);
            // ajax 发送数据到后台
        },
    }
});

question.js注意
1、这里我把三个页面整合到一起,能过v-if,v-else-if,v-else 来判断显示模块。
2、需要注意的是单项选择的时候,标签中只要存在checked属性就会被选中,所以这里我用:checked来判断是否有该checked属性。
3、进入下一步之前先要判断当前的选择是否符合需求。单选选中之后再可以进入下一步,重置选项可以清除当前页的选择; 复选框最少要有两个选择,最多则只有三个选择,选择两个的时候显示下一步并判断当前的选项有几个,如果超出三个给出提示,并不能进入下一步。
4、textarea中有属性autofocus是进入当前页,自动聚焦。必须有rows,cols属性才能有blur事件。
5、点击所有的上一步,都要清空当前页的数据。

index.js

var app = new Vue({
    el:'#app',
    data:{
        page:1
    },
});
style.css
[v-cloak]{
    display: none;
}
body,input,button,textarea,div{
    margin:0;
    padding:0;
}
#app{
    margin:20px 15px;
}
.options{
    margin-top:13px;
}
.options input[type=radio]:not(:first-child){
    margin-left:13px;
}
.options input[type=radio]{
    margin-right:5px;
}
.options input[type=checkbox]:not(:first-child){
    margin-top:15px;
}
.options input[type=checkbox]{
    margin-right:5px;
}
.not_display{
    display: none;
}
textarea{
    /*padding:50px 85px;*/
    margin-left:11px;
    margin-top:9px;
}
.able_color{
    color:#3399ff;
}
.disable_color{
    color:#808080;
}
.restart-color{
    color:#fff;
}
.big-size{
    width:200px;
}
.small-size{
    width:150px;
}
.step_bottom{
    height:35px;
    width:100%;
    position: absolute;
    bottom: 30px;
}
button{
    background-color: transparent;
    outline: none;
    border:1px solid #cccccc;
    border-radius: 5px;
}
.buttonOne{
    padding:7px 30px;
    margin-right:10px;
    width:45%;
}
input[type=submit]{
    width:29%;
    height:32px;
    margin-right:7px;
    border:1px solid #cccccc;
    border-radius: 5px;
}
/*.buttonOne:hover{*/
/*background-color:#cccccc;*/
/*border:1px solid #cccccc;*/
/*}*/
.greyColor{
    background-color:#808080;
    border:1px solid #808080;
    color:#fff;
}
.disabledColor{
    background-color:#cccccc;
    border:1px solid #cccccc;
}
.second_quesiton button{
    padding:7px 30px;
    width:30%;
    margin-right:5px;
}

表单提交相关的文章可以参考:
https://blog.csdn.net/caixiaodaohaha/article/details/78860452

最终效果图截图:








最终数据:


相关文章

  • Vue2.0 完成调查问卷WebApp

    最近一直在看vue.js实战,里面有一个项目实践,需求与效果如下: 我现在把此项目分成index.html,que...

  • Vue.js实战 调查问卷 WebApp

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

  • 单人可做的CPA网赚平台,你知多少

    1.问卷调查类:做问卷调查,平均一份问卷在0.5到10元不等。完成问卷调查获得积分,由积分兑换现金。 收奖网:平均...

  • 小项目练习

    项目:调查问卷WebApp描述:制作一个简单的调查文件HTML5 小应用,每页有一道题目,题目可以是单选题、多选题...

  • 第九章 分析工具汇总

    9.1调查问卷分析 慧行者公司进行问卷调查,收到问卷450份,实际有效问卷425份。在调查问卷的几个关键问题如下:...

  • vue开发webAPP使用swiper遇到的问题

    前言:最近基于vue2.0版本框架开发一款webAPP项目,由于项目需求所以使用swiper来完成一些特定的功能(...

  • 学术派的问卷调查

    问卷调查法也称问卷法,是调查者运用统一设计的问卷向被选取的调查对象了解情况或征询意见的调查方法。问卷调查是以书面提...

  • 读书笔记66-调查问卷

    说起调查问卷,你是再熟悉不过的了。有线下纸质版的调查问卷,有线上电子版的调查问卷,有访问式的口头调查问卷。无论哪种...

  • 用户调研方法小结

    1、问卷调研: 做法:设计好调查方向和调查问卷内容,选择方式(单层、多层问卷;纸质、网页问卷;验前、验后问卷;开放...

  • 问卷调查改怎么做?

    什么是问卷调查 问卷调查是指通过制定详细周密的问卷,要求被调查者据此进行回答以收集资料的方法; 如何设计问卷 问题...

网友评论

    本文标题:Vue2.0 完成调查问卷WebApp

    本文链接:https://www.haomeiwen.com/subject/mgkylftx.html