9.vue2-元件註冊,prop,插槽
阿新 • • 發佈:2019-01-25
Author: vanessa
Date: 2018/06/19
1.元件命名
使用小寫,單詞中間加橫線,如:<my-input></my-input>
2.註冊
a.全域性註冊
Vue.component('my-component-name', {
// ... 選項 ...
})
b.區域性註冊,components這個屬性一定是複數
var ComponentA = { } new Vue({ el: '#app' components: { 'component-a': ComponentA, 'component-b': ComponentB } })
3.prop內容
a.html對大小寫不敏感,大寫都會轉化為小寫,所以prop中大寫會被轉化為小寫加橫線,
props一般以字串陣列對形式展示,但是可以用物件表示,指定每個變數對型別,同時可以新增一些驗證
props: ['title', 'likes', 'isPublished', 'commentIds', 'author'] props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object } Vue.component('my-component', { 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 ['success', 'warning', 'danger'].indexOf(value) !== -1 } } } })
b.傳遞對值可以是動態對也可是靜態的,傳遞的值可以是數子,字串,布林,陣列,物件
<blog-post v-bind:title="post.title"></blog-post>
c.單向資料流,父級的改變會單向流動到子級,不能在子元件中改變prop的值
c1.子元件中使用父級的prop傳遞來的資料,最好在子元件的data中定義一個變數,或者定義一個計算屬性
c2.物件和陣列是通過引用傳入的,子元件中改變會影響父元件的值
ps:使用動態繫結的資料,必須是前面加v-bind後面資料加打括號:my-object="{user}"
4.屬性合併和替換
絕大多少屬性會父元件中定義的屬性會替換掉子元件中的,class和style會父子間進行合併,追加到子元件的class後面
<bootstrap-date-input>的模版是這樣的
<input type="date" class="form-control">
<bootstrap-date-input type="text" class="active"></bootstrap-date-input>
子元件中type屬性會被替換成text,class將會進行合併變成 form-control active
ps:禁用特性繼承,將放棄父級中的屬性
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
可以使用$attrs在子元件中使用父元件的屬性,通過inheritAttrs:false禁止向父級繼承屬性,通過v-bind="$attrs",將父級的屬性繫結到子元件的input標籤上
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>
`
})
<base-input v-model="username" class="username-input" placeholder="Enter your username" data-ss="aaaa"></base-input>
4.具名插槽
<base-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</base-layout>
Vue.component("baseLayout",{
template:`
<div class="container">
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
`
})
ps:全域性元件定義必須在new Vue()之前,否則控制檯報錯: Unknown custom element
編譯作用域
父元件模板的所有東西都會在父級作用域內編譯;子元件模板的所有東西都會在子級作用域內編譯。
<todo-list :todos="todos">
<template slot-scope="{todo}">
{{todo}}
</template>
</todo-list>
Vue.component("todo-list",{
props:['todos'],
template:`
<ul>
<li v-for="todo in todos">
<slot :todo="todo">{{todo.name}}</slot>
</li>
</ul>
`
});
slot-scope能獲得子元件的資料,template能替換子元件slot中內容