初學vue2.0-組件-文檔理解筆記v1.0

組件

  • 組件能夠擴展 HTML 元素,封裝可重用的代碼javascript

  • 在較高層面上,組件是自定義元素, Vue.js 的編譯器爲它添加特殊功能html

  • 在有些狀況下,組件也能夠是原生 HTML 元素的形式,以 is 特性擴展。vue

使用組件

註冊一個全局組件

<div id="example">
<!--web組件的定義脫離了通常的dom元素的寫法,至關於自定義了元素-->
  <my-component></my-component>
</div>
// 註冊全局組件,指定以前設定的元素名,而後傳入對象
Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})
// 建立根實例
new Vue({
  el: '#example'
})

局部註冊組件

沒必要在全局註冊每一個組件。經過使用組件實例選項註冊,可使組件僅在另外一個實例/組件的做用域中可用java

//將傳入給組件的對象單獨寫
var Child = {
  template: '<div>A custom component!</div>'
}
new Vue({
  //經過components語法建立局部組件
  //將組件僅僅放在這個vue實例裏面使用
  components: {
    // <my-component> 將只在父模板可用
    'my-component': Child
  }
})

DOM模板解析說明

當使用 DOM 做爲模版時(例如,將 el 選項掛載到一個已存在的元素上), 你會受到 HTML 的一些限制,jquery

由於 Vue 只有在瀏覽器解析和標準化 HTML 後才能獲取模版內容。
尤爲像這些元素 <ul> , <ol>, <table> , <select> 限制了能被它包裹的元素, <option> 只能出如今其它元素內部。web

<!--這種是不行的,會報錯-->
<table>
  <my-row>...</my-row>
</table>
<!--要經過is屬性來處理-->
<table>
  <tr is="my-row"></tr>
</table>

data必須是函數

使用組件時,大多數能夠傳入到 Vue 構造器中的選項能夠在註冊組件時使用,有一個例外: data 必須是函數。 實際上chrome

//這樣會報錯,提示data必須是一個函數
Vue.component('my-component', {
  template: '<span>{{ message }}</span>',
  data: {
    message: 'hello'
  }
})
<div id="example-2">
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
</div>
var data = { counter: 0 }
Vue.component('simple-counter', {
  template: '<button v-on:click="counter += 1">{{ counter }}</button>',
  // data 是一個函數,所以 Vue 不會警告,
  // 可是咱們爲每個組件返回了同一個對象引用,因此改變其中一個會把其餘都改變了
  data: function () {
    return data
  }
})
new Vue({
  el: '#example-2'
})

避免出現同時改變數據的狀況api

//返回一個新的對象,而不是返回同一個data對象引用
data: function () {
  return { //字面量寫法會建立新對象
    counter: 0
  }
}

構成組件

組件意味着協同工做,一般父子組件會是這樣的關係:數組

  • 組件 A 在它的模版中使用了組件 B 。它們之間必然須要相互通訊瀏覽器

  • 父組件要給子組件傳遞數據,子組件須要將它內部發生的事情告知給父組件

然而,在一個良好定義的接口中儘量將父子組件解耦是很重要的。這保證了每一個組件能夠在相對隔離的環境中書寫和理解,也大幅提升了組件的可維護性和可重用性。

在 Vue.js 中,父子組件的關係能夠總結爲 props down, events up 。
父組件經過 props 向下傳遞數據給子組件,子組件經過 events 給父組件發送消息。看看它們是怎麼工做的。

prop

使用prop傳遞數據

  • 組件實例的做用域是孤立的。這意味着不能而且不該該在子組件的模板內直接引用父組件的數據。

  • 使用 props 把數據傳給子組件。

  • prop 是父組件用來傳遞數據的一個自定義屬性

  • 子組件須要顯式地用 props 選項聲明 「prop」

<div id="example-2">
    <!--向這個組件傳入一個字符串-->
    <child message="hello!"></child>
</div>
Vue.component('child', {
        // 聲明 props,用數組形式的對象
        props: ['message'],
        // 就像 data 同樣,prop 能夠用在模板內
        // 一樣也能夠在 vm 實例中像 「this.message」 這樣使用
        template: '<span>{{ message }}</span>'
    });
    new Vue({
        el: '#example-2'
    })

動態prop

用 v-bind 動態綁定 props 的值到父組件的數據中。每當父組件的數據變化時,該變化也會傳導給子組件

<div id="example-2">
<!--使用v-modal實現雙向綁定-->
    <input v-model="parentMsg">
    <br>
    <!--須要注意這裏使用短橫線的變量,由於在html下是使用短橫線變量的,可是在vue下使用駝峯變量-->
    <!--將父組件的parentMsg和子組件的my-message進行綁定-->
    <child v-bind:my-message="parentMsg"></child>
</div>
Vue.component('child', {
        // 聲明 props
        props: ['my-message'], 
        template: '<span>{{ myMessage }}</span>' //若是寫my-message會報錯,須要轉換爲駝峯寫法
    });
    new Vue({
        el: '#example-2',
        data: {
            parentMsg: ''
        }
    })

短橫線和駝峯寫法

HTML 特性不區分大小寫。當使用非字符串模版時,prop的名字形式會從 camelCase 轉爲 kebab-case(短橫線隔開)

  • 在javascript裏面使用駝峯寫法,可是在html裏面須要轉成短橫線寫法

  • 反之亦然,vue會自動處理來自html的短橫線寫法轉爲駝峯寫法

字面量語法和動態語法

<!-- 默認只傳遞了一個字符串"1" -->
<comp some-prop="1"></comp>

<!-- 用v-bind實現傳遞實際的數字 -->
<comp v-bind:some-prop="1"></comp>

單向數據流

  • prop 是單向綁定的

  • 當父組件的屬性變化時,將傳導給子組件,可是不會反過來。這是爲了防止子組件無心修改了父組件的狀態——這會讓應用的數據流難以理解。

  • 每次父組件更新時,子組件的全部 prop 都會更新爲最新值。這意味着你不該該在子組件內部改變 prop 。若是你這麼作了,Vue 會在控制檯給出警告。

一般有兩種改變 prop 的狀況:

  1. prop 做爲初始值傳入,子組件以後只是將它的初始值做爲本地數據的初始值使用

定義一個局部 data 屬性,並將 prop 的初始值做爲局部數據的初始值。

<div id="example-2">
<!--這裏用短橫線寫法-->
    <child initial-counter="10"></child>
</div>
Vue.component('child', {
        props: ['initialCounter'],//這裏用駝峯寫法
        data: function () { //轉爲一個局部變量,寫一個data對象給組件使用
            return {counter: this.initialCounter}
        },
        template: '<span>{{ counter }}</span>'
    });
    new Vue({
        el: '#example-2'
    })
  1. prop 做爲須要被轉變的原始值傳入。

定義一個 computed 屬性,此屬性從 prop 的值計算得出。

//例子沒有寫完,可是根據第一個例子能夠知道利用computed的手法原理其實跟寫一個data差很少
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

注意在 JavaScript 中對象和數組是引用類型,指向同一個內存空間,若是 prop 是一個對象或數組,在子組件內部改變它會影響父組件的狀態。

prop驗證

組件能夠爲 props 指定驗證要求,當組件給其餘人使用時這頗有用。

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
      }
    }
  }
})

自定義事件

每一個 Vue 實例都實現了事件接口(Events interface)

  • 使用 $on(eventName) 監聽事件

  • 使用 $emit(eventName) 觸發事件

  • 父組件能夠在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件。

<div id="counter-event-example">
    <p>{{ total }}</p>
    <!--監聽子組件的事件觸發,監聽increment1事件,處理程序爲incrementTotal事件-->
    <button-counter v-on:increment1="incrementTotal"></button-counter>
    <!--關鍵在於這裏v-on綁定的是一個子組件的事件,而且賦值了一個父組件的方法給他,那麼子組件裏面就可使用這個方法-->
    <button-counter v-on:increment1="incrementTotal"></button-counter>
</div>
Vue.component('button-counter', {
        //監聽click事件,處理程序爲increment(子組件定義的方法)
        template: '<button v-on:click="increment">{{ counter }}</button>',
        //每個counter都是獨立的對象屬性
        data: function () {
            return {
                counter: 0
            }
        },
        //子組件的方法
        methods: {
            increment: function () {
                this.counter += 1;
                //在子組件裏面直接觸發以前監聽的increment1事件來執行父組件的方法
                this.$emit('increment1');
            }
        },
    })
    new Vue({
        el: '#counter-event-example',
        data: {
            total: 0
        },
        //父組件的方法
        methods: {
            incrementTotal: function () {
                this.total += 1
            }
        }
    })

1.組件之間由於做用域不一樣的關係,因此相互獨立,因此子組件想要使用父組件的方法的話須要作一個新的監聽映射

給組件綁定原生事件

<!--代替.on,這麼就可以綁定原生js的事件了-->
<my-component v-on:click.native="doTheThing"></my-component>

使用自定義事件的表單輸入組件

自定義事件也能夠用來建立自定義的表單輸入組件,使用 v-model 來進行數據雙向綁定。
因此要讓組件的 v-model 生效,它必須:

  • 接受一個 value 屬性

  • 在有新的 value 時觸發 input 事件

<!--直接使用v-model,v-modal默認處理input事件-->
<input v-model="something">

<!--v-modal是語法糖,翻譯過來原理是這樣:-->
<!--綁定一個value,而後監聽input事件,經過獲取input的輸入來不斷改變綁定的value的值,知足了v-modal的觸發條件就能夠實現v-modal了-->
<input v-bind:value="something" v-on:input="something = $event.target.value">

一個很是簡單的貨幣輸入:

<!--綁定一個v-model爲price,實際上是綁定了一個value-->
<currency-input v-model="price"></currency-input>
Vue.component('currency-input', {
  template: '\
    <span>\
      $\
      <input\
        ref="input"\ //註冊爲input,是DOM的節點元素
        v-bind:value="value"\ //v-model的value(也是prop)
        v-on:input="updateValue($event.target.value)"\ //封裝更新value的函數
      >\
    </span>\
  ',
  props: ['value'], //父組件將綁定的value傳給子組件
  methods: {
    // 不是直接更新值,而是使用此方法來對輸入值進行格式化和位數限制
    updateValue: function (value) {
      var formattedValue = value //對值進行處理
        // 刪除兩側的空格符
        .trim()
        // 保留 2 小數位和2位數
        .slice(0, value.indexOf('.') + 3)
      // 若是值不統一,手動覆蓋以保持一致,爲了保持輸入框顯示內容跟格式化內容一致
      if (formattedValue !== value) {
      //由於註冊是一個input元素,因此this.$refs 就是input元素
        this.$refs.input.value = formattedValue
      }
      //手動觸發input事件,將格式化後的值傳過去,這是最終顯示輸入框的輸出
      this.$emit('input', Number(formattedValue))
    }
  }
})
//實例化vue實例的
new Vue({
        el: '#aa', //要綁定一個vue實例,例如包裹一個id爲aa的div
        data:{
            price:'' //v-model要有數據源
        }
    })

ref 被用來給元素或子組件註冊引用信息。引用信息會根據父組件的 $refs 對象進行註冊。若是在普通的DOM元素上使用,引用信息就是元素; 若是用在子組件上,引用信息就是組件實例 ref

這是一個比較完整的例子:

<div id="app">
<!--有3個組件,分別不一樣的v-model-->
  <currency-input 
    label="Price" 
    v-model="price"
  ></currency-input>
  <currency-input 
    label="Shipping" 
    v-model="shipping"
  ></currency-input>
  <currency-input 
    label="Handling" 
    v-model="handling"
  ></currency-input>
  <currency-input 
    label="Discount" 
    v-model="discount"
  ></currency-input>
  
  <p>Total: ${{ total }}</p>
</div>
Vue.component('currency-input', {
  template: '\
    <div>\
      <label v-if="label">{{ label }}</label>\
      $\
      <input\
        ref="input"\  // 這些沒什麼特別,引用註冊爲input DOM元素
        v-bind:value="value"\  
        v-on:input="updateValue($event.target.value)"\
        v-on:focus="selectAll"\  //這裏多了focus事件監聽,焦點在的時候全選,也只是多了處理而已,對總體邏輯理解沒啥影響
        v-on:blur="formatValue"\ //這裏多了blur事件監聽,焦點離開的時候格式化
      >\
    </div>\
  ',
  props: {  //多個prop傳遞,由於prop是對象,只要是對象格式就行
    value: {
      type: Number,
      default: 0
    },
    label: {
      type: String,
      default: ''
    }
  },
  mounted: function () { //這是vue的過渡狀態,暫時忽略不影響理解
    this.formatValue()
  },
  methods: {
    updateValue: function (value) {
      var result = currencyValidator.parse(value, this.value)
      if (result.warning) {
      // 這裏也使用了$refs獲取引用註冊信息
        this.$refs.input.value = result.value
      }
      this.$emit('input', result.value)
    },
    formatValue: function () {
      this.$refs.input.value = currencyValidator.format(this.value) //這裏注意下,這個this是prop傳遞過來的,也至關於這個組件做用域
    },
    selectAll: function (event) { //event能夠獲取原生的js事件
      // Workaround for Safari bug
      // http://stackoverflow.com/questions/1269722/selecting-text-on-focus-using-jquery-not-working-in-safari-and-chrome
      setTimeout(function () {
          event.target.select()
      }, 0)
    }
  }
})

new Vue({
  el: '#app',
  data: {
    price: 0,
    shipping: 0,
    handling: 0,
    discount: 0
  },
  computed: {
    total: function () {
      return ((
        this.price * 100 + 
        this.shipping * 100 + 
        this.handling * 100 - 
        this.discount * 100
      ) / 100).toFixed(2)
    }
  }
})

非父子組件通訊

在簡單的場景下,使用一個空的 Vue 實例做爲中央事件總線:

var bus = new Vue()

// 觸發組件 A 中的事件
bus.$emit('id-selected', 1)

/*
經過on來監聽子組件的事件來實現傳遞
*/

// 在組件 B 建立的鉤子中監聽事件
bus.$on('id-selected', function (id) {
  // ...
})

使用Slot分發內容

爲了讓組件能夠組合,咱們須要一種方式來混合父組件的內容與子組件本身的模板。這個過程被稱爲 內容分發 (或 「transclusion」 若是你熟悉 Angular)

編譯做用域

組件做用域簡單地說是:父組件模板的內容在父組件做用域內編譯;子組件模板的內容在子組件做用域內編譯。
假定 someChildProperty 是子組件的屬性,上例不會如預期那樣工做。父組件模板不該該知道子組件的狀態。

<!-- 無效 -->
<child-component v-show="someChildProperty"></child-component>

若是要綁定子組件內的指令到一個組件的根節點,應當在它的模板內這麼作:

Vue.component('child-component', {
  // 有效,由於是在正確的做用域內
  template: '<div v-show="someChildProperty">Child</div>',
  data: function () {
    return { //由於這個屬性在當前組件內編譯(建立了)
      someChildProperty: true
    }
  }
})

相似地,分發內容是在父組件做用域內編譯。

單個Slot

  • 除非子組件模板包含至少一個 <slot> 插口,不然父組件的內容將會被丟棄。

  • 當子組件模板只有一個沒有屬性的 slot 時,父組件整個內容片斷將插入到 slot 所在的 DOM 位置,並替換掉 slot 標籤自己。

  • 備用內容在子組件的做用域內編譯,而且只有在宿主元素爲空,且沒有要插入的內容時才顯示備用內容。

<!--父組件模版:-->
<div id="aa">
    <h1>我是父組件的標題</h1>
    <!--子組件的做用域內編譯,宿主元素爲空,且沒有要插入的內容-->
    <my-component></my-component>
    <my-component>
        <p>這是一些初始內容</p>
        <p>這是更多的初始內容</p>
    </my-component>
</div>
Vue.component('my-component', { 
    //my-component 組件有下面模板
        template: '\
            <div>\
                <h2>我是子組件的標題</h2> \
                <slot> \  //有slot插口,因此沒有被父組件丟棄
                只有在沒有要分發的內容時纔會顯示。\
                </slot> \
            </div> \
        '
    })
    new Vue({
        el: '#aa',
    })

渲染結果:

<div id="aa"><h1>我是父組件的標題</h1>
    <div>
        <h2>我是子組件的標題</h2>
        <!--這裏是直接插入,沒有使用DOM元素-->
        只有在沒有要分發的內容時纔會顯示。
    </div>
    <div>
        <h2>我是子組件的標題</h2>
        <p>這是一些初始內容</p>
        <p>這是更多的初始內容</p>
    </div>
</div>

有名字的Slot

  • <slot> 元素能夠用一個特殊的屬性 name 來配置如何分發內容。多個 slot 能夠有不一樣的名字。具名 slot 將匹配內容片斷中有對應 slot 特性的元素。

  • 仍然能夠有一個匿名 slot ,它是默認 slot ,做爲找不到匹配的內容片斷的備用插槽。若是沒有默認的 slot ,這些找不到匹配的內容片斷將被拋棄。

<div id="aa">
    <app-layout>
        <!--這是header-->
        <h1 slot="header">這裏多是一個頁面標題</h1>
        <p>主要內容的一個段落。</p>
        <p>另外一個主要段落。</p>
        <!--這是footer-->
        <p slot="footer">這裏有一些聯繫信息</p>
    </app-layout>
</div>
Vue.component('app-layout', {
        template: '\
            <div class="container"> \
                <header> \  //找到名字叫header的slot以後替換內容,這裏替換的是整個DOM
                    <slot name="header"></slot> \
                </header> \
                <main> \ //由於slot沒有屬性,會將內容插入到slot的所在的DOM位置
                    <slot></slot> \
                </main> \
                <footer>\  //跟header相似
                    <slot name="footer"></slot> \
                </footer> \
            </div> \
        '
    });
    new Vue({
        el: '#aa',
    })

渲染結果爲:

<div class="container">
  <header>
    <h1>這裏多是一個頁面標題</h1>
  </header>
  <main>
    <p>主要內容的一個段落。</p>
    <p>另外一個主要段落。</p>
  </main>
  <footer>
    <p>這裏有一些聯繫信息</p>
  </footer>
</div>

做用域插槽(vue2.1)

  • 做用域插槽是一種特殊類型的插槽,用做使用一個(可以傳遞數據到)可重用模板替換已渲染元素。

  • 在子組件中,只需將數據傳遞到插槽,就像你將 prop 傳遞給組件同樣

  • 在父級中,具備特殊屬性 scope 的 <template> 元素,表示它是做用域插槽的模板。scope 的值對應一個臨時變量名,此變量接收從子組件中傳遞的 prop 對象

<div id="parent" class="parent">
    <child>
    <!--接收從子組件中傳遞的prop對象(這個就是做用域插槽)-->
        <template scope="props">
            <span>hello from parent</span>
            <!--使用這個prop對象-->
            <span>{{ props.text }}</span>
        </template>
    </child>
</div>
Vue.component('child', {
        props: ['props'], //這個寫不寫均可以,做用域插槽固定會接收prop對象,並且這個prop對象是確定存在的
        template: '\
            <div class="child"> \
            <slot text="hello from child"></slot> \ //在子組件裏直接將數據傳遞給slot
            </div> \
        '
    });
    new Vue({
        el: '#parent',
    })

渲染結果:

<div class="parent">
  <div class="child">
    <span>hello from parent</span>
    <!--子組件的東西出如今這裏了-->
    <span>hello from child</span>
  </div>
</div>

另一個例子,做用域插槽更具表明性的用例是列表組件,容許組件自定義應該如何渲染列表每一項

<div id="parent">
<!--綁定一個組件的prop ,位置1-->
    <my-awesome-list :items="items">
        <!-- 做用域插槽也能夠在這裏命名 -->
        <!--這裏props只表明肯定接受prop對象的東西,不關注prop對象裏面有什麼,位置2-->
        <template slot="item" scope="props">
            <li class="my-fancy-item">{{ props.text }}</li>
        </template>
    </my-awesome-list>
</div>
Vue.component('my-awesome-list', {
        props:['items'], //須要聲明prop爲items,須要是爲下面的循環遍歷的items的數據源作設定,位置3
        template: '\
            <ul> \
                <slot name="item" v-for="item in items" :text="item.text"> \ //在slot中,循環遍歷輸出items的text,位置4
                </slot> \
            </ul> \
        '
    });
    new Vue({
        el: '#parent',
        data : {
            items:[ //初始化items數據
                {text:"aa"},
                {text:"bb"}
            ]
        }
    })
  1. 位置1,實現了一個組件的prop綁定,prop須要在組件裏面聲明,這裏綁定的是items,這是要將父組件的items傳遞到子組件,因此在位置3裏面須要聲明,在vue實例要初始化

  2. 位置2,這裏scope的props是表明做用域插槽接收來自prop對象的數據,props.text是表明每個li要輸出的是prop對象的text屬性

  3. 位置3,在組件裏聲明props,爲了接收父組件綁定的items屬性,而後將其給位置4的循環使用

  4. 位置4,這裏綁定了text屬性,就是前呼位置2裏面輸出的prop對象的text屬性

動態組件

多個組件可使用同一個掛載點,而後動態地在它們之間切換。使用保留的 <component> 元素,動態地綁定到它的 is 特性

var vm = new Vue({
  el: '#example',
  data: {
    currentView: 'home' //默認值
  },
  components: { //根據不一樣的值進行不一樣的組件切換,這裏用components寫法
    home: { /* ... */ }, 
    posts: { /* ... */ },
    archive: { /* ... */ }
  }
})
<!--這個is是一個字符串,根據返回值來給組件進行v-bind-->
<component v-bind:is="currentView">
  <!-- 組件在 vm.currentview 變化時改變! -->
</component>

keep-alive

若是把切換出去的組件保留在內存中,能夠保留它的狀態或避免從新渲染。爲此能夠添加一個 keep-alive 指令參數

<keep-alive>
  <component :is="currentView">
    <!-- 非活動組件將被緩存! -->
  </component>
</keep-alive>

雜項

編寫可複用組件

在編寫組件時,記住是否要複用組件有好處。一次性組件跟其它組件緊密耦合不要緊,可是可複用組件應當定義一個清晰的公開接口。
Vue 組件的 API 來自三部分 - props, events 和 slots :

  • Props 容許外部環境傳遞數據給組件

  • Events 容許組件觸發外部環境的反作用

  • Slots 容許外部環境將額外的內容組合在組件中。

<!--v-bind,縮寫:,綁定prop-->
<!--v-on,縮寫@,監聽事件-->
<!--slot插槽-->
<my-component
  :foo="baz"  
  :bar="qux"
  @event-a="doThis"
  @event-b="doThat"
>
  <img slot="icon" src="...">
  <p slot="main-text">Hello!</p>
</my-component>

子組件索引

儘管有 props 和 events ,可是有時仍然須要在 JavaScript 中直接訪問子組件。爲此可使用 ref 爲子組件指定一個索引 ID 。

<div id="parent">
  <user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// 訪問子組件
var child = parent.$refs.profile
  1. 當 ref 和 v-for 一塊兒使用時, ref 是一個數組或對象,包含相應的子組件。

  2. $refs 只在組件渲染完成後才填充,而且它是非響應式的。它僅僅做爲一個直接訪問子組件的應急方案——應當避免在模版或計算屬性中使用 $refs 。

  3. ref 被用來給元素或子組件註冊引用信息。引用信息會根據父組件的 $refs 對象進行註冊。若是在普通的DOM元素上使用,引用信息就是元素; 若是用在子組件上,引用信息就是組件實例 ref

組件命名約定

  • 當註冊組件(或者 props)時,可使用 kebab-case ,camelCase ,或 TitleCase 。Vue 不關心這個。

  • 在 HTML 模版中,請使用 kebab-case 形式:

// 在組件定義中
components: {
  // 使用 kebab-case 形式註冊--橫線寫法
  'kebab-cased-component': { /* ... */ },
  // register using camelCase --駝峯寫法
  'camelCasedComponent': { /* ... */ },
  // register using TitleCase --標題寫法
  'TitleCasedComponent': { /* ... */ }
}
<!-- 在HTML模版中始終使用 kebab-case--橫線寫法 -->
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<title-cased-component></title-cased-component>

遞歸組件

  • 組件在它的模板內能夠遞歸地調用本身,不過,只有當它有 name 選項時才能夠

  • 當你利用Vue.component全局註冊了一個組件, 全局的ID做爲組件的 name 選項,被自動設置.

//組件能夠用name來寫名字
name: 'unique-name-of-my-component'
//也能夠在建立的時候默認添加名字
Vue.component('unique-name-of-my-component', {
  // ...
})
//若是同時使用的話,遞歸的時候就會不斷遞歸本身,致使溢出
name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'

使用-v-once-的低級靜態組件-Cheap-Static-Component

儘管在 Vue 中渲染 HTML 很快,不過當組件中包含大量靜態內容時,能夠考慮使用 v-once 將渲染結果緩存起來,就像這樣:

Vue.component('terms-of-service', {
  template: '\
    <div v-once>\
      <h1>Terms of Service</h1>\
      ... a lot of static content ...\
    </div>\
  '
})

v-once只渲染元素和組件一次。隨後的從新渲染,元素/組件及其全部的子節點將被視爲靜態內容並跳過。這能夠用於優化更新性能。

相關文章
相關標籤/搜索