組建的特點:
組件其實也是一個Vue實例,因此它在定義時也會接收:data、methods、生命周期函數等;
組件不會與頁面的元素綁定,否則就無法復用了,因此沒有el屬性。
但是組件渲染需要html模板,所以增加了template屬性,值就是HTML模板;
data必須是一個函數,不再是一個對象。
Vue全局組件注冊后是在任何實例下都可以使用的,注冊方式為
Vue.component('button-counter(組件名)', {
?template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
data(){
? ? return {? count: 0? ? }
? },
?})
局部組件只能在注冊過的父組件使用,是直接在Vue實例里面注冊,父組件調用時要使用
var Child = { template: '<div>A custom component!</div>' }
components{
'my-component': Child
}
注意:
局部組件定義時使用的時components,全局組件注冊時Vue.component,多一個s
局部組件在注冊的時候因為內容比較復雜,所以建議模板定義在一個全局變量里,代碼看起來容易一點(項目中一般另外定義一個.vue文件,一個.vue文件就是一個組件,當要調用某個組件時,引入子組件,然后再components里面注冊即可使用)
注意局部注冊的組件在其子組件中不可用。
組件間傳值:
父傳子:
父組件調用子組件是傳入message
?<vue2test?:message="message"></vue2test>
子組件通過??props:['message']可以獲得父組件傳過來的值,多個值可以在數組里放入多個值獲得
子傳父:
子組件不能直接將值傳給父組件,必須通過觸發父組件綁定在子組件上監聽的函數傳值
父組件:<vue2test?:message="message"?@acceptChild="acceptChild"></vue2test> 注意:若綁定的函數有參數,函數名后不要加括號
子組件:子組件會通過$emit('函數名',參數)形式觸發父組件綁定的函數,子組件中需要以某種方式觸發事件
非父子組件傳值:
vue沒有提供直接子組件對子組件的方法,如果是與父組件的父組件進行通訊可以采用鏈式傳值,先傳到父組件,然后經由父組件再傳過去。但不推薦此方法進行非父子組件間的通訊。vue官網提供了vue狀態管理來解決非父子組件間的通訊,vuex就香一個組件共用的倉庫,不同組件間可以通過vuex進行值的更改與傳遞。更多關于vuex的使用等待vuex總結更新。
插槽:
Slot 通俗的理解就是“占位”,在組件模板中占好了位置,當使用該組件標簽時候,組件標簽里面的內容就會自動填坑(替換組件模板中slot位置)
并且可以作為承載分發內容的出口
插槽內可以包含普通文本、也可以包含任何模板代碼,包括HTML、其他組件、使用數據;
規則:
父級模板里的所有內容都是在父級作用域中編譯的;子模板里的所有內容都是在子作用域中編譯的。
(默認內容)插槽
有時候我們需要給插槽設置一個具體的默認內容,當別的組件沒有給你內容的時候,那么默認的內容就會被渲染
具名插槽
有時候我們一個組件里需要多個插槽,<slot>元素有一個特殊的特性:name?,這個特性可以用來定義額外的插槽
如果一個<slot>不帶name屬性的話,那么它的name默認為default
在向具名插槽提供內容的時候,我們可以在<template>元素上使用v-slot指令,并以參數的形式提供其名稱
使用方法:
在子組件定義插槽:<slot?name="footer"></slot>
父組件中在
在向具名插槽提供內容的時候,我們可以在<template>元素上使用v-slot指令,并以參數的形式提供其名稱
< soltTestVue (子組件名)>
<template v-slot: footer >
<h1>給子組件具名插槽傳遞的內容</h1>
</template>
</ soltTestVue >
現在?<template>?元素中的所有內容都將會被傳入相應的插槽。任何沒有被包裹在帶有?v-slot?的?<template>?中的內容都會被視為默認插槽的內容。
注:v-slot只能添加在一個<template>上,(只有一種例外情況,下面會說)
作用域插槽
插槽跟模板其他地方一樣都可以訪問相同的實例屬性(也就是相同的"作用域"),而不能訪問子組件的作用域
父組件: ?v-slot:default="slotProps"拿那個插槽的值:如果有多個插槽綁定值,只有一個就取默認
??<soltTestVue??>??????
<template?v-slot:default="slotProps">????{{?slotProps.msg?}}??</template>??
<template?v-slot:footer="footerTest">???{{footerTest.footer}}??</template>
??</soltTestVue>
子組件:
<slot?:msg="msg"></slot>
<slot?name="footer"?:footer="footer"></slot>
綁定在?<slot>?元素上的特性被稱為插槽?prop。在父組件中,我們可以用?v-slot?設置一個值來定義我們提供的插槽 prop 的名字,然后直接使用就好了
解構插槽Prop
因為 作用域插槽 的內部工作原理是將你的插槽內容包括在一個傳入單個參數的函數里
這意味著v-slot的值實際上可以是任何能夠作為函數定義中的參數的 JS 表達式
所以本來是這樣寫的:
<div>
? <test v-slot="slotProps">
? ? {{slotProps.usertext.firstName}}
? </test>
</div>
還可以這樣寫:
? ?<div>? <test v-slot={usertext}>
? ? {{usertext.firstName}}
? </test>
</div>
這樣可以使模板更簡潔,尤其是在該插槽提供了多個prop的時候。它同樣開啟了prop重命名等其它可能,
例如可以將 usertext 重命名為 person:
<div>? <test v-slot={usertext:person}>
? ? {{person.firstName}}
? </test>
</div>
甚至可以定義 后備內容(默認內容),用于插槽沒有值時可以使用默認內容的情形:
<div>
? <test v-slot="{usertext={firstName:'Yang'}}">
? ? {{usertext.firstName}}
? </test>
</div>
動態插槽名(2.6.0新增)
動態指令參數也可以用在v-slot上,來定義動態的插槽名:
<base-layout>
? <template v-slot:[dynamicSlotName]>
? ? ...
? </template>
</base-layout>
具名插槽的縮寫(2.6.0新增)
跟?v-on?和?v-bind?一樣,v-slot?也有縮寫,即把參數之前的所有內容?(v-slot:)?替換為字符?#。例如?v-slot:header?可以被重寫為?#header:
原來是這樣寫的:
<div>
? <template v-slot:header>
? ? <h1>Here might be a page title</h1>
? </template>
? <p>A paragraph for the main content.</p>
? <p>And another one.</p>
? <template v-slot:footer>
? ? <p>Here some contact info</p>
? </template>
</div>?
現在可以這樣寫:
<div>
? <template #header>
? ? <h1>Here might be a page title</h1>
? </template>
? <p>A paragraph for the main content.</p>
? <p>And another one.</p>
? <template #footer>
? ? <p>Here some contact info</p>
? </template>
</div>
注:該指令和其他指令一樣,只在其有參數的時候才可用
如果希望使用縮寫的話,必須始終以明確插槽名取而代之