Vue文檔的深入了解組件這章節過程中的一些注意語句摘記一下

1, v-model 會忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實例的數據作為數據來源。你應該通過 JavaScript 在組件的 data 選項中聲明初始值。
2,v-model 在內部為不同的輸入元素使用不同的屬性并拋出不同的事件:
text 和 textarea 元素使用 value 屬性和 input 事件;
checkbox 和 radio 使用 checked 屬性和 change 事件;
select 字段將 value 作為 prop 并將 change 作為事件。
3, 單個復選框,綁定到布爾值: 多個復選框,綁定到同一個數組:
4, 如果 v-model 表達式的初始值未能匹配任何選項,<select> 元素將被渲染為“未選中”狀態。在 iOS 中,這會使用戶無法選擇第一個選項。因為這樣的情況下,iOS 不會觸發 change 事件。因此,更推薦像上面這樣提供一個值為空的禁用選項。
5,一個組件的 data 選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷貝:
6, 如果你想要將一個對象的所有屬性都作為 prop 傳入,你可以使用不帶參數的 v-bind (取代 v-bind:prop-name) 如:

post: {
  id: 1,
  title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
等價于: 
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

7,常見的試圖改變一個 prop 的情形:

這個 prop 用來傳遞一個初始值;這個子組件接下來希望將其作為一個本地的 prop 數據來使用。在這種情況下,最好定義一個本地的 data 屬性并將這個 prop 用作其初始值:
props: ['initialCounter'],
data: function () {
 return {
   counter: this.initialCounter
 }
}
這個 prop 以一種原始的值傳入且需要進行轉換。在這種情況下,最好使用這個 prop 的值來定義一個計算屬性:
props: ['size'],
computed: {
 normalizedSize: function () {
   return this.size.trim().toLowerCase()
 }
}

注意在 JavaScript 中對象和數組是通過引用傳入的,所以對于一個數組或對象類型的 prop 來說,在子組件中改變這個對象或數組本身將會影響到父組件的狀態。

8,對于絕大多數特性來說,從外部提供給組件的值會替換掉組件內部設置好的值。所以如果傳入 type="text" 就會替換掉 type="date" 并把它破壞!慶幸的是,class 和 style 特性會稍微智能一些,即兩邊的值會被合并起來,從而得到最終的值:form-control date-picker-theme-dark。

9,如果你不希望組件的根元素繼承特性,你可以在組件的選項中設置 inheritAttrs: false。例如:

Vue.component('my-component', {
  inheritAttrs: false,
  // ...
})
注意 inheritAttrs: false 選項不會影響 style 和 class 的綁定。

10: 不同于組件和 prop,事件名不存在任何自動化的大小寫轉換。而是觸發的事件名需要完全匹配監聽這個事件所用的名稱。v-on 事件監聽器在 DOM 模板中會被自動轉換為全小寫 (因為 HTML 是大小寫不敏感的),所以 v-on:myEvent 將會變成 v-on:myevent——導致 myEvent 不可能被監聽到。
因此,我們推薦你始終使用 kebab-case 的事件名。
11 : 一個組件上的 v-model 默認會利用名為 value 的 prop 和名為 input 的事件,但是像單選框、復選框等類型的輸入控件可能會將 value 特性用于不同的目的model 選項可以用來避免這樣的沖突:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
<base-checkbox v-model="lovingVue"></base-checkbox>
這里的 lovingVue 的值將會傳入這個名為 checked 的 prop。同時當 <base-checkbox> 觸發一個 change 事件并附帶一個新的值的時候,這個 lovingVue 的屬性將會被更新。注意你仍然需要在組件的 props 選項里聲明 checked 這個 prop。

12: 當我們用一個對象同時設置多個 prop 的時候,也可以將這個 .sync 修飾符和 v-bind 配合使用:

<text-document v-bind.sync="doc"></text-document>

這樣會把 doc 對象中的每一個屬性 (如 title) 都作為一個獨立的 prop 傳進去,然后各自添加用于更新的 v-on 監聽器。
13,父級模板里的所有內容都是在父級作用域中編譯的;子模板里的所有內容都是在子作用域中編譯的。
14: ## 后備內容
有時為一個插槽設置具體的后備 (也就是默認的) 內容是很有用的,它只會在沒有提供內容的時候被渲染。例如在一個 <submit-button> 組件中:

<button type="submit">
  <slot>Submit</slot>
</button>

15,## 具名插槽
自 2.6.0 起有所更新。已廢棄的使用 slot 特性的語法在這里
v-slot 只能添加在一個 <template> 上** (只有一種例外情況),這一點和已經廢棄的 slot特性不同。

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

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

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

16,只要出現多個插槽,請始終為所有的插槽使用完整的基于 <template> 的語法:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user>

17,作用域插槽的內部工作原理是將你的插槽內容包括在一個傳入單個參數的函數里:

function (slotProps) {
  // 插槽內容
}
這意味著 `v-slot` 的值實際上可以是任何能夠作為函數定義中的參數的 JavaScript 表達式。所以在支持的環境下[單文件組件或[現代瀏覽器],你也可以使用 [ES2015 解構]來傳入具體的插槽 prop,如下:
<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>

18,跟 v-on 和 v-bind 一樣,v-slot 也有縮寫,即把參數之前的所有內容 (v-slot:) 替換為字符 #。例如 v-slot:header 可以被重寫為 #header:
如果你希望使用縮寫的話,你必須始終以明確插槽名取而代之:

<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>

19,插槽 prop 允許我們將插槽轉換為可復用的模板,這些模板可以基于輸入的 prop 渲染出不同的內容。這在設計封裝數據邏輯同時允許父級組件自定義部分布局的可復用組件時是最有用的。

<ul>
  <li
    v-for="todo in filteredTodos"
    v-bind:key="todo.id"
  >
    <!--
    我們為每個 todo 準備了一個插槽,
    將 `todo` 對象作為一個插槽的 prop 傳入。
    -->
    <slot name="todo" v-bind:todo="todo">
      <!-- 后備內容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

<todo-list v-bind:todos="todos">
  <template v-slot:todo="{ todo }">
    <span v-if="todo.isComplete">?</span>
    {{ todo.text }}
  </template>
</todo-list>

20,這里的異步組件工廠函數也可以返回一個如下格式的對象:

const AsyncComponent = () => ({
  // 需要加載的組件 (應該是一個 `Promise` 對象)
  component: import('./MyComponent.vue'),
  // 異步組件加載時使用的組件
  loading: LoadingComponent,
  // 加載失敗時使用的組件
  error: ErrorComponent,
  // 展示加載時組件的延時時間。默認值是 200 (毫秒)
  delay: 200,
  // 如果提供了超時時間且組件加載也超時了,
  // 則使用加載失敗時使用的組件。默認值是:`Infinity`
  timeout: 3000
})

21,在每個 new Vue 實例的子組件中,其根實例可以通過 root 屬性進行訪問。 22,對于 demo 或非常小型的有少量組件的應用來說這是很方便的。不過這個模式擴展到中大型應用來說就不然了。因此在絕大多數情況下,我們強烈推薦使用 [Vuex](https://github.com/vuejs/vuex) 來管理應用的狀態。 23,當 ref 和 v-for 一起使用的時候,你得到的引用將會是一個包含了對應數據源的這些子組件的數組。 24,refs 只會在組件渲染完成之后生效,并且它們不是響應式的。這僅作為一個用于直接操作子組件的“逃生艙”——你應該避免在模板或計算屬性中訪問 $refs。
25,provide 選項允許我們指定我們想要提供給后代組件的數據/方法。

provide: function () {
  return {
    getMap: this.getMap
  }
}

然后在任何后代組件里,我們都可以使用 inject 選項來接收指定的我們想要添加在這個實例上的屬性:

inject: ['getMap']

然而,依賴注入還是有負面影響的。它將你應用程序中的組件與它們當前的組織方式耦合起來,使重構變得更加困難。同時所提供的屬性是非響應式的。這是出于設計的考慮,因為使用它們來創建一個中心化規模化的數據跟使用 $root做這件事都是不夠好的。如果你想要共享的這個屬性是你的應用特有的,而不是通用化的,或者如果你想在祖先組件中更新所提供的數據,那么這意味著你可能需要換用一個像 Vuex 這樣真正的狀態管理方案了。
26,組件是可以在它們自己的模板中調用自身的。不過它們只能通過 name 選項來做這件事:
稍有不慎,遞歸組件就可能導致無限循環:
類似上述的組件將會導致“max stack size exceeded”錯誤,所以請確保遞歸調用是條件性的 (例如使用一個最終會得到 false 的 v-if)。

27,### 內聯模板
當 inline-template 這個特殊的特性出現在一個子組件上時,這個組件將會使用其里面的內容作為模板,而不是將其作為被分發的內容。這使得模板的撰寫工作更加靈活。

<my-component inline-template>
  <div>
    <p>These are compiled as the component's own template.</p>
    <p>Not parent's transclusion content.</p>
  </div>
</my-component>

另一個定義模板的方式是在一個 <script> 元素中,并為其帶上 text/x-template 的類型,然后通過一個 id 將模板引用過去。例如:

<script type="text/x-template" id="hello-world-template">
  <p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
  template: '#hello-world-template'
})

28,### 強制更新
如果你已經做到了上述的事項仍然發現在極少數的情況下需要手動強制更新,那么你可以通過 $forceUpdate 來做這件事。
29,### 通過 v-once 創建低開銷的靜態組件
渲染普通的 HTML 元素在 Vue 中是非常快速的,但有的時候你可能有一個組件,這個組件包含了大量靜態內容。在這種情況下,你可以在根元素上添加 v-once 特性以確保這些內容只計算一次然后緩存起來,就像這樣:

Vue.component('terms-of-service', {
  template: `
    <div v-once>
      <h1>Terms of Service</h1>
      ... a lot of static content ...
    </div>
  `
})
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 主要還是自己看的,所有內容來自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,373評論 0 25
  • 以下內容是我在學習和研究Vue時,對Vue的特性、重點和注意事項的提取、精練和總結,可以做為Vue特性的字典; 1...
    科研者閱讀 14,122評論 3 24
  • vue學習筆記 安裝 Vue 提供一個官方命令行工具,可用于快速搭建大型單頁應用。只需幾分鐘即可創建并啟動一個帶熱...
    EL_PSY_CONGROO閱讀 1,085評論 0 5
  • 1. Vue 實例 1.1 創建一個Vue實例 一個 Vue 應用由一個通過 new Vue 創建的根 Vue 實...
    王童孟閱讀 1,029評論 0 2
  • 組件注冊 組件名 在注冊一個組件的時候,我們始終需要給它一個名字。 該組件名就是Vue.component的第一個...
    oWSQo閱讀 406評論 0 1