1-5. Vue.js核心知識之組件化

組件 (Component) 是 Vue.js 最強大的功能之一。組件能夠擴展 HTML 元素,封裝可重用的代碼。html

組件的建立和註冊

咱們可使用 Vue.component(tagName, options)註冊一個全局組件。vue

<!--全局註冊-->
<template>
  <div id="app">
    <my-component></my-component>
  </div>
</template>

<script>
  // 全局註冊組件
  Vue.component('my-component', {
    template: '<div>個人組件</div>'
  })

  // 建立根實例
  new Vue({
    el: '#app'
  })
</script>

<!--渲染後的HTML-->
<div id="app">
  <div>個人組件</div>
</div>

咱們還能夠經過某個 Vue 實例/組件的實例選項 components 註冊僅在其做用域中可用的組件,即局部組件。web

<!--局部註冊-->
<template>
  <div id="app">
    <my-component></my-component>
  </div>
</template>
<script>
  var Child = {
    template: '<div>個人組件</div>'
  }

  new Vue({
    el: '#app',
    components: {
      // 局部註冊組件,<my-component> 將只在父組件模板中可用
      'my-component': Child
    }
  })
</script>

<!--渲染後的HTML-->
<div id="app">
  <div>個人組件</div>
</div>
使用prop
組件實例的做用域是孤立的。父組件的數據須要經過 prop 才能下發到子組件中。

<!--靜態prop-->
<template>
  <child message="哈嘍"></child>
</template>
<script>
  Vue.component('child', {
    // 聲明 props
    props: ['message'],
    // 就像 data 同樣,prop 也能夠在模板中使用
    // 一樣也能夠在 vm 實例中經過 this.message 來使用
    template: '<span>{{ message }}</span>'
  })
</script>

若是想要傳遞一個變量到子組件中去,即傳給子組件的值會跟隨父組件中該變量的值的變化而變化,咱們能夠用 v-bind 來動態地將 prop 綁定到父組件的數據。數組

<!--動態prop-->
<template>
  <div id="dynamic-prop">
    <input v-model="parentMsg">
    <br>
    <child v-bind:my-message="parentMsg"></child>
  </div>
</template>
<script>
  new Vue({
    el: '#dynamic-prop',
    data: {
      parentMsg: '父組件發過來的消息'
    }
  })
</script>

咱們還能夠爲組件的 prop 指定驗證規則。若是傳入的數據不符合要求,Vue 會發出警告。這對於開發給他人使用的組件很是有用。app

<!--prop驗證-->
<script>
  Vue.component('example', {
    props: {
      // 基礎類型檢測 (`null` 指容許任何類型)
      propA: Number,
      // 多是多種類型
      propB: [String, Number],
      // 必傳且是字符串
      propC: {
        type: String,
        required: true
      },
      // 數值且有默認值
      propD: {
        type: Number,
        default: 100
      },
      // 數組/對象的默認值應當由一個工廠函數返回
      propE: {
        type: Object,
        default: function () {
          return { message: 'hello' }
        }
      },
      // 自定義驗證函數
      propF: {
        validator: function (value) {
          return value > 10
        }
      }
    }
  })
</script>

自定義事件進行組件通信

如今咱們父組件可使用 prop 傳遞數據給子組件。但子組件怎麼跟父組件進行通訊呢?這裏咱們能夠經過自定義事件來實現。框架

具體點說就是使用 $on(eventName) 監聽事件,使用 $emit(eventName, optionalPayload) 觸發事件。函數

<template>
  <div id="message-event">
    <p v-for="msg in messages">{{ msg }}</p>
    <button-message v-on:message="handleMessage"></button-message>
  </div>
</template>
<script>
  Vue.component('button-message', {
    template: `<div>
    <input type="text" v-model="message" />
    <button v-on:click="handleSendMessage">發送消息</button>
  </div>`,
    data: function () {
      return {
        message: '哈嘍'
      }
    },
    methods: {
      handleSendMessage: function () {
        this.$emit('message', { message: this.message })
      }
    }
  })

  new Vue({
    el: '#message-event',
    data: {
      messages: []
    },
    methods: {
      handleMessage: function (payload) {
        this.messages.push(payload.message)
      }
    }
  })
</script>

使用插槽分發內容

爲了讓組件能夠自由組合,咱們須要一種方式來混合父組件的內容與子組件本身的模板。這個過程被稱爲內容分發。咱們可使用特殊的 <slot> 元素做爲原始內容的插槽,從而實現內容分發。組件化

若是子組件模板包含一個 <slot> 插口,那麼父組件的內容將會被渲染到插槽中。ui

<!--子組件模板-->
<templalte>
  <div>
    <h2>子組件的標題</h2>
    <slot>
      只有在沒有要分發的內容時纔會顯示。
    </slot>
  </div>
</templalte>

<!--父組件模板-->
<template>
  <div>
    <h1>父組件的標題</h1>
    <my-component>
      <p>這是將會分發到子組件的一些初始內容</p>
    </my-component>
  </div>
</template>

<!--渲染後的HTML-->
<div>
  <h1>父組件的標題</h1>
  <div>
    <h2>子組件的標題</h2>
    <p>這是將會分發到子組件的一些初始內容</p>
  </div>
</div>

當須要有多個插槽時,咱們能夠在<slot> 元素上用一個特殊的特性 name 來進一步配置如何分發內容。多個插槽配置不一樣的名字,這時具名插槽將匹配內容片斷中有對應 slot 特性 name 的元素。this

<!--layout 子組件模板-->
<template>
  <div class="container">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<!--父組件模板-->
<template>
  <layout>
    <h1 slot="header">頭部標題</h1>

    <p>主體內容的一個段落。</p>

    <p slot="footer">尾部版權信息</p>
  </layout>
</template>

<!--渲染後的HTML-->
<div class="container">
  <header>
    <h1>頭部標題</h1>
  </header>
  <main>
    <p>主體內容的一個段落。</p>
  </main>
  <footer>
    <p>尾部版權信息</p>
  </footer>
</div>

總結

本節主要知識點是vue.js中組件的建立和註冊,父組件使用prop向子組件傳遞數據並進行數據驗證,使用自定義事件進行組件間的通信,使用插槽來使組件能夠自由組合。vue.js組件是vue框架中最強大的功能,學完後相信你對web組件化也會有必定的瞭解了。

相關文章
相關標籤/搜索