最近俩月正好用 vue 做了一个大数据的项目,积累了很多心得。今天终于有机会分享出来了。
vue 提供的模块化无疑是提高开发效率的神器,而且对于后期代码优化和维护也提供的极大地便利。
vue 提供了组件功能,组件又可以分为全局组件和非全局组件。区别是全局组件你可以直接在 .vue 文件中直接使用自定义的 html 即可。非全局组件必须在 Vue 的对象中定义 components 引入这个组件
局部组件引用方式
import A from '@/component/A'
export default {
data () {},
components: { A }
}
全局组件引用方式
// index.js 文件
import A from '@/component/A'
A.install = function (Vue) {
Vue.component(A.name, A)
}
export {
A
}
// main.js 文件
import { A } from './components/index'
Vue.use(A)
这里针对引入全局组件有一个优化小技巧,上面的方式引入全局组件需要同时维护 index.js 文件和 main.js 文件很麻烦。采用下面的代码可以只维护 index.js 文件即可
// index.js 文件
import A from '@/component/A'
A.install = function (Vue) {
Vue.component(A.name, A)
}
function InstallAll(Vue) {
Vue.use(A)
}
export {
A,
InstallAll
}
// main.js 文件
import { InstallAll } from './components/index'
InstallAll(Vue)
手机号 + 验证码进行登录已经是目前主流的登录方式之一了。但是一个项目要使用验证码的地方非常多,像登录、注册、修改密码、信息再次确认的时候都会进行二维码请求。每个地方重写验证码逻辑很麻烦,所以验证码是需要抽象出来的组件的。
验证码通常会对接多个接口,或者是一个接口但是需要传递获取验证码的类型。而这些接口通常都需要一个手机号。因此验证码需要接收俩个参数:phone, type。自身完成单击操作和读秒操作即可,不需要对引用的地方产生任何影响。
// 最后每个页面调用的时候大概长这个样子
收藏功能使用的频率要比验证码更高,当然也更难。
像我最近做的大数据项目,用户可以对视频、音乐、话题进行收藏。同时他们出现的地方也非常多,像视频列表、音乐列表、话题列表、视频详情、音乐详情、话题详情... ... 都会有收藏的功能,不抽象成一个组件同样的逻辑写好几个地方后期维护是及其困难的。
像这种收藏,通常都会需要一个 id,是否收藏状态,以及完成收藏后的一系列的跳转功能。因此需要俩个参数: id 和 status。和 complete 回调方法
// 最后每个页面调用的时候大概长这个样子
我上面提到我会收藏音乐、视频、话题,很显然是三个收藏接口。难道要写三个收藏组件么?当然不是,既然同属于收藏功能,自然是一个组件搞定了。再加一个 type 参数区别一下即可了
// 最后每个页面调用的时候大概长这个样子
这样每次用到收藏的时候我只需要复制这一行代码就可以了
第三方 UI 库会给我们引入非常多好用的组件,像轮播图、表单、图片上传。但是这些都是跟业务无关的组件,而我们在做项目的时候时候肯定会碰到大量重复的功能。为了代码的易维护性一定要有良好的组件抽象能力。合理运用好 component 功能。
上面提到的验证码和收藏功能使用次数频繁,我通常都会当做全局组件处理(个人会把使用次数 > 1 的组件当成全局组件),但是有的页面及其复杂,一个页面上万行代码后期查找肯定费事巴拉的。也一定要对其进行拆分处理不要一个组件写到尾。针对这种情况我通常都会采用局部组建去维护,提高界面的简洁程度。
数据过滤无疑也是 vue 的重要功能之一。像时间、数字的过滤,实在是太频繁了。掌握 filter 无疑能大大提高代码幸福度和可维护性
同 component 一样 filter 也分为全局过滤器和局部过滤器。
全局过滤器
vue.filter('date', function (value1, value2, ...) {
return '处理之后的结果'
})
局部过滤器
export default {
filters: {
date (value1, value2, ...) {
return '处理之后的结果'
}
}
}
使用方式(不管是全局的还是局部的使用方式都一样):
// 不带参数
{{value1 | date}}
// 带参数
{{value1 | date(value2, ...)}}
// 多个过滤器
{{value1 | filter1 | filter2}}
注意:第一个参数是管道符 (|) 前面的值
我大部分都是使用的全局过滤器。像局部过滤器,一是获取到原始数据的时候可以直接进行处理,二是发现早期使用的局部过滤器都升级为全局过滤器了。如果你有好的局部过滤器场景欢迎评论
日期处理。后端传的数据要么是 2019-03-14 09:00:00 这种字符串类型的。要么就是时间戳类型的,但是界面通常只会展示一部分,比如只展示年月日,或者是月日啊。因此有个全局 date 过滤器,幸福到哭。这个过滤器最好是同时支持以上俩种格式。要是不知道
数字处理。像保留几位小数、超过多少位以字母 w 代替,或者是汉字“亿”都很常见
上面俩种是我碰到的最多的,也欢迎你评论补充。
该用 filters 的地方千万别手软,超过一处就要写成公共的。否则后期要是逻辑处理的不对,你不知道哪些地方用了相同的处理逻辑很容易造成 bug 漏改的情况。
这个属性也分为全局和局部使用,全局使用了将会对之后的所有组件产生影响。因此我不建议在业务代码中使用全局 mixins。而且感觉全局 mixins 使用起来不利于代码维护,你想突然在 template 中使用了一个一个函数第一想法肯定是去 methods 中查找,找不到就很难受了。而且破坏性也比较大,所以我都采用局部注入的方式。让别人知道这里采用了 mixins,要是遇到了一些奇怪的情况,他知道这里有 mixins 就会主动去这里面查看相关代码了。
这个属性我用的最多的是引用第三方的列表库的时候他通常都会有个 formatter 的格式化数据属性。这里 filters 是用不了的。但像列表对于数据的处理重复性是特别多的,因此 注入一个 mixins 就方便多了。
钩子函数 beforeEach 做路由跳转的时候会先执行 beforeEach 。因此你可以在路由跳转的时候进行判定是否可以跳转,常见场景就是判定用户是否登录,有没有某个页面的权限
// to: Route: 即将要进入的目标 路由对象
// from: Route: 当前导航正要离开的路由
// next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
router.beforeEach((to, form, next) => {})
action 的技巧 action 是可以异步执行方法的。我在业务中通常会遇到这样的情况:获取某种信息,但是这个信息接口多个页面都用到了,每个页面都处理一下这个接口真的很麻烦。所以传入 vuex 中共享这部分信息就十分幸福了。因为是异步的所以用到了 action。提供一个参考代码:
actions: {
getMemberShip ({ state, commit }) {
return new Promise((resolve, reject) => {
if (!state.memberShip) {
// memberShip 为 ajax 请求方法
memberShip(state.userInfo).then(res => {
commit('setMemberShip', res)
resolve(res)
}).catch(err => {
reject(err)
})
} else {
resolve(state.memberShip)
}
})
},
}
这个是我定义的一个获取会员套餐的情况,会员套餐很多个页面都会用到。但是他改动次数频繁,而且也没必要用户一登录就去加载,因此使用 action 存起来。如果没有这个值就执行 ajax 请求,如果有就直接返回结果。
echarts 图表界的老大哥了,支持 N 多种图表,配置项说好几千应该没夸大其词吧。不过也正因为繁多的配置项才给了你更多的自由配置的可能。那用 echarts 有什么技巧呢?
快速定位配置项
echarts 包含标题、图例、提示框、标注、标线... ... 等控件,调整个样式真的不好找。但是现在官方新加入了一个术语速查手册,之前我都是去旧官方上查,现在新官方上有了这个东西可是有福了。我需要调整那个控件的效果在上面一点就带我到相应的 API 简直是好用到飞起。
优化项目代码 不是专门的数据展示项目,用到的图表类型其实不多。通常是一个图表反复用,而 echarts 配置一个图表通常都好几十行代码。把这个配置项拿出去只传进来一个参数代码多整洁。这个实现特别简单,要是还没这么做建议马上优化你的项目哦
axios 是类似于 ajax 的的第三方控件。所以这个我也是蛮有想法跟大家交流的。
我在开发中遇到一个坑,官方文档说支持 IE,但是 IE 压根不支持。是因为 axios 底层是用 promise 写的,IE 压根还不支持这个属性,因此需要引入 profill 。解决办法是引入 babel-polyfill
// 步骤1
npm install --save babel-polyfill
// 步骤2 在 vue.config.js 文件中加入以下内容
module.exports = {
configureWebpack: config => {
return {
entry: {
app:['babel-polyfill', './src/main.js']
}
}
}
}
拥有自己的 axios 默认配置 这个代码过长,我就不分享了。想要可以关注公众号入群交流(二维码在底部)
本来还想在酝酿酝酿,不过近期发现在不总结一下自己就快渐渐的忘记了,其中还有很多东西没写出来,像项目优化技巧,指令系统。但是这篇文字已经很长了。所以只能到这里了,如果你觉得对你有用欢迎点赞,如果你想跟我交流获得指导欢迎关注公众号加我微信进行探讨。