vue实战分享--投票系统 - 雨中的博客

闲来无事,临近考试周却愈发不能静下心来复习,于是在图书馆爆肝了三天写了一个小demo—投票系统,还是熟悉的vue.js开发,同时这次尝鲜使用了美团开发的elementUI组件库,如果觉得不错可以克隆下来看看🤭!

产品预览图

这次没有来得及做移动适配,因此只能在web端显示正常,可能在手机端页面会有点小崩~,下面我就逐页介绍一下代码逻辑吧

页面结构

使用开源库

  • jQuery库(虽然vue和jQuery使用有违背初衷,但是奈何现在能力有限非常依赖jQuery的部分函数,因此还是不优雅的使用了他来开发)
  • elementUI组件库(由美团前端开发团队维护,之前使用的vux已经停更了,并且Bug太多了,因此使用了更加优秀的组件库)
  • echarts图表库(展示数据必备的库,不解释)
  • boxicons(这次使用了一个非常小众的矢量图标库)
  • vue-markdown(我可没能力写一个md编辑器,因此是引入的插件)
  • animated.css动画库(过渡动画使用,组件切换更加流畅优雅)
  • wow.js(实现页面抵达位置在加载效果)

介绍文档

登录/注册页

登录/注册页原本是想做一个视差滚动的效果了,奈何找不到太贴切主题的4k壁纸,因此不如选择一个更加朴素的效果,使用了circleMagic.js效果来实现背景漂浮许多彩色泡泡的样子,简洁可爱。

同时开发时为了更加优雅的切换登录和注册页,使用一个容器组件Container来放置登录和注册组件,切换时只是在Container.vue父组件中切换路由跳转来实现登录/注册页面的展示。下面是注册页的展示:

实现了密码的检测功能,当不同时会触发弹窗报错。同时绑定了enter事件来实现提交跳转。

控制台导航栏

最左侧的黑色导航栏是可以展开的,他是控制切换剩下的所有页面的控制导航,借助vue路由来实现父组件Console.vue来动态切换页面组件,个人信息页就是其中的一个子组件。这里给出路由的参考图:

个人信息页

yahoo~扑鼻而来的浓浓git风😆,没错这次心情大开,想模仿一下github主页的界面风格,但是还是进行了一下小小的魔改设计。登录成功后首先会显示成功登录信息同时显示当前时间。

右侧的个人信息栏实际上就是模仿的github左侧的个人信息栏,但是status状态展示部分未能成功实现展开效果,有好思路可以告诉我哦!同时也第一次尝试使用sticky的高级display属性来实现粘贴的效果,但是这个新的属性在大多数浏览器中还不能完美实现,因此暂时不推崇大量使用。

然后左侧的是数据展示内容区域,上面是活力表,使用了echarts热力图来实现的数据统计和展示。可以参考本篇博客:

中部区域的加载条展示是使用宽度百分比来实现的,使用before和after伪类来实现动态移动的效果。下面是代码逻辑较为复杂的部分,这里还是使用了v-for动态渲染数据的功能,仍然是使用v-key来区分唯一的id,然后使用transition-group来实现翻转加载的效果,最后还要注意在github中会根据不同的语言在下方使用不同的颜色进行标注。这里我是使用了v-directives命令来实现了一个动态渲染颜色的功能,当为问卷调查时是佩奇红色,为理论答题时是金黄色,大众投票时是翠绿色。

聊天会话页

yahoo~又是扑鼻而来的飞书风😆,作为一个前端实习小白,我还不太会设计页面,因此都是模仿官方网站的设计。首先给出对比图:

我自认为复原的已经非常相似了,接下来我具体介绍一下细节功能,首先是右侧的内容框是左侧栏的子组件,他可以根据通过query传递过来的数据动态渲染左侧不同群聊的信息内容,这里我只展示了某个群聊中的内容。同时下方使用了md组件进行聊天信息的编辑功能,但是发现这样无法获取输入的内容,插件并未给出具体的api来获取输入的信息。。。同时还实现了点击加载某个群聊的群管理功能,如下图:

这路尝试使用了elementUI组件提供的表单组件,不得不说确实非常强大,很容易就可以实现一个功能齐全并且自带数据非空检测的表单,唯一的缺点就是移动适配时很苦恼。同时做这个官方,团队小图标时做的很心烦,发现flex布局会使得一个元素横向无限展开导致有时候还不如relative+absolute定位来的方便😅,看来还是不能过于依赖组件库,只有自己造的轮子才是最好用的。

投票创建页

这个页面是自己设计的,没有参考其他页面,虽然不是很美观,但是这个页面的技术性较高。首页左侧是所有自己创建的投票项目,仍然使用了v-directives来动态渲染圆点颜色,同时上方可以自动刷新统计不同类别项目的总数,同时下方的搜索框可以根据输入的内容实时刷线新筛选出符合搜索条件的列表项目。并且支持自动创建新的项目,这里当时开发的时候有一个小bug一直不能解决,就是创建新项目后发现一直删除后最终上面的统计总是会多出来, 原因是因为当时是按照id来进行删除的,因此每次删除完一个id后,会导致序列号不连续,因此再创建新元素后回导致id越来越大,但是数量却并不是线性增长的,因此最终采取了双重id确认一个元素的方法解决了这个bug。同时你会发现这个创建新项目以及删除项目后列表的刷新过渡动画都非常流畅,这是巧妙利用vue提供的v-move与transition实现的列表刷新动画,并不需要引入新的动画库或者绑定已有的动画,非常神奇。同时右侧仍然是尝试使用了elementUI提供的表单组件,但是这里是写死的,没有实现为每一个项目刷新渲染一个设置页面(不是不会,实际上原理和聊天室是一样的,只是当时写的有点小烦🤬)。

投票编辑页

这个页面是最难实现,代码逻辑最复杂的地方,也是本次项目的最大亮点。首先这里页面要实现能够动态创建删除不同的题目元素,同时要能够对每一个题目单独设置是否必做,题目乱序的开启功能。不同的题目编辑的题型可选项也是不同的,例如单选是条件选项,而判断不用添加选项,单选必须至少有一个选项,多选必须至少有2个选项,因此不同的题型也要能够单独创建和删除可选项。最后不同的题目还要可以设置不同的分数,同一类题型的不同序号的题目也要能够单独设置不同的分数,并且右侧的显示栏要能够随时根据变化动态刷新题目数量与平均分数。这里涉及到了几个问题,我将逐个讲解

问题一:计算平均分要在哪里实现?

很显然编辑页是一个父容器元素,然后每一个小题目是一个渲染子元素,而平均分需要在父容器中进行计算并渲染,因此很显然题目的统计,以及总分的计算和平均分的计算需要在父容器编辑页实现。因此每一个题目的具体数据需要在父元素组件中进行绑定。因此父元素有一个数组数据类型,他存储了所有题目的信息(包括每一个题目的分数,题型,id等等)。这样父元素中使用v-for进行渲染从而以列表的形式来渲染出所有的题目元素,然后在使用相同的v-move和transition-group来实现过渡刷新动画。由于每一道题的分值都会影响到平均分的变化,因此每次有新的题目创建,或者删除某一个题目再或者某一个题目的分支发生变化,父元素组件都要重新进行分值的计算,所以很明显父元素的平均分计算有两种策略:①绑定钩子函数afterUpdated来实现每次更新刷新数据②使用computed或者watch来实现数据的随时自动计算。这里我才用了第二个策略使用computed来实现。

问题二:不同的题目怎样区分题型?

我们首先要明确无论是哪种题型,其本质上都只是一个题目对象,因此很显然他们存在相似点,比如都有状态设置(是否乱序选项乱序)、题目序号、选项列表数组(判断和投票看成选项数组为空数组即可)、分值,因此我们可以使用抽象的知识,并不需要为每一中题型数据都单数设置一个对象,而是可以创建一个统一的题目对象,然后设置一个题型状态号来标明某个题目属于哪一个题型,比如0是单选,1是多选等等以此类推,如下图就是一个题目对象的格式:

这样我们巧妙的利用题目标号即可根据不同的题目类型使用不同格式的数据存储方案。同时我们还未每一个题型的题目设置了默认的配置。这样我们就实现了一个题目的数据存储格式。

问题三:每种题目类型具体编辑页面?

虽然我们前面说过不同类型的题目可以使用的一个数据存储对象来表示,但是在渲染时不同的题目类型编辑样式还是不一样的,因此我们还是需要创建6个子组件来定义6中题型的元素渲染样式。同时我们在子组件设置他的具体编辑数据,比如可以更改状态,更改分值,选项列表等等,然后当更新变化时他将变化的数据传递给父组件。这里我给出单选的子组件样式:

每一个子组件都可以的动态渲染出状态,数值,序列号等等。这样我们就实现了每一个题目之间的配置互不干扰了,从而不会出现修改第一题又间接修改了2,3题的尴尬情况。

问题四:子组件如何将更新变化的数据传递给父组件?

我们通常在学习vue的时候学习到的父子组件通信都是子组件接受到父组件传递过来的数据后直接渲染显示,但是这里有所不同,子组件接受到的来自父组件的数据只是创建一个题目时的默认配置,我们会对每一个具体的题目进行配置的更新,而子组件的配置更新后需要传递给父组件,通知其具体对应的数据变化,那么子组件如何实现呢?这里我阅读了大量的博客,最终发现了一个秘诀—使用$emit传递,他的传递规则很奇特,需要在父组件自定义一个语法糖和函数,例如@updateData='updateData',然后子组件使用$emit时要声明父组件自定义的语法糖函数,并且还要声明传递的更新数据,这样父组件就可以通过这个自定义函数接收到更新的数据了。这里我将更新的数据封装成了一个对象传递给父组件方便数据的传输,下面是我具体实现子向父组件传递的代码:

子组件js部分

这样我们就完美解决了子组件向父组件通信更新信息的问题了。综上我们就可以随意的创建和删除题目并更改分值了,js部分代码会自动使用computed属性进行平均分的计算了,从此我们再也不用为计算平均分而苦恼了。

同时我还对创建题目的按钮进行了美化,使得其交互动感更明显,并且使用elementUI组件来实现了背景颜色的DIY功能,方便我们选择一个更加舒适的护眼颜色缓解视觉疲劳。

待开发展望

由于开发周期很短才3天,基本上一个页面一天,因此还有许多不完美的地方可以完善,比如移动适配完全可以用两三天实现。保存预览功能也很容易实现,代码逻辑和编辑完全一样,而数据分析展示可以借用echarts提供的图标库完美实现。至于设置界面难度也不是很高,随着前端的开发,我逐渐对使用假数据填充前端页面来渲染的模式愈发感到无聊,因此以后会暂停前端项目的学习和尝试,专心与java后端的开发,下一次项目实战应该就可以实现接口的调用了。那么本次分享就告于段落啦!如果您比较感兴趣,不妨点个小小的star哦~




©2020 - 2021 By wenchong
津ICP备2021004286号

本站总访问量为 访客数为

本站使用 Volantis 作为主题|借助hexo强力驱动|由腾讯云提供云服务