vue中的組件是自定的標簽,可以擴展的原生html元素,封裝可復用的代碼
note:
1、在標簽命中不要使用大寫,標簽名字必須用短橫線隔開
2、模板中只能有一個根元素,不能使用並列標簽。
定義組件
- 全局定義,在所有實例中都可以使用這個組件
<template id='hello'>
<div>
<div>hello</div>
<div>world</div>
</div>
</template>
let data={msg:'world'}
Vue.component('myComponent',{
template:'#hello',//通過模板的ID來引用這個組件
return {msg:'world'};//此時不能return data;這樣會導致如果有多個實例運用這個組件會導致,三者共享同一個data,改變其中一個,會導致其他的都改變。對象變量會導致共享數據。
})
此時就可以在實例中使用my-component標簽。
- 局部定義
let vm=new Vue({
el:'#app',
data:{msg:'hello'},
components:{
'my-component'(myComponent):{
template:'<h1>{{msg}}</h1>',
data(){
return {msg:'world'};
}
}
}
})
1、子組件不能直接使用父組件的數據
2、子組件可以聲明自己的數據
組件之間的數據傳遞
1、每個組件是沒關系的,都應該產生自己的數據。在組件中data使用的方法和默認的vm一樣。只是data不再是對象而是函數。組件可以無限嵌套。
2、聲明組件的名字,不能為已經存在的標簽
3、組件的嵌套,子組件必須寫在父組建的模板中才能使用
- 1、父級向子級傳遞數據(傳遞的屬性值)
1、如果直接寫a='b'格式傳遞的是字符串,動態數據獲取用的是v-bind,一般無論是動態還是靜態,我們都會采用:。
2、:msg='meat',meat是變量;msg='meat',meat是字符串,:msg="'meat'",meat是字符串
3、子級不能直接改變父級的數據,如果要修改可以將父級的數據修改后賦值給子級的變量,可以使用data或者computed
<div id=app>
<child :data='aaa' :data1="bbb"></child>
//此處,在子組件中左邊的是子組件的接收,用props接收,如果是放在數組中每一項就是一個字符串,右邊是從父級傳遞的數據。
</div>
<script>
let vm=new Vue({
el:'#app',
data:{
aaa:'xxxxx',
bbb:'yyyyy'
}
components:{//
child:{
props:['data','data1'],
template:'<div>{{msg}}</div>',
data(){
return {msg:this.data+'zxvv'}
},
computed:{
msg:{
get(){
return this.data+'zxvv'
}
}
}
}
}
})
</script>
props
中的validate
:
1、props:['xx','yy','zz'];
2、props:{
aa:{
type:[Number,String],//選擇值得類型符不符合要求
default:'acac',//默認值
validator(val){//校驗函數
return val>200//返回false,校驗失敗。
}
required:true,//代表屬性必須填
}
}
- 2、子級向父級傳遞數據(借助於事件)
1、子級$emit后會觸發自己身上的某一個自定的方法,這個方法對應的函數在父級的身上。
<div id="app1">
{{datas}}
<child @get-data="getData"></child>//自定義方法寫在自己身上,右邊的是父級對應方法的函數
</div>
let vm1 = new Vue({
el: '#app1',
data: {
datas: '',//用來接收自己傳遞的空數據
},
methods: {
getData(msg){//接受的參數就是從子級傳遞過來的數據
this.datas = msg;
}
},
components: {
child: {
template: `<div><button @click="say">{{msg}}</button></div>`,//綁定觸發事件
methods: {
say(){//觸發事件,以及自定義方法
this.$emit('get-data', this.msg);//這里的this指的是當前子組件
}
},
data(){
return {
msg: 'xxx'
}
}
}
}
})
- 3、兄弟之間傳遞數據
1、兄弟之間傳遞數據需要借助於事件車,通過事件車的方式傳遞數據eventBus
2、創建一個Vue的實例,讓各個兄弟共用同一個事件機制。
3、傳遞數據方,通過一個事件觸發bus.$emit(方法名,傳遞的數據)。
4、接收數據方,通過mounted(){}觸發bus.$on(方法名,function(接收數據的參數){用該組件的數據接收傳遞過來的數據}),此時函數中的this已經發生了改變,可以使用箭頭函數。
slot
具名slot,通過組件傳入模板,每個模板指定是slot名字,這個名字和定制模板匹配到,會替換定制的模板。
slot是vue中提供的一個標簽,用來做模板定制的。屬性,事件,定制模板組成了組件的API。
**使用slot分發內容**
為了讓組件可以組合,我們需要一種防暑混合父組件的內容與子組件自己的模板。這個過程被稱作內容分發(transclusion),vue.js實現了一個內容分發API,使用特殊的<slot>元素作為原始內容的插槽。
**編譯作用域**
父組件模板的內容在父組件作用域內編譯;子組件模板的內容在子組件作用域內編譯。
**單個slot**
除非子組件模板包含至少一個 <slot> 插口,否則父組件的內容將會被丟棄。當子組件模板只有一個沒有屬性的 slot 時,父組件整個內容片段將插入到 slot 所在的 DOM 位置,並替換掉 slot 標簽本身。
最初在 <slot> 標簽中的任何內容都被視為備用內容。備用內容在子組件的作用域內編譯,並且只有在宿主元素為空,且沒有要插入的內容時才顯示備用內容。
**具名slot**
<slot>元素可以用有個特殊的屬性name來配置如何分發內容。多個slot可以有不同的名字。具名slot將匹配內容片段中對應slot特性的元素。但任然可以有一個匿名slot,它是默認的slot,作為找不到匹配的內容片段的備用插槽。如果沒有默認的slot,這些找不到匹配的內容將被拋棄。
遞歸組件
組件在它的模板內可以遞歸地調用自己。recursive 遞歸組件,自己調用自己,必須有中斷條件。
默認情況下,遞歸組件是不會執行的,要制定name屬性(只在局部組件中需要添加),全局逐漸不需要加name屬性。
動態組件
is可以指定當前標簽內可以指定插入什么元素,可以防止解析出錯。
radio中默認沒有綁定數據,要給value值,這個value值會映射到radio上
<keep-alive>
<component :is="rad"></component><!--緩存組件的上一次狀態,防止每次切換時都需要渲染組件-->
</keep-alive>