VUE2中文文檔:組件基礎篇


組件基礎

組件(component),是具有 name 名稱的可復用 Vue 實例:當前示例中是 <button-counter>。我們可以使用 new Vue 創建出一個 Vue 根實例,然后將這個組件作為其中的一個自定義元素(custom element)。

由於組件是可復用的 Vue 實例,它們接收的選項,和在 new Vue 時候的選項相同,例如 datacomputedwatchmethods 和生命周期鈎子。唯一的例外是,類似 el 這樣,根實例上特有(root-specific)的選項。

data 必須是一個函數

組件的 data 選項必須是一個函數,以便每個實例都可以維護「函數返回的數據對象」的彼此獨立的數據副本,

如果 Vue 沒有遵循這個規定,點擊其中一個按鈕,會影響其他所有用到此 data 的組件實例

組件注冊有兩種方式:全局注冊和局部注冊。

全局方式注冊的組件,可以用於之后創建的所有(通過 new Vue 創建的)Vue 根實例,以及 Vue 實例組件樹中所有子組件的內部。

使用 props 向子組件傳遞數據

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: '我的 Vue 旅程' },
      { id: 2, title: '用 Vue 寫博客' },
      { id: 3, title: 'Vue 如此有趣' },
    ]
  }
})

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>
Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

使用 events 向父組件發送消息

new Vue({
  el: '#blog-posts-events-demo',
  data: {
    posts: [/* ... */],
    postFontSize: 1                          //定義一個對象用作字體大小
  }
})

<div id="blog-posts-events-demo">
  <div :style="{ fontSize: postFontSize + 'em' }">        //將style屬性動態的綁定起來,一旦數據傳入可以及時更新
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:post="post"
      v-on:enlarge-text="postFontSize += 0.1"            //監聽enlarge-text事件,觸發則執行。
    ></blog-post>
  </div>
</div>
Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <button v-on:click="$emit('enlarge-text')>          //添加點擊事件,並且將此事件返回給父組件的enlarge-text事件
        放大文本
      </button>
      <div v-html="post.content"></div>
    </div>
  `
})

 

在 event 事件中發送一個值

有時,想在 event 事件中發送一個特定的值。例如,我們可能想要在 <blog-post> 組件自身內部,去控制放大文本字號的間隔。在這種情況下,我們可以使用 $emit 的第二個參數來提供字號間隔值:

<button v-on:click="$emit('enlarge-text', 0.1)">
  放大文本
</button>

<blog-post
  ...
  v-on:enlarge-text="postFontSize += $event"               //此時$event就是傳入的值0.1
></blog-post>

或者,如果事件處理函數是一個方法:

<blog-post
  ...
  v-on:enlarge-text="onEnlargeText"
></blog-post>

methods: {
  onEnlargeText: function (enlargeAmount) {              //此時$event傳入的值會作為方法的第一個參數,這里是enlargeAmount
    this.postFontSize += enlargeAmount
  }
}

 

在組件中使用 v-model

自定義事件(custom event),還可以用來創建出「實現 v-model 機制的自定義輸入框(custom input)」

<input v-model="searchText">

等同於如下:                             //完全意義上的等同   <input v-bind:value="searchText"                   //綁定value和searchText的值(即隨着searchText實時更新value) v-on:input="searchText = $event.target.value"        //將value值賦值給searchText >                                   //以上便實現了searchText和value的雙向綁定    

 

而用於一個組件時,也是如此。

為了組件內部能夠有效運行,組件內的 <input> 必須:

  • 將 value 屬性綁定到 value prop
  • 在 input 輸入框中,在自定義的 input 事件中,發送一個新的值

這里就是上面所描述的:

Vue.component('custom-input', {
  props: ['value'],                                 //2.接受父組件傳遞的value值
  template: `
    <input
      v-bind:value="value"                             //3.將收到的value賦值給input框的value
      v-on:input="$emit('input', $event.target.value)             //4.監聽input,並向父組件返回名為input的事件以及當前DOM的value
    >
  `
})

<custom-input v-bind:value="
searchText"                           //1.將searchText綁定到value v-on:input="searchText = $event"                       //5.接受子組件觸發input,將子組件傳遞的value賦值給searchText ></custom-input>
                                        //以上五點即有效實現了子組件和父組件完全復刻,也就是說v-modle在父組件也可以用了

所以,父組件用更簡潔的形式替代如下。
<custom-input v-model="searchText"></custom-input>
 

 

使用 slots 進行內容分發

通過 Vue 的 <slot> 自定義元素,可以非常簡單的實現這個任務:

Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})

<alert-box>
  發生一些錯誤。
</alert-box>

會被渲染為如下結果:

動態組件

 通過向 Vue 的 <component> 元素傳入 is 特性,

<!-- Component changes when currentTabComponent changes -->
<component v-bind:is="currentTabComponent"></component>

通過改變:is的值就可以改變組件的選擇。                          //話說這難道不是vue-router?

 

DOM 模板解析注意事項

有些 HTML 元素,例如 <ul><ol><table> 和 <select> 這些元素,會對於出現在其內部的元素有所限制;而另一些 HTML 元素,例如 <li><tr> 和 <option> 這些元素,只可以出現在前面那些元素的內部。

由於這種 HTML 運行機制,在這些受限制的元素內部使用組件,會導致一些問題。

自定義組件 <blog-post-row> 會被當作無效內容,提升到 table 元素之外,從而導致最終渲染輸出后的錯誤。幸運的是,is 特性提供了一種解決方案:

<table>
  <tr is="blog-post-row"></tr>
</table>

應當注意,在使用以下字符串模板之一的場景中,這些限制將不再適用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM