本文重点讲解对人人开源框架前端的小优化以及Vuex在项目中的真正应用!真正的彩蛋在后面~~~
背景
应该说我们这一代程序员是非常幸运的,无数免费开源的框架可供我们使用。比如:人人开源框架(https://www.renren.io/)。
有幸就业后陆陆续续使用这个框架开发项目,也和几个朋友把前后端以及数据库都玩了个遍。在进入新公司后,在与同事日常的沟通中,对前端领域的思想进一步的得到升华;今天主要就是分享最近的学习心得以及对这个框架的一些优化。
CDN引入
在性能优化方面,CDN引入是一个老生常谈的问题了,也是很普遍的优化方式。其方法网上也有很多,这里我记录几个坑:
1. index.html中,不要在head中引入cdn脚本,请在body中引入。
index引入cdn脚本2. 在webpack中外部库配置中,需要特别注意element-ui的配置,其cdn暴露出的组件名称是:ELEMENT,这点很多教程都没有指出,我也是自己踩坑后,查看了cdn源码才改回ELEMENT。
webpack配置3. cdn服务器的选择,笔者换这几个cdn换了半个多小时。本来一顿操作10分钟就能搞定,结果硬是跑不起来。最后索性换了个cdn的网址,成功了。。。。因此这里推荐一个cdn服务器:Bootcdn https://www.bootcdn.cn/
api模块抽取
这个是针对人人开源框架做的一个小优化。
1. 我把所有api抽出放在apis的文件内,并且与网络相关的都抽在services文件夹中;
apis2. 在vue实例下全局挂载$apis,页面级别直接使用this.$apis.xxx就可以了
全局挂载 页面使用3. apis的管理其实就是为了方便维护,后续接口的版本迭代,我们只需要统一在一个地方修改就行了。
VueX的使用心得
前言
这将是本文的彩蛋,这里主要分享的更多是一种项目架构的思想,也是我这两周一直在体会的。
案例
这是一个随处可见的需求:进入我的页面,请求个人信息并显示 → 点击编辑个人信息 → 保存个人信息并回到我的页面。
笔者愚昧,以往在项目中的流程基本都是:我的页面请求个人信息接口,编辑个人信息页面通过userId去请求个人信息并显示,点击保存请求修改接口,回退到我的页面,再次请求个人信息接口以达到视图更新。
这个过程就需要请求4次接口,而且数据基本都是重复的,小系统基本性能上无感知,但如果系统做大了,数据量达到千万级别,这种做法会极大增大服务器的负担。通过本次内容的分享,将使用vuex进行优化,下面请期待!
涉及技术
这个优化主要使用到,vue中的计算属性computed和vuex状态管理。下面简单讲解知识点:
1.计算属性computed和侦听属性watch:https://cn.vuejs.org/v2/guide/computed.html
1.1 概念:computed为计算属性,其依赖的值发生改变时,会触发computed进行更新,并且计算属性的getter是没有副作用的。
computer计算属性是基于它们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它们才会重新求值;这就意味着只要依赖没有改变,多次访问computer会立刻返回之前的计算结果,不必再次执行函数。(这与在视图中直接执行函数产生的性能差异是比较明显的)
1.2 getter和setter:计算属性默认只有getter,但需要时可以提供setter。应用场景见下:getter定义所依赖的变量,当依赖更新时getter会响应,并且重新计算更新视图;setter会在computed被设置的时候触发,这里可以做缓存或者通知vuex更新state等操作。实例见下图:
computed1.3 概念:watch为侦听属性,当你有一些数据需要随着watch改变的时候,可以使用。watch能实现的computed基本也可以实现,但是当数据变化时需要执行异步或者开销较大的操作时,watch是最有用的。如下面的例子:
watch使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
总结:当一个值依赖于其他值时,使用computed进行计算,依赖值改变会触发computed;当一个值影响到其他多个值时,使用watch进行侦听,watch值改变时,会触发对应函数,以达到影响其他值的的效果。一般情况下使用较多的事computed,当数据变化时需要执行异步或者开销较大的操作时,会使用到watch。
2. VueX教程:https://vuex.vuejs.org/zh/guide/state.html
2.1 五个属性:state、getter、mutations、actions、modules
2.2 state:即状态,代表组件中的数据,组件内这样调用:this.$store.state.xxx;
getter:可以看成store的计算属性(computed),getter的返回值同样会根据它的依赖被缓存起来,只有依赖值发生改变才会重新计算,组件内这样访问:this.$store.getters.xxx;
mutation:即Vuex中的事件,是Vuex中唯一可以改变store的地方。mutation中存在很多方法,每个方法都有一个事件类型和一个回调函数。回调函数必定接受state为第一个参数,之后的参数可以由调用者传入。调用者可以这样调用:this.$store.commit('user/updateName',val)。要注意,mutation是同步事务,异步事务切勿写在mutation中。
action:类似于mutation,但是action触发的是mutation,并不是直接更改状态;action用来处理任意异步操作。通过异步回调来调用mutation,以解决mutation同步事务的问题。调用者需要这样使用action:this.$store.dispatch(‘action-name’)。
实践
知识点讲解完毕,那么如何能够真正在项目中去应用这些知识点呢?
1. 假设我们建立一个user模块,我的页面、编辑个人信息页面都通过computed绑定vuex的state,这样当state被mutation更新时,页面中的computed依赖被更改,自然会重绘对应节点。
vuex模块2. 同时进入我的页面请求个人信息成功时,调用this.$store.commit('user/updateName', val)去更新state。
组件中视图绑定3. 之后进入编辑用户界面,无需调用接口直接显示state即可。点击确认修改时,分发事件给action,在.then回调中调用mutation去更新state。
分发action4. 回到我的页面时,也无需请求接口,因为state和computed已经驱动视图更新了。
总结:此种做法中,上面那个案例,整个流程就调了两次接口,一次获取用户信息,一次更改用户信息。而且数据的可维护性更高,而不是完全依赖于服务器。我想,这也是vuex状态管理设计的初衷吧。同理,笔者在开发flutter app时,这种思想也贯彻整个app的设计,这同样让我受益匪浅!
当然,也绝非每个接口都要通过vuex去管理,这需要看模块的,如果一个接口只使用一次,而且返回数据又不共用,那完全没必要这样子去做。大家还是需要理性选择。
希望大家多多指导我!
再会
网友评论