學習筆記:Vue——組件和Prop


前言:這一篇是關於組件基礎、組件注冊、Prop等內容。


 

1.組件基礎

01.組件是可復用的Vue實例

 

02.組件中的data選項必須是一個函數

 

03.一個組件默認可以有任意數量的prop

任何值都可以傳遞給任何prop。就像訪問data一樣。

 

04.使用$emit監聽子組件事件

一個全局的子組件代碼:

Vue.component('blog-post', {
    props: ['post'],
    template: `
        <div class="blog-post">
            <h3>{{ post.title }}</h3>
            <button v-on:click="$emit('enlarge-text', 0.1)">放大文字</button>
            <div v-html="post.content"></div>
        </div>
    `
})

父組件代碼:

<blog-post v-bind:post="post" :style="{fontSize: postFontSize + 'em'}" v-on:enlarge-text="onEnlargeText"></blog-post>
var vm = new Vue({
    el: '#app',
    data: {
        post: {
            id: 1,
            title: '給一個青年詩人的十封信',
            content: '<p>Vue從入門到實戰</p>'
        },
        postFontSize: 1
    },
    methods: {
        onEnlargeText: function (enlargeAmount) {
            this.postFontSize += enlargeAmount
        }
    }
})

 

05.使用事件拋出一個值

子組件的一個事件可以通過$emit的第二個參數來提供一個值,在父級組件監聽這個事件時,通過$event訪問被拋出的這個值。

<blog-post
  ...
  v-on:enlarge-text="postFontSize += $event"
></blog-post>

 

06.在組件上使用v-model

自定義事件也可以用於創建支持v-model的自定義輸入組件

<input v-model="searchText">

等價於:

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

當用在組件上時,v-model則會這樣:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

為了讓它正常工作,這個組件內的<input>必須:

  • 將其value特性綁定到一個名叫value的prop上
  • 在其input事件被觸發時,將新的值通過自定義的input事件拋出

示例如下:

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})

現在v-model就應該可以在這個組件上完美地工作起來了:

<custom-input v-model="searchText"></custom-input>

 

07.動態組件

Vue有一個<component>元素,它有一個is屬性

<!-- 組件會在 `currentTabComponent` 改變時改變 -->
<component v-bind:is="currentTabComponent"></component>

在上述示例中,currentTabComponent可以包括:

  • 已注冊組件的名字,或
  • 一個組件的選項對象

 

08.特殊的is屬性的妙用

有些html元素,諸如<ul>、<ol>、<table>、<select>,對於哪些元素可以出現在其內部是有嚴格限制的。

<table>
  <blog-post-row></blog-post-row>
</table>

這個自定義組件<blog-post-row>會被作為無效的內容提升到外部,使用is特性可解決:

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

 

 

2.Prop

01.Prop類型

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

 

02.傳入一個對象的所有屬性

如果你想要將一個對象的所有屬性都作為prop傳入,你可以使用不帶參數的v-bind取代b-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>

 

03.單向數據流

所有的prop都使得其父子prop之間形成了一個單向下行綁定

每次父級組件發生更新時,子組件中所有的prop都將會刷新為最新的值。這意味着你不應該在一個子組件內部改變prop。

 

04.Prop驗證

這在開發一個會被別人用到的組件時尤其有幫助。

Vue.component('my-component', {
    props: {
        //基礎的類型檢查
        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 ['success', 'warning', 'danger'].indexOf(value) !== -1
            }
        }
    }
})

注意:那些prop會在一個組件實例創建之前進行驗證,所以實例的屬性(如data、computed等)在default或validator函數中不可用。

 

05.類型檢查

type可以時下列原生構造函數中的一個:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

type還可以是一個自定義的構造函數,並且通過instanceof來進行檢查確認。例如,給定下列現成的構造函數:

function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

你可以使用:

Vue.component('blog-post', {
  props: {
    author: Person
  }
})

來驗證author prop的值是否是通過new Person創建的

 

06.非Prop的特性

(1)組件可以接受任意的特性,而這些特性會被添加到這個組件的根元素上

(2)替換/合並已有的特性

對絕大多數特性來說,從外部提供給組件的值會替換掉組件內部設置好的值。所以如果傳入 type="text" 就會替換掉 type="date" 並把它破壞。 class 和 style會合並兩邊的值。

(3)禁用特性繼承

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

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

一個基礎組件的例子:

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})

注意:inheritAttrs: false不會影響style和class的綁定

這個模式允許你在使用基礎組件的時候更像是使用原始的HTML元素,而不會擔心哪個元素是真正的根元素

<base-input
  v-model="username"
  required
  placeholder="Enter your username"
></base-input>

 

 

筆記摘自Vue官方文檔:

 


免責聲明!

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



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