5

使用Vue.js实现一个微型问卷调查管理平台

入门Vue有几周时间了,学习过程也只是写一些小demo,比如TodoList,购物车之类的,了解了Vue的一些基础的特性和使用方法。刚好年后开学就想做个稍微像样点的东西,于是就找出了16年百度前端学院的任务五十来作为本次将要实现的项目。废话不多说,下面看东西。


链接地址

项目地址:GitHub
预览地址:在线预览

任务描述

传送门:任务地址

技术栈

  1. Vue.js:使用最新的Vue2的语法
  2. vue-router:单页应用必备的路由管理
  3. ES6:使用ES6语法实现大部分功能
  4. Sass:CSS预处理
  5. LocalStorage:本地存储,方便保存用户的问卷数据

问题及解决

  • 全选状态的切换 比如:
    点击全选切换所有问卷的选中状态
    点击任意问卷时计算是否全部问卷均选中来实时控制全选按钮的样式
/*问卷的check按钮*/
<li @click="checkItem(item)"><i :class="{'checked': item.checked}"></i></li>

/*全选按钮*/
<p @click="checkAll(isCheckedAll)"><i :class="{'checked': isCheckedAll}"></i></p>
    methods: {
        checkItem(item, flag = null) {
            if (typeof item.checked === 'undefined') {
                Vue.set(item, 'checked', true);
            }
            else if (flag !== null) {
                item.checked = !flag;
            }
            else {
                item.checked = !item.checked;
            }
        },

        checkAll(flag) {
            this.quList.forEach( item => {
                this.checkItem(item, flag)
            });
        }
    },
    
    /*通过ES6的数组every方法来很方便的得知的问卷列表中全部问卷是否为全选或非全选*/
    computed: {
        isCheckedAll() {
            return this.quList.every( item => item.checked);
        }
    }

  • 操作问卷时提示用户的弹窗功能
    点击操作按钮会执行一个Generator函数
    用户可选择提示框中的确定/取消来决定是否执行该操作
        /*问卷的编辑按钮*/
        <span v-if="!item.state" @click="iterator = editItem(item); iterator.next()">编辑</span>

        /*提示框的选择按钮*/
        <span @click="iterator.next(); isShowPrompt = false">确定</span>
        <span @click="isShowPrompt = false">取消</span>
        
        /*通过Generator函数来控制是否要进行下一步操作*/
        *editItem(item) {
            yield this.showPrompt(`确认要编辑《${item.title}》?`);
            yield this.$router.push({name: 'Edit', params: {id: item.id}});
        }
  • 用户回答问卷提交过程的检查必填项是否已填
        /*执行提交操作时,会先调用下面的函数,来检查用户是否已经填写所有必填的项目,否则return false不提交*/
        requireValidate() {
            let textareas = document.querySelectorAll('textarea');
            return [].every.call(textareas, item => {
                if (item.hasAttribute('required') && item.value.trim() === '') {
                    return false;
                }
                return true;
            })
        }

  • 用户在填写问卷时会保存一份答案的数据
    最后用户提交时后将所有答案合并在一个对象里方便提交至服务器
    这个项目非真实线上项目所以我只打印在控制台看看)
        /*文本框的答案由一个字符串保存*/
        <textarea v-model="item.answer"></textarea>
        /*单选钮的答案是选中的选项的索引,也是由字符串保存*/
        <input v-if="item.type === 'radio'" :type="item.type" @change="item.answer = optIndex">
        /*复选框的答案是选中的选项的索引,由一个数组保存*/
        <input v-else :type="item.type" @change="checkboxAnswer($event, optIndex, item.answer)">

  • 问卷编辑页面里的坑就比较多了,我就不一一贴出来了,我说说几个我印象比较深刻的
  1. 编辑页面中每个问题的题目和选项都可以点击后切换成input来进行修改,我用的是样式来控制他们的显示和隐藏,这里因为编辑选项时会影响到处于其父级元素的题目的input的显示,所以我在这个部分加了双重验证,如果只是编辑题目就控制一项class,如果是编辑选项就要先隐藏题目的input,然后显示出选项的input。

  2. 由于修改问卷可能会修改多处地方,所以不用每修改一处都保存一次,所以我把数据进行了复制而不是引用,在最后由用户决定是否保存修改后的问卷。
  3. 这个页面的Generator函数有的两个yield有的是三个yield所以我在执行next()之前加了&&判断,这样就不会在控制台报错。
  4. 使用了一个子组件,就是日历选择器,通过$emit()将选择的日期传给父组件的input中。
  5. ......


  • 回答的数据展示是自己用Math.random()来随机生成的数据,饼状图是使用了ECharts生成的。

总结

Vue是个好东西,努力学吧。
在写这个项目的时候确实遇到挺多问题,不过还好都一一解决了。
第一次写文章,如果哪里写的不好说的不好,望各位大佬轻喷。
溜了 0.0。


NiceMing
56 声望1 粉丝

奴隶翻身做主人.