vue代碼規(guī)范

非原創(chuàng),轉(zhuǎn)公司的,覺得很不錯想保存下來,侵權刪

組件名為多個單詞

組件名應該始終是多個單詞的,根組件 App 以及 、 之類的 Vue 內(nèi)置組件除外。
這樣做可以避免跟現(xiàn)有的以及未來的 HTML 元素相沖突,因為所有的 HTML 元素名稱都是單個單詞的。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('todo', {
  // ...
})

export default {
  name: 'Todo',
  // ...
}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('todo-item', {
  // ...
})

export default {
  name: 'TodoItem',
  // ...
}</pre>

* * *

組件數(shù)據(jù)

組件的 data 必須是一個函數(shù)。 [為什么]
當在組件中使用 data property 的時候 (除了 new Vue 外的任何地方),它的值必須是返回一個對象的函數(shù)。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('some-comp', {
  data: {
    foo: 'bar'
  }
})

export default {
  data: {
    foo: 'bar'
  }
}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('some-comp', {
  data: function () {
    return {
      foo: 'bar'
    }
  }
})

// In a .vue file
export default {
  data () {
    return {
      foo: 'bar'
    }
  }
}

// 在一個 Vue 的根實例上直接使用對象是可以的,
// 因為只存在一個這樣的實例。
new Vue({
  data: {
    foo: 'bar'
  }
})</pre>

* * *

Prop定義

Prop 定義應該盡量詳細。
在你提交的代碼中,prop 的定義應該盡量詳細,至少需要指定其類型。

詳解
細致的 prop 定義有兩個好處:

  • 它們寫明了組件的 API,所以很容易看懂組件的用法;
  • 在開發(fā)環(huán)境下,如果向一個組件提供格式不正確的 prop,Vue 將會告警,以幫助你捕獲潛在的錯誤來源。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 這樣做只有開發(fā)原型系統(tǒng)時可以接受
props: ['status']</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">props: {
  status: String
}

// 更好的做法!
props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}</pre>

* * *

為 v-for 設置鍵值

總是用 key 配合 v-for [為什么]
在組件上總是必須用 key 配合 v-for,以便維護內(nèi)部組件及其子樹的狀態(tài)。甚至在元素上維護可預測的行為,比如動畫中的對象固化 (object constancy),也是一種好的做法。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><ul>
  <li v-for="todo in todos">
    {{ todo.text }}
  </li>
</ul></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><ul>
  <li
    v-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul></pre>

* * *

避免 v-if 和 v-for 用在一起

永遠不要把 v-if 和 v-for 同時用在同一個元素上。 [為什么]
一般我們在兩種常見的情況下會傾向于這樣做:

  • 為了過濾一個列表中的項目 (比如 v-for="user in users" v-if="user.isActive")。在這種情形下,請將 users 替換為一個計算屬性 (比如 activeUsers),讓其返回過濾后的列表。
  • 為了避免渲染本應該被隱藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。這種情形下,請將 v-if 移動至容器元素上 (比如 ul、ol)。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul></pre>

為組件樣式設置作用域

對于應用來說,頂級 App 組件和布局組件中的樣式可以是全局的,但是其它所有組件都應該是有作用域的。
這條規(guī)則只和單文件組件有關。這讓覆寫內(nèi)部樣式更容易:使用了常人可理解的 class 名稱且沒有太高的選擇器優(yōu)先級,而且不太會導致沖突。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><template>
  <button class="btn btn-close">X</button>
</template>

<style>
.btn-close {
  background-color: red;
}
</style></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><template>
  <button class="button button-close">X</button>
</template>

<!-- 使用 `scoped` attribute -->
<style scoped>
.button {
  border: none;
  border-radius: 2px;
}

.button-close {
  background-color: red;
}
</style></pre>

* * *

私有 property 名

使用模塊作用域保持不允許外部訪問的函數(shù)的私有性。如果無法做到這一點,就始終為插件、混入等不考慮作為對外公共 API 的自定義私有 property 使用 _ 前綴。并附帶一個命名空間以回避和其它作者的沖突 (比如yourPluginName)。**
這個約束主要是針對在使用插件及混入功能時,如果沒有涉及請忽略。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">var myGreatMixin = {
  // ...
  methods: {
    update: function () {
      // ...
    }
  }
}

var myGreatMixin = {
  // ...
  methods: {
    _update: function () {
      // ...
    }
  }
}

var myGreatMixin = {
  // ...
  methods: {
    $update: function () {
      // ...
    }
  }
}

var myGreatMixin = {
  // ...
  methods: {
    $_update: function () {
      // ...
    }
  }
}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">var myGreatMixin = {
  // ...
  methods: {
    $_myGreatMixin_update: function () {
      // ...
    }
  }
}

// 甚至更好!
var myGreatMixin = {
  // ...
  methods: {
    publicMethod() {
      // ...
      myPrivateFunction()
    }
  }
}

function myPrivateFunction() {
  // ...
}

export default myGreatMixin</pre>

* * *

組件文件

只要有能夠拼接文件的構(gòu)建系統(tǒng),就把每個組件單獨分成文件。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('TodoList', {
  // ...
})

Vue.component('TodoItem', {
  // ...
})</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- TodoList.js
|- TodoItem.js

components/
|- TodoList.vue
|- TodoItem.vue</pre>

* * *

單文件組件文件的大小寫

單文件組件的文件名應該要么始終是單詞大寫開頭 (PascalCase)
單詞大寫開頭對于代碼編輯器的自動補全最為友好,因為這使得我們在 JS(X) 和模板中引用組件的方式盡可能的一致。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- mycomponent.vue

components/
|- myComponent.vue</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- MyComponent.vue</pre>

* * *

基礎組件名

應用特定樣式和約定的基礎組件 (也就是展示類的、無邏輯的或無狀態(tài)的組件) 應該全部以一個特定的前綴(Win)開頭
基礎組件特定的前綴可以避免與三方組件沖突,也方便辨別哪些是自己的組件。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- WinButton.vue
|- WinTable.vue
|- WinIcon.vue</pre>

* * *

單例組件名

只應該擁有單個活躍實例的組件應該以 The 前綴命名,以示其唯一性。
這不意味著組件只可用于一個單頁面,而是每個頁面只使用一次。這些組件永遠不接受任何 prop,因為它們是為你的應用定制的,而不是它們在你的應用中的上下文。如果你發(fā)現(xiàn)有必要添加 prop,那就表明這實際上是一個可復用的組件,只是目前在每個頁面里只使用一次。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- Heading.vue
|- MySidebar.vue</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- TheHeading.vue
|- TheSidebar.vue</pre>

* * *

緊密耦合的組件名

和父組件緊密耦合的子組件應該以父組件名作為前綴命名。
如果一個組件只在某個父組件的場景下有意義,這層關系應該體現(xiàn)在其名字上。因為編輯器通常會按字母順序組織文件,所以這樣做可以把相關聯(lián)的文件排在一起。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue

components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue

components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue</pre>

* * *

組件名中的單詞順序

組件名應該以高級別的 (通常是一般化描述的) 單詞開頭,以描述性的修飾詞結(jié)尾。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue</pre>

* * *

方法命名的單詞順序

** 方法命名應該統(tǒng)一以 動詞+名詞的形式定義,不應該使用一個單詞進行命名,因為不便于描述方法的用途**

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">function click(){
  // do something
}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">function clickTreeNode(){
  // do something
}</pre>

* * *

自閉合組件

在單文件組件、字符串模板和 JSX 中沒有內(nèi)容的組件應該是自閉合的——但在 DOM 模板里永遠不要這樣做。
自閉合組件表示它們不僅沒有內(nèi)容,而且刻意沒有內(nèi)容。其不同之處就好像書上的一頁白紙對比貼有“本頁有意留白”標簽的白紙。而且沒有了額外的閉合標簽,你的代碼也更簡潔。

不幸的是,HTML 并不支持自閉合的自定義元素——只有官方的“空”元素。所以上述策略僅適用于進入 DOM 之前 Vue 的模板編譯器能夠觸達的地方,然后再產(chǎn)出符合 DOM 規(guī)范的 HTML。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!-- 在單文件組件、字符串模板和 JSX 中 -->
<MyComponent></MyComponent>

<!-- 在 DOM 模板中 -->
<my-component/></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!-- 在單文件組件、字符串模板和 JSX 中 -->
<MyComponent/>

<!-- 在 DOM 模板中 -->
<my-component></my-component></pre>

* * *

模板中的組件名大小寫

對于絕大多數(shù)項目來說,在單文件組件和字符串模板中組件名應該總是 PascalCase 的——但是在 DOM 模板中總是 kebab-case 的。
PascalCase 相比 kebab-case 有一些優(yōu)勢:

  • 編輯器可以在模板里自動補全組件名,因為 PascalCase 同樣適用于 JavaScript。
  • 視覺上比 更能夠和單個單詞的 HTML 元素區(qū)別開來,因為前者的不同之處有兩個大寫字母,后者只有一個橫線。
  • 如果你在模板中使用任何非 Vue 的自定義元素,比如一個 Web Component,PascalCase 確保了你的 Vue 組件在視覺上仍然是易識別的。 不幸的是,由于 HTML 是大小寫不敏感的,在 DOM 模板中必須仍使用 kebab-case。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!-- 在單文件組件和字符串模板中 -->
<mycomponent/>

<!-- 在單文件組件和字符串模板中 -->
<myComponent/>

<!-- 在 DOM 模板中 -->
<MyComponent></MyComponent></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!-- 在單文件組件和字符串模板中 -->
<MyComponent/>

<!-- 在 DOM 模板中 -->
<my-component></my-component></pre>

* * *

JS/JSX 中的組件名大小寫

JS/JSX 中的組件名應該始終是 PascalCase 的.

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('myComponent', {
  // ...
})

import myComponent from './MyComponent.vue'

export default {
  name: 'myComponent',
  // ...
}

export default {
  name: 'my-component',
  // ...
}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('MyComponent', {
  // ...
})

Vue.component('my-component', {
  // ...
})

import MyComponent from './MyComponent.vue'

export default {
  name: 'MyComponent',
  // ...
}</pre>

* * *

完整單詞的組件名

組件名應該傾向于完整單詞而不是縮寫。
編輯器中的自動補全已經(jīng)讓書寫長命名的代價非常之低了,而其帶來的明確性卻是非常寶貴的。不常用的縮寫尤其應該避免。
反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- SdSettings.vue
|- UProfOpts.vue</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue</pre>

* * *

Prop 名大小寫

在聲明 prop 的時候,其命名應該始終使用 camelCase,而在模板和 JSX 中應該始終使用 kebab-case。
在 JavaScript 中更自然的是 camelCase。而在 HTML 中則是 kebab-case。
反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">props: {
  'greeting-text': String
}

<WelcomeMessage greetingText="hi"/></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">props: {
  greetingText: String
}

<WelcomeMessage greeting-text="hi"/></pre>

模板中簡單的表達式

組件模板應該只包含簡單的表達式,復雜的表達式則應該重構(gòu)為計算屬性或方法。
復雜表達式會讓你的模板變得不那么聲明式。我們應該盡量描述應該出現(xiàn)的是什么,而非如何計算那個值。而且計算屬性和方法使得代碼可以重用。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">{{
  fullName.split(' ').map(function (word) {
    return word[0].toUpperCase() + word.slice(1)
  }).join(' ')
}}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!-- 在模板中 -->
{{ normalizedFullName }}

// 復雜表達式已經(jīng)移入一個計算屬性
computed: {
  normalizedFullName: function () {
    return this.fullName.split(' ').map(function (word) {
      return word[0].toUpperCase() + word.slice(1)
    }).join(' ')
  }
}</pre>

簡單的計算屬性

應該把復雜計算屬性分割為盡可能多的更簡單的 property。 [為什么]

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">computed: {
  price: function () {
    var basePrice = this.manufactureCost / (1 - this.profitMargin)
    return (
      basePrice -
      basePrice * (this.discountPercent || 0)
    )
  }
}</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">computed: {
  basePrice: function () {
    return this.manufactureCost / (1 - this.profitMargin)
  },
  discount: function () {
    return this.basePrice * (this.discountPercent || 0)
  },
  finalPrice: function () {
    return this.basePrice - this.discount
  }
}</pre>

* * *

帶引號的 attribute 值

非空 HTML attribute 值應該始終帶雙引號

在 HTML 中不帶空格的 attribute 值是可以沒有引號的,但這鼓勵了大家在特征值里不寫空格,導致可讀性變差。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><input type=text>

<AppSidebar :style={width:sidebarWidth+'px'}></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><input type="text">

<AppSidebar :style="{ width: sidebarWidth + 'px' }"></pre>

* * *

指令縮寫

指令縮寫 (用 : 表示 v-bind:、用 @ 表示 v-on: 和用 # 表示 v-slot:) 應該要么都用要么都不用。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><input
  v-bind:value="newTodoText"
  :placeholder="newTodoInstructions"
>

<input
  v-on:input="onInput"
  @focus="onFocus"
>

<template v-slot:header>
  <h1>Here might be a page title</h1>
</template>

<template #footer>
  <p>Here's some contact info</p>
</template></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><input
  :value="newTodoText"
  :placeholder="newTodoInstructions"
>

<input
  v-bind:value="newTodoText"
  v-bind:placeholder="newTodoInstructions"
>

<input
  @input="onInput"
  @focus="onFocus"
>

<input
  v-on:input="onInput"
  v-on:focus="onFocus"
>

<template v-slot:header>
  <h1>Here might be a page title</h1>
</template>

<template v-slot:footer>
  <p>Here's some contact info</p>
</template>

<template #header>
  <h1>Here might be a page title</h1>
</template>

<template #footer>
  <p>Here's some contact info</p>
</template></pre>

* * *

組件/實例的選項的順序

組件/實例的選項應該有統(tǒng)一的順序。

這是公司的組件選項默認順序。它們被劃分為幾大類,所以你也能知道從插件里添加的新 property 應該放到哪里。

  1. 副作用 (觸發(fā)組件外的影響)
    • el
  2. 全局感知 (要求組件以外的知識)
    • name
    • parent
  3. 組件類型 (更改組件的類型)
    • functional
  4. 模板修改器 (改變模板的編譯方式)
    • delimiters
    • comments
  5. 模板依賴 (模板內(nèi)使用的資源)
    • components
    • directives
    • filters
  6. 組合 (向選項里合并 property)
    • extends
    • mixins
  7. 接口 (組件的接口)
    • inheritAttrs
    • model
    • props/propsData
  8. 本地狀態(tài) (本地的響應式 property)
    • data
    • computed
  9. 事件 (通過響應式事件觸發(fā)的回調(diào))
    • watch
    • 生命周期鉤子 (按照它們被調(diào)用的順序)
    • · beforeCreate
    • · created
    • · beforeMount
    • · mounted
    • · beforeUpdate
    • · updated
    • · activated
    • · deactivated
    • · beforeDestroy
    • · destroyed
  10. 非響應式的 property (不依賴響應系統(tǒng)的實例 property)
*   methods
  1. 渲染 (組件輸出的聲明式描述)
*   template/render
*   renderError

元素 attribute 的順序

元素 (包括組件) 的 attribute 應該有統(tǒng)一的順序。
這是組件選項的默認順序。它們被劃分為幾大類,所以你也能知道新添加的自定義 attribute 和指令應該放到哪里。

  1. 定義 (提供組件的選項)
    • is
  2. 列表渲染 (創(chuàng)建多個變化的相同元素)
    • v-for
  3. 條件渲染 (元素是否渲染/顯示)
    • v-if
    • v-else-if
    • v-else
    • v-show
    • v-cloak
  4. 渲染方式 (改變元素的渲染方式)
    • v-pre
    • v-once
  5. 全局感知 (需要超越組件的知識)
    • id
  6. 唯一的 attribute (需要唯一值的 attribute)
    • ref
    • key
  7. 雙向綁定 (把綁定和事件結(jié)合起來)
    • v-model
  8. 其它 attribute (所有普通的綁定或未綁定的 attribute)
  9. 事件 (組件事件監(jiān)聽器)
    • v-on
  10. 內(nèi)容 (覆寫元素的內(nèi)容)
*   v-html
*   v-text

組件/實例選項中的空行

在多個 property 之間增加一個空行。
當你的組件開始覺得密集或難以閱讀時,在多個 property 之間添加空行可以讓其變得容易。在一些諸如 Vim 的編輯器里,這樣格式化后的選項還能通過鍵盤被快速導航。

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">props: {
  value: {
    type: String,
    required: true
  },

  focused: {
    type: Boolean,
    default: false
  },

  label: String,
  icon: String
},

computed: {
  formattedValue: function () {
    // ...
  },

  inputClasses: function () {
    // ...
  }
}</pre>

* * *

單文件組件的頂級元素的順序

單文件組件定級元素順序應該總是讓、、

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><style>/* ... */</style>
<script>/* ... */</script>
<template>...</template>

<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>

<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style></pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!-- ComponentA.vue -->
<style>/* ... */</style>
<template>...</template>
<script>/* ... */</script>

<!-- ComponentB.vue -->
<style>/* ... */</style>
<template>...</template>
<script>/* ... */</script></pre>

* * *

隱性的父子組件通信

**應該優(yōu)先通過 prop 和事件進行父子組件之間的通信,而不是 this.parent 或變更 prop。** 一個理想的 Vue 應用是 prop 向下傳遞,事件向上傳遞的。遵循這一約定會讓你的組件更易于理解。然而,在一些邊界情況下 prop 的變更或 this.parent 能夠簡化兩個深度耦合的組件。

問題在于,這種做法在很多簡單的場景下可能會更方便。但請當心,不要為了一時方便 (少寫代碼) 而犧牲數(shù)據(jù)流向的簡潔性 (易于理解)。

反例

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  template: '<input v-model="todo.text">'
})

Vue.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  methods: {
    removeTodo () {
      var vm = this
      vm.$parent.todos = vm.$parent.todos.filter(function (todo) {
        return todo.id !== vm.todo.id
      })
    }
  },
  template: `
    <span>
      {{ todo.text }}
      <button @click="removeTodo">
        X
      </button>
    </span>
  `
})</pre>

好例子

<pre class="addPadding" style="font-family: Consolas, Menlo, &quot;Liberation Mono&quot;, Courier, monospace; border-radius: 3px; display: block; padding: 6px 10px; margin: 1em 1em 1em 1.6em; background-color: rgb(250, 250, 250); border: 1px solid rgb(226, 226, 226); width: auto; overflow: auto hidden; color: rgb(51, 51, 51); font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Vue.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  template: `
    <input
      :value="todo.text"
      @input="$emit('input', $event.target.value)"
    >
  `
})

Vue.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  template: `
    <span>
      {{ todo.text }}
      <button @click="$emit('delete')">
        X
      </button>
    </span>
  `
})</pre>
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容