下篇主要内容为开发vue项目时的风格规范,良好的风格规范可以规避小纠结于反模式,同时提高项目的可读性和可维护性以及能带来良好的开发体验,上篇主要提及了vue项目的最佳实践,最佳实践可以帮助我们规避错误
vue常见优化手段(上)
状态管理 or props
我们有时会疑惑,某些状态究竟是放入vuex/pinia还是通过props来传入目标组件中
通常而言,业务组件中的状态会交由全局状态解决方案来维护,不同的组件共用一个方案,这样不同组件间的通信也会十分方便
对于通用组件,我们更倾向于使用props来维护状态,通用组件会被拿到各个业务组件中使用,需要于业务解耦,所以需要通过props来维护状态
组件命名
虽然组件的命名并不会影响代码的效率,但一个良好的组件命名规范能提高开发体验
基础组件名
如果是无逻辑,无状态,只是用来展示特定内容的组件我们应全部以 Base/App/V 开头
通常会包含所用到的元素名字 BaseTable,BaseInput 等等,因为这些组件会被频繁使用,所以需要将它们进行全局导入
不好的例子
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
好的例子
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
//or
components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
//or
components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
单例组件名
如果一个组件只会有一个活跃的实例,每个页面只会使用一次,那么这个组件应该以 The 开头
这个组件不会接受任何prop,如果我们发现有必要添加prop,就表明这实际上是一个可复用的组件,只是目前在每个页面里只使用了一次
不好的例子
components/
|- Heading.vue
|- MySidebar.vue
好的例子
components/
|- TheHeading.vue
|- TheMySidebar.vue
和父组件紧密耦合的组件名
和父组件紧密耦合的子组件应该以父组件名作为前缀命名
不好的例子
components/
|- TodoList/
|- Item/
|- index.vue
|- Button.vue
|- index.vue
我们通常的解决方案就是上面这个例子,通过目录结构来强调其与组件的相关性
但这会有以下问题
- 许多文件的名字相同,这使得在编辑器中快速切换文件变得困难
- 过多嵌套的子目录增加了在编辑器侧边栏中浏览组件所花的时间
更推荐的例子
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
自闭合组件
在单文件组件、字符串模板和JSX中,没有内容的组件应该是自闭合的,但在DOM模板中不能这么做
自闭合组件在语义上表示无法写内容,而不是可以有内容但没有写内容,而且没有额外的闭合标签,代码也更简洁,然而在DOM中并不支持自闭合标签
不好的例子
<!-- 在单文件组件、字符串模板和JSX中 -->
<MyComponent></MyComponent>
<!-- 在DOM模板中 -->
<my-component/>
更推荐的例子
<!-- 在单文件组件、字符串模板和JSX中 -->
<MyComponent/>
<!-- 在DOM模板中 -->
<my-component></my-component>
表达式
在模板中的表达式我们应尽可能的简单,如果有着复杂的表达式我们可以将其变成计算属性或方法
不好的例子
{{
fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}}
更推荐的例子
<!-- 在模板中 -->
{{ normalizedFullName }}
// 复杂表达式已经移入一个计算属性
computed: {
normalizedFullName: function () {
return this.fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}
}
更简单的计算属性
如果一个计算属性十分复杂的话我们应该将其拆分成多个简单的属性,拆分成多个属性有着许多优点:
- 易于测试
因为每个计算属性的依赖都十分简单,所以编写时不容易出错 - 易于阅读
给每个计算属性都取一个见名知意的名称,这样即是这个属性无法复用,开发者也知道这个属性是做什么的 - 更好地拥抱变化
这些属性我们都能用在视图上,在某些情况下我们能给用户提供更多信息
不好的例子
computed: {
price: function () {
var basePrice = this.manufactureCost / (1 - this.profitMargin)
return (
basePrice -
basePrice * (this.discountPercent || 0)
)
}
}
更推荐的例子
computed: {
basePrice: function () {
return this.manufactureCost / (1 - this.profitMargin)
},
discount: function () {
return this.basePrice * (this.discountPercent || 0)
},
finalPrice: function () {
return this.basePrice - this.discount
}
}