Vue开发规范
###############################
有赞:https://github.com/youzan/vant
https://github.com/iview/iview
https://github.com/ElemeFE/element
https://github.com/JosephusPaye/Keen-UI
https://github.com/ElemeFE/mint-ui
https://github.com/museui/muse-ui
https://github.com/youzan/vant
https://github.com/AT-UI/at-ui
zircle UI: https://zircleui.github.io/zircleUI/#/?id=introduction
https://vuetifyjs.com/components/breadcrumbs
https://github.com/xudafeng/autoresponsive-vue
https://github.com/xudafeng/autoresponsive-vue
https://github.com/Miller547719886/iview-FuncTable
单文件组件内容:
<!--componentA.vue--> <script>/*...*/</script> <template>...</template> <style>/*...*/</style>
组件相关:
尽可能的减少watcher的数量
尽量减少组件嵌套,递归渲染影响性能
大量数据渲染导致卡顿,可以先渲染用户可见部分,后面滚动在渲染其他数据
推荐用单文件的方式组织组件,利于提高单个组件的编辑查阅效率,即使不使用构建工具,也可以变通的使用单文件组件开发方式。
组件命名规则:
组件命名应使用完整单词。原因:避免歧义。
组件名必须为多个单词。原因:避免与未来的HTML元素冲突,配合框架或规范约束第一条理解。
- 基础组件加特定前缀预示复用性,例如Base;
- 单例组件用The前缀标识预示唯一性;
TheHeading.vue,
TheSidebar.vue
- 耦合组件中的子组件使用父组件名做前缀预示耦合关系,例如TodoList和TodoListItem;
- 相关组件命名用一般性描述单词开头,用修饰性单词结尾,例如ColorPicker、ColorPickerMulti、ColorPickerQuery。SearchButtonClear.vue,SearchButtonRun.vue
1.组件的 data 属性的值必须是返回一个对象的函数;
原因:如果直接用一个数据对象,则组件的多个实例之间会产生数据污染,导致失去复用价值。
2.组件的Prop在声明时推荐使用PascalCase(驼峰式),但在模板中必须使用kebab-case(连字符式);
原因:HTML对大小写不敏感。
组件的Prop 定义应该尽量详细,至少要定义类型,利于开发期间调试和提高组件代码可读性。
通过props和事件进行父子组件之间通信,不可使用this.$parent或改变prop。避免隐性的父子组件通信
区分vuex和props的使用边界:业务组件使用vuex维护状态,方便组件之间通信;通用组件使用props以及事件进行父子组件通信,与业务解耦. 在通用组件中定义props尽可能详细,指定类型
在除了DOM模板以外的任何地方使用自闭和组件写法,使代码更简洁,例如<my-component/>。
组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法,因为计算属性和方法利于复用和重构,而且模板也会看起来也更清晰易懂。
为列表渲染设置属性key。切忌使用下标作为key,会失去虚拟Dom对比的优化
v-for必须配合key使用;
原因:可以提高部分情况下Vue的渲染性能。
<div v-for = 'item in items' :key = 'item.id'>
<!--内容-->
</div>
在v-if/v-if-else/v-else 中使用key,添加key,对比虚拟Dom时会认为是不同的节点,将旧元素直接移除并在相同位置添加新元素
<div v-if = 'error' key = 'search-status'> {{error}} </div> <div v-else key = 'search-results'> {{results}} </div>
指令缩写要么一直用要么一直不用,提高模板可读性。指令缩写保持统一 ,用:表示v-bind,@表示v-on
避免v-if和v-for一起使用。
推荐做法
- 为过滤列表中的项目,可将循环列表替换为一个计算属性,返回过滤后的列表
- 为避免渲染本该隐藏的列表,可将v-if放到容器组件上
scoped 样式中避免使用元素选择器;
原因:遍历元素的效率通常很低
组件样式必须设置作用域,避免样式冲突,单文件组件可以选择使用scope特性,通用组件可以选择基于class的规则,例如BEM。
为组件样式设置作用域,通过scoped特性或者css Modules设置样式作用域,组件库使用class策略,使用容易理解的class名称且没有太高的选择器优先级,不容易导致冲突,拥有多个特性的元素应该分多行撰写,每个特性一行。
不要在选项属性或回调上使用箭头函数。比如 created: () => console.log(this.a)
或 vm.$watch('a', newValue => this.myMethod())
。因为箭头函数是和父级上下文绑定在一起的,this
不会是如你所预期的 Vue 实例,且 this.a
或 this.myMethod
也会是未定义的。
为所有路由统一添加query:上级路由携带的query参数,需要在所有路由中携带,且不影响切换
解决方案:
使用全局守卫beforeEach
// 缺点 全局守卫beforeEach会执行两次,且每次切换路由都会切换两次 const query = {refer: 'test'} router.beforeEach((to,from,next)=>{ to.query.referer ? next() : next({...to,query,...query}) })
使用函数劫持,推荐使用
const query = {refer: 'test'}; const transitionTo = router.history.transitionTo router.history.transitionTo = function(location,onComplete,onAbout){ location = typeof location === 'object' ? {...location,query:{...location.query,...query}} : {path:location,query} transitionTo.call(router.history,location,onComplete,onAbout) }
路由切换组件不变。路由的params参数改变不会重新触发组件的生命周期
解决方案
- 路由导航守卫beforeRouteUpdate,拉取数据重新渲染视图,vue-router2.2+支持,推荐使用,
-
观察$route对象的变化,添加watch,增加依赖追踪的内存开销
// good const User = { template:'...', watch:{ '$route.query.id'(to,from){ //.... }, '$route.query.page'(to,from){ //.... } } }
为router-view组件添加属性key,利用虚拟dom渲染通过key对比节点的原理,不足之处在于切换路由组件会被销毁并重新创建
<router-view :key = '$route.fullPath'></router-view>
js中方法名和类名规范:
- 类名遵循大驼峰命名规范: function MyClass() {}
- 方法名遵循小驼峰规范:function myFunc() {}
#####################