吴键成 周旭宇 陈怡芯
摘要:该文描述了利用高度遵循MVVM架构的前端框架Vue Js并以前后端分离的方式开发一个网络基础课程在线教学平台。在这个平台中学生用户可以通过图文/视频的方式学习课程、完成作业练习、在线提问、参与考试、在线观看课件;教师用户完全拥有学生用户的功能并且能发布课程信息、发布作业/考试、上传课件/资源、查看学生考试情况等。该平台结合了富文本、WebSocket、Canvas等技术呈现出一个功能丰富的在线教学平台,为类似需求的实现提供一种实现思路。
关键词:MVVM;Web;Vue JS;Node JS;在线教学
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2020)05-0083-04
开放科学(资源服务)标识码(OSID):
1 背景
随着前端领域的高速发展、技术不断更新迭代,越来越多的网站首选使用前后端分离的方式来进行开发,大大小小的前端框架也在前端生态中先后涌现,其中華人尤雨溪的Vue JS框架在前端生态中知名度一直在提升,与Facebook的React、谷歌的Angular并称为前端三大框架。Vue JS的架构高度遵循MV-VM,其视图层和数据模型层的分离的思想在前端的开发上带来了很多便利。本文就在线教学平台这一案例,阐述利用VueJS作为基本技术栈,对该在线教学平台的设计与实现。
2 MVVM的理解
MVVM架构分为三层:Model、View、ViewModel。Model层代表数据模型,数据的修改、操作逻辑就在这一层中定义;View代表视图,负责把数据模型转化为UI;ViewModel则是自动地把Model、View两层连接起来,使用者无须关心,可以把更多注意力放在Model-层上。MVVM架构的这一特征使得开发者能更专注于业务逻辑的开发,无须手动操作DOM,代码可读性要强上不少,特别是在像大型项目这样需求功能丰富的情景下,能节省开发者大量的精力,缩短开发周期,也减少了传统前端开发因为DOM操作频繁所带来意想不到的BUG。
3 技术选型
本项目在前端方面选用了并没有完全遵循但高度遵循MVVM架构的Vue JS(MVVM架构不允许View层与Model层直接通信,对于某些情境下的前端组件化中父子组件的通信带来了不便,Vue JS提供了ref属性解决了该问题,但违背了MVVM架构本身),Vue JS组件化的思想使得项目的部件、功能变得模块化,更易读、更容易维护,很好地解决了传统前端开发需要开发人员手动书写大量闭包来实现模块化的状况。
后端方面选用对高并发处理十分擅长的Node.JS,并与Koa.js框架相结合,Koa是Express框架的幕后原班人马打造的基于Node.js平台的下一代Web开发框架,支持ES7的Async/Await语法,能有效回避回调地狱和多层Promise嵌套使得代码可读性糟糕的问题。
数据库选用了介于关系与非关系的MongoDB,MongoDB是一个基于分布式文件存储的数据库,旨在为WEB应用提供可扩展的高性能数据存储解决方案,它所支持的数据结构是类似于json的bson,相比于关系数据库如:MySQL,JSON式的存储使其在业务上可拓展性要高上不少。
4 项目设计与实现
4.1 项目总览
项目分为桌面PC端和移动端,用户类型分为两种:教师用户、学生用户。平台主要分为以下几大模块:课程模块、资源模块、答疑模块、考试模块、作业练习模块。
4.2 用户类型的识别
为了能给不同的用户类型提供不一样的权限控制,当用户登录时都会传人一个字段以标识用户类型,后端对该账号的登录认证完成后会将该用户类型连带非敏感的用户基本信息以及登录状态写入前端cookie,而后前端每次向后端发起请求都会带上该cookie,如此一来后端就能根据传回的cookie获知用户类型以便做权限管理。至于在前端UI方面给不同类型的用户显示不一样的交互页面也无须专门给不同用户准备单独不同的页面组件,得益于视图、数据模型分离的MVVM架构,利用在数据上对不同用户类型的标识作为条件,使用Vue的惰性条件渲染v-if指令即可渲染出供不同用户类型使用的交互控件,达到同一个页面组件给不同类型的用户呈现响应的交互界面的效果。
4.3 课程模块
课程模块需要实现富文本编辑课程章节内容,可以本地上传视频或外链视频,并能记录用户上一次观看到的章节。富文本组件选用CKEditor,它拥有现代化又简约美观的UI,对xss(Cross-site scripting)攻击也有一定的抵抗能力,但CKEditor的官方视频导人模块十分局限,不仅不支持本地视频上传,也不支持中国国内常见视频网站的外链。我们的解决方案是把官方的视频组件提取出来进行改造,使之能支持本地视频的断点续传,并放弃使用vue模板创建HTML的方式,而是利用Vue中最接近编译器的render渲染函数来渲染需要嵌入的外链视频代码,灵活且编程能力强的render函数能轻松应对诸如优酷、腾讯的外链视频。把富文本中的视频部分文本渲染成html模板展示到页面有以下几个步骤:
1)改造CKEditor的视频导入插件中把视频连接转换成em-bed标签的逻辑(节选):
editor.config.define(,mediaEmbed ,{
providers:[
{
name:normal 7.
url: /^(.+Vmp4)/。
html: match=>f
returnf
+
、
)
}
},
{
name: 'youku',
url: /^vVyoukuVcomVv_showVid_(.+)Vhtml/,
html: match => {
return (
''
}
]
})分转换相应的 dom元素 :
slice(content) {
const normal_regex = /https? :\N.+Vmp4/gi;
const youku_regex = /https?:WvVyoukuVcomVv_showVid_(.+)VhtmVgi;
function gen_youku_template(url) {
return '
' allowfullscreen ' >' ;
const split = content.split(
/《figure class= "media" > kfigure class= "media">ygi
);
if (split.length === 0) {
return
}
split.forEach(p => {
return null;
}
let m;
if《m = youku_regex.exec(p》 !== null) {
return this.template.push(gen_youku_template (m[l l》;
}
if《m = p.match(normal_regex》 !== null) {
return this.template.push({
tag: 'videoPlayer',
data: {
props: [
options: {
language: 'zh_CN',
playbackRates: [0.7, 1.0, 1.5, 2.0],
fluid: true,
preload: ' auto ',
sources: [
{
type:,video/mp4r,
src: m[0]
)】),
】Ⅲ;
)
this.template.push(p);
”;
3)注冊无状态函数式组件用作渲染组件:
components:{
videoPlayer,
CPCTemplate:{
functional: true,
props:{
el:f
type: Object,
required: true
¨,
render: function(createElement, content){
return createElement(
content.props.el.tag,
JSON.parse(JSON.stringify (content.props.el.data》
))))
4)渲染出富文本字符串中各个组成部分:
虽然在数据模型这一层次上有写死html模板的逻辑,但依然体现着MVVM架构中的数据驱动视图的思想,视图层确实不需要关注模板的内容,而是由数据模型层的逻辑去生成,视图层依靠render函数和v-html指令就能正确渲染出我们所期望的内容。
对于对用户阅读章节进度的持久化概率我们采用了前端本地存储方式中的locaIStorage方案,只需要在用户进入某一课程的某一章节页面时(对应Vue生命周期中的created或mount-ed)将信息写入localStorage就达到了记录当前用户阅读进度的目的,用户无感知且无须发起请求。
4.4 资源模块
资源模块是课程资源的上传、下载,包括PDF课件、课程视频、软件。PDF课件需要实现在线预览、涂鸦功能,资源可模糊搜索。由于视频可能会很大,以至于突破HTTP协议的消息体最大长度从而导致上传失败,为解决这个问题,我们将用户上传的视频进行了自动分段,实现了断点续传,每一段的上传都会带上总段数、当前段号等信息,当最后一段上传完毕后后端会把各段按顺序拼接成一个完整文件并把分段文件删除,把文件信息、地址存人数据库后给前端返回文件地址;前端不仅可以计算出上传进度,还能在上传完成后马上获取到文件URL。我们通过Canvas实现了PDF文件的在线预览与涂鸦,把PDF文件的内容按照分页转成图片,绘制在Canvas中,把canvas封装在组件中,通过props传人参数控制当前页的显示:
:src="src"
:page=”currentPage”
stvle=”background-color: #eee;”
@error=”pdfError
>
视图是由数据驱动的,通过vue的列表渲染就可以实现渲染pdf文件每一页的缩略图,监听缩略图与“上一页”“下一页”控件的点击事件,改变当前页面的数据,vue即可根据被改变的数据去渲染视图层(改变元素的样式、pdf页面的显示):
:stvle=”(
transform: 、translateX(calc(-200-/o 术 ${catalogueltemOffset-Page - iD)'
)”
@page-loaded=”pageLoaded(pageNumber)”
@error=”pdfError”
>
利用Canvas API、鼠标onmousedown、onmousemove、on-mouseup事件可以实现画图功能,得益于Canvas API的支持,可以实现不同的笔刷粗细、笔刷颜色。模糊搜索功能则是使用动态生成正则表达式的方式,使用非贪婪模式,过滤不匹配的结果实现的,该方式不仅在资源模块中使用,在课程、答疑等模块中皆有使用,并且支持多条件的模糊搜索。
4.5 答疑模块
答疑模块类似于论坛,一个提问对应多条回答,一个回答可对应多条评论,并且同样支持富文本。与课程模块一致,富文本组件同样使用CKEditor;MongoDB数据存储有着很高的可拓展度,对象、数组是可以嵌套的,提问与回答与评论的一对多关系的存储问题迎刃而解,一个document对应一条提问,多条回答以对象数组的形式存于document中,一条回答的多条评论以对象数组的形式存于每个“回答”对象中,对于前端而言,嵌套的列表渲染即可方便渲染出提问内容、回答内容、评论内容。
4.6 考试模块、作业练习模块
考试模块需要实现选择题(单选、多选)的自动阅卷、评分;而作业练习模块不计成绩,但需在学生用户交卷后显示答案解析。为了能实现自动阅卷、显示答案解析,我们在交互上的设计是引导教师用户在创建试卷的时候就需要给每道题设置正确答案(对于作业练习模块而言还需要答案解析),这些信息连同题干、选项等信息存人数据库中,试卷中每一道题都使用UUID作为唯一标识,學生用户在进入试卷时后端只返回题干、选项、唯一标识等信息;交卷时把用户所选答案、题目唯一标识、试卷唯一标识传到后端,后端就能把用户答案与数据库中的数据进行比对,进而算出最终成绩。而对于考试时间倒计时的计算,同时使用前端计算和后端计算两种方式,当进入考试后前端自动设置定时器开始倒计时并使用WebSocket与服务器连接,发送事件,后端接收到事件后开始倒计时。后端每隔5分钟向前端发送事件使前端的倒计时与后端同步,当考试倒计时变为0时后端向前端发送事件,使其强制交卷以结束考试。
5 结束语
本文详细分析了一个基于类MVVM架构前端框架Vue JS的在线教学平台的设计与实现。该平台涉及功能丰富、完整,成功结合了WebSocket、富文本、Canvas画图等技术,体现了Vue JS与其他技术良好的可结合性,展示了Vue JS这个高度遵循MVVM架构的前端框架在开发中的便利,也为相似业务需求的平台中功能的设计实现提供了一些可行的思路。
参考文献:
[1]易剑波.基于MVVM模式的WEB前端框架的研究[J].信息与电脑:理论版,2016(19):76-77,84.
[2]徐頔,朱广华,贾瑶,基于Vuejs的WEB前端开发研究[Jl.科技风,2017(14):69.
[3]薛玉倩.基于MVVM管理信息系统的研究与应用[J].内蒙古科技与经济,2019(20):63-64.
[4]朱二华.基于Vue.js的Web前端应用研究[J].科技与创新,2017(20):119-121.
[5]冯传波,彭章友,张钟浩,基于Vue.js的移动应用可视化平台的研究[J].工业控制计算机,2019(5):102-103.
[6]王鹏强.基于vue的MVVM框架的研究与分析[J].电脑知识与技术,2019(11):97-98,100.
[7]何焕春,杨怿,基于MVVM构架的Web前端框架研究[J].电脑知识与技术,2017(24):59-60.
[8]莫文水.Web前端中MVVM框架的应用研究[J].网络安全技术与应用,2017(4):64.
【通联编辑:谢媛媛】