3.Vue.js 实战 调查问卷WebApp项目

       问卷调查demo已上传,欢迎大家指正,欢迎大家下载:https://download.csdn.net/download/lzb348110175/11085995

       之前也有看过Vue,但是一直都是处于大致知道点的状态。针对Vue的数据双向绑定等还是挺有好感的。感觉太酷了。但是

面对初学者,什么资料适合初学者呢。当时也确实是个很头大的问题。

       有看过视频教程,《大地老师的无人点餐,无人收银系统》 链接: 提取码:cipy ,讲的确实是不错。但是。还是讲了一些

表面知识。没有具体深入到实质。Vue在基础部分,一个一个脱离开来讲解,确实简单到没劲。就是这样子的没劲,但是到了后

面组件部分,当将之前最简单的知识放到组件一起使用,只有一个感觉:懵圈到想吐。确实是这个样子的。

        但是鉴于Vue的种种考虑,博主还是准备努力去学习学习Vue,也为自己能多学点,多会个技术多挣点钱吧。哈哈。反正就

是一个字,干!!!

        博主现在在看着书籍学习。找了一堆 Vue相关的书籍,诸如:《Spring Boot+Vue全栈开发实战》、《Vue2实践揭秘》、

《Vue.js实战》。但是综合之后,发现《Vue.js实战》这本书还算不错。所以就从开始认认真真的学习开始了。

        基础知识篇,还是那样子和视频里一样,简单到爆炸,学的没劲。除了组件之间的相互传值还稍微有那么点难度。其他的真

的没啥。组件之间的相互传值问题。在没使用Vuex之前,就是通过$emit,props,@on,bus总线等来完成。想了解,可以查看

1.Vue组件之间传值问题  这个也是为了方便记忆。好记性不如烂笔头,所以也就随手记录了一下。

        在者就是遇到了v-model用在组件上的困惑问题。在input框上使用v-model就是数据的双向绑定。但是用到组件上之后确实

让初学者会有点一脸懵逼,反正我是这样子的。又是v-model,又是this.$emit('input',xxxx),又是父组件@input啥的接受值,确

实看着头疼,主要是看完之后还是不知道为什么???这就很崩溃了,根本找不到为什么。所以博主也就在努力的寻找v-model

用于组件上的用法相关的问题。最后终于知道为什么了,当明白为什么之后,瞬间觉得柳暗花明,其实真没啥难度,只要细研究

一下v-model的实现原理就全都知道了。2.v-model 用在组件中  这块我也就做了个笔记,随手记录一下。

         博主目前刚把基础知识学完,看到了第2篇 进阶篇。

        进阶篇第一个就是这个问卷调查问题。从基础篇刚转过来。看到这真是一脸的蒙圈的。书中也没有参考答案部分。

我又开始怀疑人生了。。。还是硬着头皮往上,就是干。。所以今天研究了很长时间,一步一步,终于还是做出点样子来了。

该题要求:

      1、起码做出个长的和图片一样的框框来

      2、按钮需要用到组件,并且可控制颜色、状态

      3、单选题必选、多选题最少2项最多3箱,文本框不少于100字

 这道题,有很多种办法来完成。博主用到的是之前基础篇学到的作用域插槽的知识来完成的。该组件一共分为三部分(没有关注

css样式):survey.htmlsurvey.jsmyButton.js三部分。算是把如上的所有功能都做出来了。直接上代码吧!!!

问卷调查demo已上传,欢迎大家下载:https://download.csdn.net/download/lzb348110175/11085995

结构图

survey.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>survey_demo</title>
    <style>
        /*不可用*/
        .activeColor{
            color:#0f0;
        }
        /*不可用*/
        .disableColor{
            color:#ccc;
        }
    </style>
</head>
<body>
    <div id="app">
        <survey :surveys="surveyList" v-model="activeKey" :sex="sex" :hobby="hobby" :introduce="introduce" :active-color="activeColor" :disable-color="disableColor">
            <template slot="surveyTitle" scope="props">
                <div v-if="props.surveyId == activeKey">
                    <span v-text="props.surveyId"></span>
                    <span>.</span>
                    <span v-text="props.surveyTitle"></span>
                </div>
                <div v-if="props.surveyId == activeKey">
                    <div v-if="props.surveyType == 'radio'" v-for="sexVal in props.surveyValue">
                        <input :id="sexVal" type="radio" v-model="sex" :value="sexVal"><label :for="sexVal" v-text="sexVal"></label>
                    </div>
                    <div v-if="props.surveyType == 'checkbox'" v-for="hobbyVal in props.surveyValue">
                        <input :id="hobbyVal" type="checkbox" v-model="hobby" :value="hobbyVal"><label :for="hobbyVal" v-text="hobbyVal"></label>
                    </div>
                    <div v-if="props.surveyType == 'textarea'">
                        <textarea :id="props.surveyId" v-model="introduce" placeholder="不少于100字"></textarea>
                    </div>
                </div>
            </template>
        </survey>
    </div>
    <script src="../vue.min.js"></script>
    <script src="survey.js"></script>
    <script src="myButton.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data:{
                activeKey:1,
                sex:'',
                hobby:[],
                introduce:'',
                surveyList:[
                    {
                        id:1,
                        type:'radio',
                        topic:'sex',
                        title:'请问您的性别是什么?',
                        value:['男','女','保留']
                    },
                    {
                        id:2,
                        type:'checkbox',
                        topic:'hobby',
                        title:'请选择您的兴趣爱好?',
                        value:['看书','游泳','跑步','看电影','听音乐']
                    },
                    {
                        id:3,
                        type:'textarea',
                        topic:'introduce',
                        title:'请介绍一下自己',
                        value:''
                    }
                ],
                activeColor:'activeColor',
                disableColor:'disableColor',
            },
           watch:{
                activeKey:function (val) {
                    console.log("父类value:"+val)
                }
           }

        })
    </script>
</body>
</html>

survey.js

Vue.component('survey',{
    data:function () {
        return{
            currentValue:this.value,
            nextStepBtn:true,
            submitBtn:true
        }
    },
    props:{
        surveys:{
            type:Object,
            default:''
        },
        value:{
            type:Number,
            default:1
        },
        sex:{
            type:Number,
            default:Infinity
        },
        hobby:{
            type:Array,
            default:[]
        },
        introduce:{
            type:String,
            default:'',
            minLength:100
        },
        activeColor:{
            type:String,
            default:'activeColor'
        },
        disableColor:{
            type:String,
            default:'disableColor'
        }
    },
    template:'<div>' +
            '   <div id="title">' +
            '       <slot  name="surveyTitle" v-for="survey in surveys" :survey-id="survey.id" :survey-type="survey.type" :survey-topic="survey.topic" :survey-title="survey.title" :survey-value="survey.value"></slot>' +
            '   </div>' +
            '   <my-button v-model="currentValue">' +
            '        <button :class="activeColor" v-if="currentValue <= surveys.length && currentValue != 1" @click="upStep(currentValue-2)">上一步</button>' +
            '        <button :class="[nextStepBtn?disableColor:activeColor]" v-if="currentValue != surveys.length" :disabled="nextStepBtn" @click="nextStep(currentValue)">下一步</button>' +
            '        <button @click="reset">重置</button>' +
            '        <button v-if="currentValue == surveys.length" :disabled="submitBtn" @click="submit">提交</button>' +
            '    </my-button>'+
            '</div>',
    methods:{
        nextStep:function (id) {
            this.checkStatus(id);
            this.currentValue ++;
        },
        upStep:function (id) {
            this.checkStatus(id);
            this.currentValue --;
        },
        reset:function () {
            this.$parent.sex = '';
            this.$parent.hobby = [];
            this.$parent.introduce = '';
            alert("重置成功")
        },
        submit:function () {
            let sex = this.$parent.sex;
            let hobby = this.$parent.hobby;
            let introduce = this.$parent.introduce;
            alert("提交:\rsex:" + sex + "\rhobby:" + hobby + "\rintroduce" + introduce);
        },
        //优化下一步按钮是否置灰问题
        checkStatus:function (id) {
            if('hobby' == this.surveys[id].topic){
                if(this.hobby.length<2 || this.hobby.length > 3){
                    this.nextStepBtn = true;
                }else{
                    this.nextStepBtn = false;
                }
            }else if('sex' == this.surveys[id].topic){
                if(this.sex.length > 0){
                    this.nextStepBtn = false;
                }else{
                    this.nextStepBtn = true;
                }
            }
        }
    },
    created:function(){
        this.nextStepBtn = true;
    },
    watch:{
        currentValue:function (val) {
            this.$emit('input',val);
        },
        sex:function () {
            if(this.sex.length > 0){
                this.nextStepBtn = false;
            }
        },
        hobby:function(){
            if(this.hobby.length<2 || this.hobby.length > 3){
                this.nextStepBtn = true;
            }else{
                this.nextStepBtn = false;
            }
        },
        introduce:function (val) {
            if(val.length>100){
                this.submitBtn = false;
            }
        },
        nextStepBtn:function(){

        }
    }
})

myButton.js

Vue.component('my-button',{
    data:function () {
        return {
            buttonValue:this.value
        }
    },
    props:{
        value:{
            type:Number,
            default:1
        }
    },
    template:'<div id="myBtn">' +
             '    <slot></slot>' +
             '</div>',

    methods:{

    }
})

测试结果如下:

        总体效果就算是做出来了。整体来说全部功能都实现了。可能代码部分也还有部分不咋滴好吧。博主也算是完成了对自己的

一点小超越,算是比较欣慰吧。有小错误的话。Vue菜鸟一枚,欢迎大家指正,谢谢大家了。

        网上也找到其他两个做出来的。和我写的都不是很一样。

        第一种是最基础的。感觉是基于Vue 1.0来的。只是用到if-else来达到效果。看着有点乱

        第二种看着还不错。就是篇幅好长。哈哈。我感觉自己的写的比他们的稍微好那么点。大家也可以评论评论,哈哈

        第一种:https://www.jianshu.com/p/8b8a667247cf

        第二种:https://www.jianshu.com/p/b32c75a25f2d

---->如有疑问,请发表评论,或者联系博主:[email protected],欢迎哦^_^

猜你喜欢

转载自blog.csdn.net/lzb348110175/article/details/88999699