- VueDevtools">1、安装 VueDevtools
- VuePerformanceDevtool(Vue性能开发工具)">2、安装 VuePerformanceDevtool(Vue性能开发工具)
- 3、组件间通信
- 4、使用VueX来做复杂的状态管理
- 5、代码切割效果
- 6、组件注册的简单方式
- 7、避免将所有组件都注册为全局组件
- 8、验证 props 属性
- VueRouter">9、VueRouter
- 10、url 变了,但视图没有更新
- 11、表单数据验证
- 12、好好理解一下 Vue 的生命周期
- 13、避免直接修改DOM
- 14、进行数据交互
- 15、列表遍历
- 16、计算属性和方法
- mixins">17、学习和使用 mixins
- 18、用上 Vue 自带的修饰符
- 19、好的系统布局和架构
- 20、做好必要的清理工作
- 21、往一个元素上添加多个 class
1、安装 VueDevtools
可以说,搞 Vue 开发,没有 VueDevtools 是不可行的。它是个火狐和 Chrome 浏览器里的扩展,装了它,就可以给你的 Vue 开发带来不尽的便利。
2、安装 VuePerformanceDevtool(Vue性能开发工具)
这个 Chrome 扩展可以让你检测 Vue 组件的性能,也是一个非常有用的工具,可以通过这个链接安装:
安装好了,你得在代码里加上这么一句,才能启用它:
Vue.config.performance = true;
记得要将其加在 new Vue 实例之前,当然了,这样的话,你生产环境上也就开启这个工具了,这往往不是我们想要的,你可以基于环境监测来决定是否开启这个,可以用下面的代码实现:
Vue.config.performance = process.env.NODE_ENV !== 'production'
3、组件间通信
Vue 里面组件间的通信有好几种形式。你可以使用 props 从上到下地往组件里传递数据,这是一种单向的沟通:
<my-component :firstProp="someValue"></my-component>
如果你想着在子组件里通知父组件,告诉它某些事情发生了,或某个值发生了变化,可以用子组件发送事件的方式:
...
export default {
methods: {
onClick() {
this.$emit('nameOfEvent', someValue);
}
}
}
然后你就可以在父级组件里,对这个事件的发生做相应监听和处理:
<my-component :firstProp="someValue" @nameOfEvent=”doSomething”></my-component>
这里的 $emit()发送事件的方法,只能用在 parent/child,也即父级和子级组件之间的通信。
如果你想着实现更复杂的组件间通信,比如两个子级组件之间,不通过父级,如何实现通信呢?这个时候你就可以使用 EventBus 或者 Vuex。EventBus 在小中型的应用里,基本上就够用了,如果你并没有特别复杂的组件间状态管理的话。
4、使用VueX来做复杂的状态管理
我们说过 EventBus 模式处理小中型项目够用了,因为它简单直接,但如果你确定要做一个大中型的项目,你的前端应用里有较多数据处理,有很多贯穿整个应用的状态需要共享或处理,那么这个时候,就一般要使用 VueX 了。
学习和使用 VueX 的建议:
- 去学一下 VueX 里的 state, getters, mutations and actions 这些分别是啥
- 研究一下 Vuex modules,建议如果用VueX,就最好上来就用上 VueX modules,如果你觉得 VueX modules繁琐、不值得,那么可能你的应用也没复杂到非得用VueX的地步
- 学一下如何创建出好的结构,因为 VueX 默认并没有给你任何限制
- 学一下“strict”模式是如何运作的
- 可以多参考一下这个 Vuex Cheatsheet
5、代码切割效果
现如今,性能是个热门话题,随着你应用越来越大、越来越复杂,我们得让其越快越好。尽可能地实现代码切割效果,这样可以极大减小你主要的 bundle 或 app 文件的体积,因而能提高你应用的初始化时间。
const Loader = () => import(/* webpackChunkName: "aChunkName" */'../path/to/component.vue');
6、组件注册的简单方式
传统上,我们喜欢这样来注册 Vue 组件:
import MyAwesomeComponent from './my-awesome-component.vue';
...
components: {
'my-awesome-component': MyAwesomeComponent
}
这没啥错,但你也可以更简洁一些:
...
components: {
MyAwesomeComponent,
MyAwesomeComponentTwo,
MyAwesomeComponentThree
}
7、避免将所有组件都注册为全局组件
只有一些基本的组件,你在应用里到处用到,才应该被注册为全局组件,比如说一些Buttons/Inputs
组件。
特定功能的组件,可以引入到其他的组件里,同时可以的话用上动态引入,这样可以让你的bundle文件小一些,性能更好一些,这块可以多参考前面的代码切割建议和文章。
8、验证 props 属性
当往一个组件里传参时,你最好是立马就进行一些验证,如果没有验证,没有声明一个 props 应该是个什么类型(String, Array, Object……),那么尤其是你团队里其他调用你组件的人,他们就不知道该传个啥了,包括你自己,当数据类型发生变化或错误时,你也没有个很好的错误提示了。
9、VueRouter
如果你是要做个单页应用(spa),纯前端逻辑的话,那么很可能你会需要用到客户端方面的路由,需要在不同组件之间跳来跳去,这个时候就可以用上 VueRouter,它是 Vue 官方的路由组件。
10、url 变了,但视图没有更新
当在一个 SPA 里时,你很可能会想着在视图里重复利用一些组件。假设你现在在一个博客文章页面上,然后你想从那个页面跳到另一篇文章上,你会期望相应的内容也改成新的文章的内容,但它却没有变化。
这往往是复用同一个组件的结果,Vue 还是用了之前的一个实例,这时候组件里this.$route
是变了,但是相应的那些生命周期事件,比如 created(), beforeMounted() 和 mounted(),它们就没有被重新触发。
这个问题,一般有两种解决办法:
要强制 Vue 创建一个新的组件实例,可以在<router-view>
设置一个unique key:
<router-view :key="$route.fullPath">
或者你也可以设置个 watch 函数,当 route 路由变了的时候,就触发相应逻辑:
watch: {
"$route.params.somevalue": {
handler(somevalue) {
// do stuff
},
immediate: true
}
}
11、表单数据验证
当前端有表单时,我们可能会想着在前台页面直接加上验证,这样可以免去非得先往后端验证一下,当然这不是说你后端就不验证了,双重的验证仍是必要的,只是这样可以让前端体验更好更直接一些。
当然了,你没必要自己去处理前端验证的提示和逻辑,已经有这方面很好的组件了,可以试试 Vuelidate 或 VeeValidate,两个都不错,都可以帮你节省不少时间
12、好好理解一下 Vue 的生命周期
要想真正发挥出 Vue 的强大,就极其建议你好好理解 Vue 的生命周期。
比方说,如果你想在 beforeCreated() 下去获取 data 里的一个值,那么就肯定获取不到;或者,你想在 created() 里去获取一个 ref 元素,那么你也获取不到,因为这个时候还没有加载 DOM 元素呢。
13、避免直接修改DOM
使用 Vue 的一个首要原则就是,你不能直接去操作和修改 DOM 元素,这也是我们用一个像 Vue 这样的前端框架的目的,就不再像原生 js 或j query 里那样了。
当然了,你可以用$refs来进行相关操作,这是更简洁更符合 Vue 的方式的做法,这样也更容易日后维护,因为这样你就不需要依赖有着某个特定class或id的元素了。
14、进行数据交互
开发中,难免我们需要跟一些外部的服务沟通,来获取或发送数据,比如我们的后端 API。
那么最简单的,你可以用浏览器自带的 fetch() 方法来获取数据,当然这个不一定所有浏览器都支持。
此外呢,建议使用axios
组件来做各种数据访问和交互,它在 Vue 和 React 社区里极其受欢迎。
15、列表遍历
Vue 里面可以用 v-for 很方便地进行列表遍历:
<div v-for="item in items" v-bind:key="item.id">
<!-- content -->
</div>
当你的 v-for 是用来循环输出一个简单的 array 时,其中的:key
是可以不用指定的,但当你的 v-for 是用在一个组件上时,也即循环输出某个组件的内容和逻辑时,就必须得加上:key
,这样的话,当你列出来的某一个组件逻辑发生变化时,Vue 才知道到底要去更新列表里的哪一个,所以这个:key
就相当于是列表元素的一个辨识符。当然了,你也可以不管 v-for 的逻辑是否复杂,是否是用在子组件上,你默认都带上:key
。
16、计算属性和方法
当你想对 Vue 实例里已有的 data 数据进行进一步处理时,就可以用计算属性,它的另一个好处是性能有保证,因为计算属性的结果是会被缓存的,只要它所依赖的数据不变,它就不用来回去计算,不用每次都计算一下。
data:{
names: ["Leonardo", "Donatello", "Rafael", "Michaelangelo"]
},
computed:{
//返回名字以D开头的球星
startsWithD(){
return this.names.filter(name => name.startsWith("D"))
}
}
<p v-for="(name, index) in startsWithD" :key="index"></p>
如果你有个很复杂的计算属性,那么最好的做法时,将其拆分成多个简单的计算属性,这样更容易测试、维护和阅读。
而一个方法,可以理解成是绑定到Vue实例上的一个函数,它只有当你明确调用它的时候才执行,就跟一个普通的 js 或 PHP 里的方法一样。
methods:{
startWithCharacter(char){
return this.names.filter(name => name.startsWith(char))
}
}
17、学习和使用 mixins
当我们开发应用时,经常会遇到一些功能和逻辑,需要在不同的组件间多次使用,比如同样的方法逻辑,两个组件都要用到,但我们又不想也不应该完全复制两遍,这个时候就该用 mixins 了。
这意味着,如果我创建了一个组件,它有X个不同的方法、周期逻辑、本地的状态等,我想复用它们,我就可以创建个 mixins,让其他的组件扩展这个 mixins,就可以在这些新的组件里使用原本它们没有的方法了。
18、用上 Vue 自带的修饰符
在不同的场景下,Vue有一系列不同的修饰符可以用,建议大家可以大概看看,在一些场景下用起来还是比较方便的。
这里呢,并不对它们具体展开,因为都比较简单,大家可以直接看文档即可。
- .lazy
- .number
- .trim
事件修饰符
原本我们经常需要用event.preventDefault()
来阻止提交按钮或点击事件的默认动作,但是有了Vue的事件修饰符,我们就可以在绑定事件时加上个.stop
来阻止单击事件继续传递,用.prevent
来阻止表单提交的默认刷新,非常方便,当然还有更多类似的。
- .stop
- .prevent
- .capture
- .self
- .once
- .passive
按键修饰符,可以很方便地监听一些按键事件,文档地址跟上面的事件修饰符是一个
- .enter
- .tab
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
19、好的系统布局和架构
Vue 没有给你提供任何默认的系统布局或架构,除非比如说你用 Nuxt 之类的基于 Vue 的框架。
所以怎么组织你的应用结构,就取决于你自己了,取决于你的团队了,你们怎么样协商出一个好的、易于理解的应用结构,让所有的团队成员能更好地开展协作。
如果你是个私人的小项目,你可能不需要太在意这点,但如果你们是一个大中型的团队项目,那么这一点,将对你们极其重要,一个好的、有意义的系统结构,可以让你们的日常开发事半功倍、相互不牵扯。
这一点上,可以多借鉴后端应用和框架的通行做法,比如模块化,将原本单个的、相互牵扯的应用,开发成一个一个独立的模块,各个模块间相互不影响,只通过有限的途径进行沟通;也可以借鉴后端比较流行的微服务架构,将原本一个庞大的系统,拆分成多个微服务,它们完全独立、不相干,甚至不同的部分都可以用不同的语言、不同的框架。这些做法或趋势,也正在被逐步实践到前端框架和项目当中,在大型项目开始前,能将这个设计好,将会为你们的开发奠定良好长远的基础。
20、做好必要的清理工作
当你在开发一个 SPA 应用时,如果你不留意去移除一些自定义的事件、实例、intervals 等,就可能导致应用的内存占用越来越多,最终变得缓慢甚至无法响应。
可以是像类似这个样子:
created() {
refreshUserLoginTokenInterval(); //开启一个interval来刷新token
},
beforeDestroy () {
destroyUserLoginInterval(); //在组件销毁前,要记得移除这个interval
}
21、往一个元素上添加多个 class
添加一个 class 是很简单的:
//当isError是true时,就加上red这个class
<div :class=”{'red': isError}”></div>
但是怎么样添加多个 class 呢?其实也很简单
// 相应属性为true时,就添加相应class
<div :class="{'red': isError, 'text-bold': isActive }”></div>
当然了,当添加多个 class 时,你也可以使用计算属性来实现。