vue-sfc.md 8.3 KB

vue 单文件组件

基本原则

总体原则

  1. 使用setup语法,组合式 API,而非选项式 API
  2. 不要使用mixins,vue3中已不推荐使用,参考:mixinsapp.mixin()
  3. 不要在 updated 钩子中更改组件的状态,这可能会导致无限的更新循环!
  4. 慎用provideinject
  5. 慎用watch,能在数据变化源头进行操作的,就不要用watch
  6. 适时进行组件拆分,组件中代码长度不宜超过300行(概数,少于或者略超都可接受),宽度不宜超过3/4 屏幕宽度,代码应适时空格换行空行
  7. 每次提交代码之前,应移除console.log等无用代码。

组件拆分原则

  1. 通常v-for遍历的每一项,应拆分为独立组件。除非场景极其简单,或者确定后续不再更改
  2. 通常v-if对应的每一项,应拆分为独立组件。除非场景极其简单,或者确定后续不再更改
  3. 通常modal组件中的内容,应拆分为独立组件
  4. 通常drawer组件中的内容,应拆分为独立组件
  5. 通常popover组件中的内容,应拆分为独立组件
  6. 通常表单应拆分为独立组件
  7. 过于复杂的组件应设法拆分为多个独立组件

模板-template

  1. v-ifv-for不要用在同一个节点上。
  2. v-for必须加独立的唯一的key,如果API不返回,客户端应设法构造一个唯一的可逆的key
  3. 任意节点的key都不能用随机数
  4. 不要在模板里写函数,例如:<button @click="() => {status = 1}">按钮</button>,这是糟糕的做法。
  5. 不要在模板里写过多js表达式,请使用计算属性或者其他定义好的值。例如:绑定的样式对象直接在模板里书写,这是糟糕的做法。
  6. 模板中的字符串使用双引号包裹,例如:<div title="标题"></div>
  7. 不要使用v-else,当在模板中存在条件判断时,应写完整的v-if,例如:<div v-if="open">开</div><div v-if="!open">关</div>。使用v-else不利于后续扩展
  8. 请使用缩写指令,@代替v-on:代替v-bind#代替v-slot
  9. 当节点上有多个属性时,应对每一个属性进行换行
  10. 在模板中使用自定义组件时,应写成大写驼峰(参考下方组件命名),而非小写中横线

脚本-script

  1. js中的字符串使用单引号包裹,例如:const user_name = ref('zhangsan')
  2. 代码不宜写成一坨,要进行合理的空行。通常做相似事情的代码可连续书写,当代码进行到下一类事情时,需空行。例如声明多个变量,可连续书写,当将要声明一个函数时,需空行后再进行函数声明。
  3. 关键词操作符之间要进行合理的空格
  4. 注释要清晰,必要时添加文档进行说明。请参考jsdoc进行注释。

样式-style

  1. 在样式中不要直接使用元素选择器
  2. 在样式中不要使用 deep

命名规范

为了统一风格,特对于项目中的命名进行一些规定。下方给出了一个项目的src目录中关键文件的命名示例

src/
  |- index.js
  |- App.vue
  |- assets/
    |- images/
      |- site-logo.png
      |- man.svg
      |- woman.svg
    |- audio/
      |- response-media.mp3
    |- video/
      |- movie.mp4
  |- store/
    |- index.js
    |- use-counter.js
  |- routes/
    |- index.js
  |- components/
    |- account/
      |- Login.vue
      |- Register.vue
    |- product/
      |- ProductCreateForm.vue
      |- ProductDetail.vue
    |- shop-online/
      |- ShopOnlineConfirmForm.vue
      |- ShopOnlineStatus.vue
  |- views/
    |- Index.vue
    |- About.vue
    |- Login.vue
    |- ProductDetail.vue

文件夹名称

文件夹名称一律小写,用中横线分隔。例如:shop-online

文件名称

除了组件名之外,其他类型的文件一律使用小写英文字母,使用中横线分隔。例如:response-media.mp3site-logo.png

第三方组件名在模板中的使用

对于第三方组件,使用小写中横线的方式进行书写。

<template>
  <a-space>
    <a-button type="primary">Primary</a-button>
    <a-button>Secondary</a-button>
    <a-button type="dashed">Dashed</a-button>
    <a-button type="outline">Outline</a-button>
    <a-button type="text">Text</a-button>
  </a-space>
</template>

自定义组件名称

组件名使用驼峰形式命名,例如:Index.vueProductDetail.vue

项目内自定义组件

对于项目内自定义组件,使用大写驼峰方式进行书写。

<template>
  <ViewContainer>
    <ProductDetail :id="product_id"/>

    <PriceHistory />
  </ViewContainer>
</template>

props命名

props命名使用小写下划线形式命名。例如下方的props.user_ageprops.user_name

<script>
const props = defineProps({
  foo: String,
  user_age: Number,
  user_name: String
});
</script>

emit命名

emit命名使用小写驼峰形式,例如:priceChange,messageFinished

无需加on前缀,例如:onPriceChange,这是错误做法。

<script>
const emit = defineEmits(['change', 'delete'])
</script>

变量命名

props命名,使用小写下划线形式。

const my_name = ref('张三');
const user_age = 18;
const theme_color = 'dark';

常量命名

常量使用大写字母加下划线的形式命名。

const PROJECT_TITLE = '小数智能'; // 项目名称

const EXPIRE_VALUE = 3600; // 过期时间

函数命名

函数名称同emit命名

function handleClick(){

}

/**
 * 获取产品的ID
 * @params {string} id - 产品ID
 **/
function getProductInfo(id){

}

类命名

使用大写驼峰形式命名。

class Human{

}

class Animals{

}

class ProductOrder{

}

关键顺序约定

单文件组件顺序

单文件组件中区块顺序按照template,script,style顺序进行书写。

<template>
  <div class="container">组件模板</div>
</template>

<script>
import { ref } from "vue";

const status = ref(1);
</script>

<style scoped>
.container {
  font-weight: bold;
}
</style>

<style>

</style>

模板中元素属性的顺序

在模板中为元素绑定属性,需要遵循一定的顺序,大致顺序如下:

  1. v-开头的指令,v-ifv-showv-for
  2. keyclassstyleidtitle
  3. 自定义属性,例如: :age="18":price="300"
  4. 事件 @click@input@change

    <template>
    <div 
    v-if="is_show" 
    class="news-title"
    :class="{'disabled': disabled}"
    title="标题"
    :age="18"
    @click="handleTitleClick"
    >这是新闻的标题</div>
    </template>
    

script标签内的顺序

单文件组件中,各项顺序大致如下:

  1. import
  2. defineProps
  3. defineEmits
  4. defineExpose
  5. refreactiveletconstvar
  6. computed
  7. watch
  8. 事件处理方法
  9. 生命周期钩子:onCreatedonMountedonUpdatedonBeforeUnmount

css属性规则的顺序

样式的定义应遵循一定的顺序。

建议遵循以下顺序:

  1. 布局定位属性:display / position / float / clear / visibility / overflow
  2. 自身属性:width / height / margin / padding / border / background
  3. 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
  4. 其他属性(CSS3):content / cursor / border-radius / box-shadow / text-shadow / background:linear-gradient …

参考:https://guide.aotu.io/docs/css/code.html#%E5%B1%9E%E6%80%A7%E4%B9%A6%E5%86%99%E9%A1%BA%E5%BA%8F

.title{
  display: block;
  position: relative;
  float: left;
  width: 100px;
  height: 100px;
  margin: 0 10px;
  padding: 20px 0;
  font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
  color: #333;
  background: rgba(0,0,0,.5);
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  -o-border-radius: 10px;
  -ms-border-radius: 10px;
  border-radius: 10px;
}