vue.js
25 Jan 2018router
route的代码组织也可以按照模块拼装到一起,这样每个模块的目录都有自己的router,代码的分割和维护更好一些。
router的一个重要的需要考虑的地方是history,如果不加任何控制,每次通过
带参数的router重新加载
很多时候,我们用同一个route带不同的参数,对应不同的内容,比如 /blog/:id,表示一条blog,那么问题来了,当切换id的时候,vue认为是同一条路由,不会重新加载,简单的解决方案就是:
<router-view :key="$route.fullPath" />
vuex
状态管理vuex是可选的,稍大的app都应该使用。一个常见场景是,多个page间切换、回退,如果每次都从服务器端加载数据,操作体验不好,所以要通过vuex把很多数据管理在全局store里,这样切换页面时,可以接近本地应用的体验。
vuex的核心是state,就是要管理的状态对象,同时封装了对state的两类操作mutation和action,可以把mutation理解为对state的同步修改,无关业务逻辑,action则是包含异步业务逻辑代码的,并且action并不直接修改state,而要通过mutation来修改(可以调用多次),这样整个封装就很清楚了。
为什么mutation要同步修改state,因为mutation遵循vux的响应规则,可以触发view的自动修改,所以必须同步修改掉state,因此所有需要异步操作后再修改state的操作必须封装在action里,另一个原因是同步的修改才可以被跟踪维护。
模板
有时为了使用v-if,或v-for,但不用不想绑定到任何tag上,可以使用内置的template标签,这样用:
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
转义
- 一般变量替换的时候内容都会被转义,html格式不再保留,可以用v-html=”var”来保留html格式。
- 如果不希望vue处理一段标签,可以在上层标签加v-pre属性。
动态模板
在很多时间需要从服务器端返回一段模板,插入当前页面,这是动态模板的应用,要做到支持动态模板,需要完整版本的vue(包括compiler),而不仅是runtime版本,在webpack配置中需要增加一个alias,类似
vue: 'vue/dist/vue.js'
然后在模板文件中,使用下面的方式来嵌入动态模板
<component :is="dynamicTemplate()" />
dynamicTemplate函数需要返回编译好的模块,类似:
return Vue.compile('<div>' + dynamicContent +'</div>')
之所以再套一个div,是因为Vue的模块需要单根。另一个需要注意的问题是,如果在动态模板内容中依赖一些组件,这些组件需要提前注册好,可以使用vue的全局模块注册。
组件
自定义组件中实现v-model需要做一些事情,把v-model替换为:
<custom-component :value="xxx" @input="xxx = $event"></custom-component>
就知道组件里应该做什么了,通常类似这样:
Vue.component('custom-input', {
props: ['value'],
template: `<input value="value" @input="$emit('input', $event.target.value)">`
})
这里有一点不统一,$event.target.value是html的intput送出的input事件参数,而自定义组件里,需要直接把这个值放出做event参数,不再需要target了。
全局变量
一般不应该使用全局变量,如果是希望在所有组件共用,可以用instance Properties:
Vue.prototype.$var = 'value'
css
在vue的模块css部分,可以用scoped指定是否这个css全局生效。
如果某些css需要依据环境动态加载,比如移动端使用,桌面不使用,可以在index.template.html里用条件模板的方式加入,比如:
<% if (htmlWebpackPlugin.options.ctx.mode.cordova) { %>
<style type="text/css">
*:not(input):not(textarea) {
-webkit-user-select: none; /* disable selection/Copy of UIWebView */
-webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
}
</style>
<% } %>
ajax
ajax组件在vue2中不是缺省内置的,在这里有解释, 官方的推荐是Axios。
通用处理
使用axios很容易做通用处理,包括异常处理,比如
Vue.prototype.$http = Axios.create({
baseURL: 'http://xxx.com/api',
headers: {'token': 'abcdefg'}
})
Vue.prototype.$http.interceptors.response.use(
response => { return response },
error => { return error.response ? Promise.reject(error) : Toast.create.negative('网络出错了') })
ui
- vant 有赞开源的ui库,非常轻量,自带icon,不错的组件设计
性能
大量的组件很容易导致render性能下降,可以在beforeCreated里加时标输出,再在mounted里加下面的时标输出:
this.$nextTick(function () {
console.log(Date.now())
})
两个时标相减来评估初始化+render时间,最简单的优化方法是减少不必要的组件,将大部分组件转换为标准html可以有效提高render性能。