最近业余帮朋友做两个vue项目,一个是面向用户纯展示系列的(后统称A项目),一个是后端管理系统类的(后统称B项目)。两者在技术上都没难度,这里对开发过程遇到的问题、取舍等做一个小节。
关于项目搭建
目前vue-cli脚手架已经很成熟,创建项目很方便,按照官网文档或网上相应教程即可快速搭建(https://cli.vuejs.org/zh/guide/deployment.html)
优点:快速、方便、零配置、可扩展性强、灵活性强
缺点:对于小项目来讲,搭建不够精简,会默认安装多余的包(比如会默认按照jest,nightwath,这些测试框架一般都没有用到)
PS:如果有用到单元测试且在本地运行,需在jest.config.js配置下新增两个字段:
verbose: true, testURL: ‘http://localhost/‘ 并移除如下字段 mapCoverage: true,关于http请求
采用axios,对http请求结果做统一处理后,列如请求结果返回code为200时处理后直接返回期望值data,非200时按实际情况处理,比如统一弹toast或者跳转、重定向等。
关于UI框架
A项目采用iview,B项目采用elementUI
从使用舒适度来讲,elementui完胜iview。其组件引用更便捷、自定义样式更灵活,事件绑定更贴近vue开发习惯。
iview体验较差的原因有:
1. button组件、以及menu组件下的menuitem等点击事件绑定需要写成@click.native形式,否则点击事件可能不生效;
2. 按官网文档引入iview-loader后,并不是所有组件都能直接以组件名的方式引用,如menu组件下的menuitem,依然要写成i-menu-item才生效 (对此,既然官网文档已出但却没有达到如述期望,因此对它不太信任...)
关于路由非登录重定向
这里提供两种方案:
1. 保存登录状态,在目标路由页面进行登录状态判断,若未登录,重定向
2. 在路由管理处,通过路由导航守卫做登录检测,若未登录,重定向(推荐这种方式,实现请参考https://github.com/vuejs/vue-router/blob/dev/examples/auth-flow/app.js)
A、B项目的登录状态isLogin均挂载在vue实例上,通过this.$root.isLogin可全局访问。其取值来自localStorage里键名为loginState的值。loginState的值是在登录或退出成功的时候设置。其弊端是当loginState的值被手动修改,那么展示状态也会随着更改。但因接口都需权限,且在路由或相应页面做了处理,所以几乎没什么影响。【之所以没用cookie,是为了用户安全起见,服务端将cookie设置为只读,本地拿不到cookie,一定程度上防御了xxs攻击】
关于upload组件上传文件跨域问题
因为elementui或iview upload组件上传文件时使用的是其底层的axios请求,若其action属性下的接口地址与本地的域名或ip不统一,就会存在cookie跨域的问题。解决方法就是统一域名或ip。
关于elmentui upload组件有删除提示时,终止文件上传会提示“是否删除文件xxx”的bug绕行
elementui upload组件做文件上传类型限制时,有两种方案:
1. 直接在其accept属性里设置允许上传的文件类型(推荐这种)
2. 在其beforUpload里做类型判断,如果为期望类型,返回true允许上传,否则返回false,终止上传。
方案2本来是没问题,但如果在beforeRemove函数下引入了this.$confirm(‘确定删除xxxxx‘)?,就会出现bug:beforUpload返回false,upload组件下任务会展示文件上传进度及上传成功,并同时弹出“确定删除xxxxx”的提示框。在这里文件确实没有上传,推测upload里展示的上传可能是个假象,但会给人莫名其妙的感觉,为了避免这个问题,在beforeRemove里做一个判断,即:当文件允许上传时才调用this.$comfirm方法,否则不做处理。
关于菜单激活项与当前路由匹配的解决方案
两种UI框架的思路一样,以elementui为例,设置为router模式,对应el-menu-item的index属性取值为目标路由名,如‘/dashboard’,点击这个菜单项时就会自动导航到目标路由。我们希望点击这个菜单项时,菜单为激活状态,menu有个属性为default-active,将该属性动态取值为路由名就行,假设default-active=‘activeIndex‘, 通过coumputed监测当前路由值即可:
computed: {
activeIndex () {
return this.$route.path // 此处建议路由名称统一小写,在取得路由值的时候将字母统一小写,不然名称大小写不一致会影响激活状态的展示
}
}
关于数组遍历后单项选中状态的样式设置
有两种方案,
1. 后端字段返回selected状态值,假设true为选中,false为选中,前端点击后,将这个值取反
2.前端设置一个curIndex变量,点击之后就复制当前index给curIndex,在html片段里做条件判断,如果curIndex === index,则展示选中样式。
关于内容块如课程模块(涉及章、节标题)的新增、删除、修改的开发
惯用的思维可能会联想到点击新增、删除等会直接进行dom节点的相应操作,这其实不太可取。因为新增的模块越多,就不好管理消耗比较大。但直接利用vue数据的特性,对其课程模块数组进行增、删、改就会容易很多。