记录下 Vue 官方推荐的编码规范

823 阅读5分钟

开篇

话说盘古开天辟地之时~~~
串了,串了,串到昨晚在成都天府广场说书的时候了,你们有可能觉得我多才多艺,实则不然,我是因为在公司写代码的时候被大佬批评了,导致我很有可能拿不到绩效,拿不到绩效说明我这个月过不下去,所以我需要赚点外快,寒门的儿子也太难了!!!

以下是大佬和我的对话。

大佬开头就说你们某些人的代码让我以后怎么招聘人? 招聘来的人来看你的代码后去发掘金损坏公司形象你能负责吗?

  • 大佬:我昨天review了各位的代码,今天我们开个小会(批评会)
  • 大佬:我们来看看 xxx 的代码,你把v-for 和 v-if 写在一起干嘛?
  • 大佬:你 SbSettings.vue 这个组件是干嘛用的?不满公司了?
  • 大佬:你同一个页面,同一个组件,在没有slot的情况下,为什么 <MyComponent><my-component> 这两种写法都在?
  • 大佬:你这个***.vue文件,为什么1024行?领导内心活动(你tm的)!!
  • 大佬:你这个组件里面style 为什么不使用 scoped,还写个input 选择器?
  • 大佬:你为什么写了两个Input.vue?
  • 大佬:你都在用vue3了,为啥你提交的代码中一个use都看不到?
  • 大佬:.........
  • 我:哦,哦,哦,哦,哦,哦,........

随后大佬叫我认真看看文档,看了文档后终于能写出好看,可读性高的的代码啦!

必要的:

  • 组件名应该始终由多个单词组成
  • Prop的定义尽量详细,至少为其指定类型,加上validator会更好
  • 为vfor设置key值
  • 避免vif和vfor一起使用,推荐以下方式
    • 使用计算属性方式
    • 将vfor移动至template上(Vue3才支持)
  • 为组件样式设置作用域(scoped,css Modules)...
  • mixin中对外公开的api,使用$_前缀,并附带一个命名空间 例如:$_myGreatMixin_update

强烈推荐:

  • 编写组件最好把每个组件拆分成一个文件,不应该把多个组件写在一个文件里面
  • 单文件组件的文件名要么始终是大写字母开头(YourComponent),单词大写开头对于编辑器自动补全最友好,要么始终是横线链接(your-component)
  • 应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V等前缀,项目应该统一
    • BaseButton.vue
    • AppButton.vue
    • VButton.vue
  • 只应该拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性
    • 这并不意味着组件只可被用于一个页面,而是每个页面只能使用一次。这些组件永远不接受任何 prop
  • 紧密耦合的组件名称
    • 与父组件紧密耦合的子组件应该以父组件名作为前缀命名,不应该在父组件的目录中建立一个文件夹放置其它子组件
    • components/ 这样才规范
      • |- TodoList.vue
      • |- TodoListItem.vue
      • |- TodoListItemButton.vue
  • 组件名称应该以高阶的 (通常是一般化描述的) 单词开头,并以描述性的修饰词结尾
    • |- SearchButtonClear.vue
    • |- SearchButtonRun.vue
    • |- SearchInputExcludeGlob.vue
    • |- SearchInputQuery.vue
    • |- SettingsCheckboxLaunchOnStartup.vue
    • |- SettingsCheckboxTerms.vue
  • 在dom模板中 <my-component></my-component> 这种写法是永不过时的,因为dom不区分大小写,我们强烈建议使用 PascalCase 格式以保持一致性
  • 组件名称应该倾向于完整的单词,而不是缩写。
    • components/ 坏的
      • |- SdSettings.vue
      • |- UProfOpts.vue
    • components/ 好的
      • |- StudentDashboardSettings.vue
      • |- UserProfileOptions.vue
  • 在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case。
  • 多个 attribute 的元素应该分多行撰写,每个 attribute 一行。
  • 组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。
  • 应该把复杂计算属性尽可能多地分割为更简单的计算属性。
  • 非空 HTML attribute 的值应该始终带有引号 good <input type="text"> or bad <input type=text>
  • 指令缩写 (用 : 表示 v-bind:,@ 表示 v-on: 和用 # 表示 v-slot) 应该要么始终使用,要么始终不使用

推荐写法:

  • 元素 (包括组件) 的 attribute 应该有统一的顺序。
    • 定义 (提供组件的选项)
    • 列表渲染 (创建相同元素的多个变体)
    • 条件 (元素是否渲染/显示)
    • 渲染修饰符 (改变元素的渲染方式)
    • 全局感知 (要求在组件以外被感知)
    • 唯一性 Attribute (需要唯一值的 attribute)
    • 双向绑定 (结合了绑定与事件)
    • 其他 Attribute (所有普通的、绑定或未绑定的 attribute)
    • 事件 (组件事件监听器)
    • 内容 (覆写元素的内容)
  • 常用 attribute 顺序
    • is
    • v-for
    • v-if
    • v-else-if
    • v-else
    • v-show
    • v-cloak
    • v-pre
    • v-once
    • id
    • ref
    • key
    • .... 普通html attribute
    • v-model
    • v-on
    • v-html
    • v-text

谨慎使用的:

  • 元素选择器应该避免在 scoped 中出现,会导致查找很慢,应该使用其它例如class
<style scoped> 
  button {
    background-color: red;
  }
</style>
  • 尽量不要使用this.$parent或者refs的方式引用某个组件,最好使用prop向下传递数据,想上emit传递事件的方式,方便理解,易于理解
  • 应该优先通过 Vuex 管理全局状态,而不是通过 this.$root 或一个全局事件总线
  • 动态渲染两个不同的组件,应该使用内置的"component"使用,不应该使用v-if之类的

Vue3.2 的 <script setup>

  • <script setup> 中必须使用 definePropsdefineEmits API 来声明 props 和 emits ,
  • 它们具备完整的类型推断并且在 <script setup> 中是直接可用的
  • 为了在 <script setup> 组件中明确要暴露出去的属性,使用 defineExpose 编译器宏
  • <script setup> 使用 slots 和 attrs 的情况应该是很罕见的,因为可以在模板中通过 slotsslots 和 attrs 来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlotsuseAttrs 两个辅助函数
  • <script setup> 可以和 <script> 一起使用
  • <script setup> 不能写在外部js文件中,然后这样引入<script src=""/>是不行的,因为它依赖单文件组件的上下文