Vue/組件
創(chuàng)建組件
單獨(dú)聲明一個(gè)Vue.component,使用只需要在Vue實(shí)例下使用定義的組件名
在組件中data不能是一個(gè)對(duì)象谷醉,而必須是一個(gè)函數(shù)辆亏,這個(gè)函數(shù)返回一個(gè)對(duì)象
全局組件
<div id='#app'>
<my-component></my-component>
</div>
Vue.component('my-component',{
data(){
return {
name: 'sss'
}
},
template: `<div>我的第一個(gè)組件 - {{name}}}</div>`
})
//my-component 聲明的組件名
//template 組件的模板
局部組件
放在實(shí)例的對(duì)象components下杂瘸,使用只能在實(shí)例el下使用
let vm = new Vue({
el: '#app2',
components: {
"child-component": {
template: `<div>局部組件 - {{name}}}</div>`
}
}
})
組件通信
props down, events up,
父組件傳遞給子組件數(shù)據(jù),通過屬性傳遞翔曲,子組件傳遞給父組件數(shù)據(jù),通過事件傳遞
<div id="app">
<my-component food="西瓜"></my-component>
</div>
Vue.component('my-component',{
props:['food'], //一個(gè)子組件需要通過props中的獲得父組件傳遞的屬性信息
template: `<div><p>{{food}}</p></div>`
})
//獲取實(shí)例下數(shù)據(jù)
<div id="app">
<my-component v-bild:food="foods"></my-component>
</div>
Vue.component('my-component',{
props:["food"],
template:`
<div>
<p>{{food}}</p>
</div>
`,
})
new Vue({
el: '#app',
data: {
foods: "蘋果"
}
})
//蘋果
子組件可以接收來自父組件的數(shù)據(jù)劈愚,為了保證數(shù)據(jù)的正確性瞳遍,完整性,安全性菌羽,vue會(huì)禁止直接修改父組件的數(shù)據(jù)掠械,如果非要更改這個(gè)數(shù)據(jù),一定要通過事件的方式通知父組件
比如上面的我們?cè)谀0嫦露x一個(gè)按鈕注祖,當(dāng)點(diǎn)擊的時(shí)候
<div id="app3">
<my-component :data="foods" @edit-data="callback"></my-component>
</div>
Vue.component('my-component',{
props:["data"],
template:`
<div>
<p>{{data}}</p>
<button @click="click">按鈕</button>
</div>
`,
methods: {
click(){
this.$emit('edit-data',"我要吃蘋果")
//點(diǎn)擊后赦邻,觸發(fā)事件
}
}
})
let vm = new Vue({
el: '#app3',
data: {
foods:
"蘋果"
},
methods: {
callback(v){
//這邊就監(jiān)聽到后,相當(dāng)于子組件要請(qǐng)求修改數(shù)據(jù)晚顷,通過事件傳遞給父組件家凯,然后告訴實(shí)例,實(shí)例自己來修改數(shù)據(jù)署鸡,最后影響到數(shù)據(jù)的更改
this.foods = v;
}
}
})
console.log(vm.foods)
props驗(yàn)證
我們可以為組件的 props 指定驗(yàn)證規(guī)格案糙。如果傳入的數(shù)據(jù)不符合規(guī)格,Vue 會(huì)發(fā)出警告靴庆。當(dāng)組件給其他人使用時(shí),要指定驗(yàn)證規(guī)格时捌,需要用對(duì)象的形式,而不能用字符串?dāng)?shù)組:
//在props里通過一個(gè)對(duì)象來給props來限制條件
Vue.component('example', {
props: {
// 基礎(chǔ)類型檢測(cè) (`null` 意思是任何類型都可以)
propA: Number,
// 多種類型
propB: [String, Number],
// 必傳且是字符串
propC: {
type: String,
required: true
},
// 數(shù)字炉抒,有默認(rèn)值
propD: {
type: Number,
default: 100
},
// 數(shù)組/對(duì)象的默認(rèn)值應(yīng)當(dāng)由一個(gè)工廠函數(shù)返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定義驗(yàn)證函數(shù)
propF: {
validator: function (value) {
return value > 10
}
}
}
})
非prop屬性
如果一個(gè)組件標(biāo)簽上的屬性沒有在props中定義奢讨,那么這個(gè)屬性將會(huì)被自動(dòng)添加到組件的根元素上,對(duì)于style和class進(jìn)行合并(把組件標(biāo)簽上的style或class與區(qū)間根元素上的style或class進(jìn)行合并)焰薄,但是其他的屬性將是覆蓋操作
//div background: red; border: 1px solid #000;<div id="app">
<m-area style="border: 1px solid #000" :r="100"></m-area>
</div>
Vue.component("mArea",{
props: {
r: {
type: Number,
default: 10
}
},
template: `
<div style="background: red">
<p>面積: {{Math.PI * r * r}}</p>
</div>
`
});
let vm = new Vue({
el: "#app"
})
//div background: red; border: 1px solid #000;
style標(biāo)簽并沒有在props中定義拿诸,那就會(huì)自動(dòng)添加在組件模版根元素(div)上,style這個(gè)屬性也不是被覆蓋塞茅,而是合并在一起了
插槽slot
在組件模板中通過 <slot></slot> 來定義一個(gè)插槽亩码,在解析的時(shí)候,會(huì)把對(duì)應(yīng)的內(nèi)容放到slot位置
一個(gè)組件中可以使用多個(gè)slot野瘦,如果有多個(gè)的話描沟,需要給slot設(shè)置name屬性飒泻,沒有name的就是默認(rèn)插槽
<div id="app">
<h1>自身h1標(biāo)題</h1>
<my-component>
<p>自身的文字</p>
<p>自身的文字1111</p>
</my-component>
</div>
Vue.component('my-component',{
template:`
<div>
<p>模版文字</p>
<span>moban</span>
<slot>slot的文字</slot>
</div>
`
});
//如果外面使用模版,有模版以為的內(nèi)容吏廉,看里面是否有插槽泞遗,有就把外面自身的內(nèi)容放到插槽位置里,沒有內(nèi)容就是用插槽的內(nèi)容
具名
<slot>
元素可以用一個(gè)特殊的屬性name
來配置如何分發(fā)內(nèi)容席覆。多個(gè) slot 可以有不同的名字史辙。具名 slot 將匹配內(nèi)容片段中有對(duì)應(yīng)slot
特性的元素。仍然可以有一個(gè)匿名 slot娜睛,它是默認(rèn) slot髓霞,作為找不到匹配的內(nèi)容片段的備用插槽。如果沒有默認(rèn)的 slot畦戒,這些找不到匹配的內(nèi)容片段將被拋棄方库。
<div id="app">
<my-component>
<p>沒有固定要放的位置</p>
<h1 slot="head">我要放的自己的頭部?jī)?nèi)容</h1>
<p>沒有固定要放的位置111</p>
<p slot="foot">我要放的自己的底部?jī)?nèi)容</p>
<p slot="head">我要放的自己的頭部?jī)?nèi)容111</p>
</my-component>
</div>
Vue.component('my-component',{
template:`
<div>
<header>
<slot name="head"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="foot"></slot>
</footer>
</div>
`
});
//展示
<div>
<header>
<h1>我要放的自己的頭部?jī)?nèi)容</h1>
<p>我要放的自己的頭部?jī)?nèi)容111</p>
</header>
<main>
<p>沒有固定要放的位置</p>
<p>沒有固定要放的位置111</p>
</main>
<footer>
<p>我要放的自己的底部?jī)?nèi)容</p>
</footer>
</div>
作用域插槽
作用域插槽是一種特殊類型的插槽,用作使用一個(gè) (能夠傳遞數(shù)據(jù)到) 可重用模板替換已渲染元素障斋。
在父級(jí)中纵潦,具有特殊屬性
scope
的<template>
元素必須存在,表示它是作用域插槽的模板垃环。scope
的值對(duì)應(yīng)一個(gè)臨時(shí)變量名邀层,此變量接收從子組件中傳遞的 props 對(duì)象:
<div id="app">
<div class="parent">
<my-component>
<template scope="props">
<span>{{props.text}}</span>
</template>
</my-component>
</div>
</div>
Vue.component('my-component',{
template:`
<div class="child">
<slot a=10></slot>
<slot b=10></slot>
<slot age="18"></slot>
<slot text="hello from child"></slot>
</div>
`
});
//相當(dāng)于循環(huán)了模版里的內(nèi)容,你有幾個(gè)slot就循環(huán)幾次遂庄,那就是4個(gè)span標(biāo)簽寥院,內(nèi)容就用{{props.需要的屬性}},沒有就為空標(biāo)簽
//展現(xiàn)
<div class="parent">
<div class="child">
<span></span>
<span></span>
<span></span>
<span>hello from child</span>
</div>
</div>
具名作用域
<div id="app">
<my-component>
<template scope="props" slot="list"> //
<li>{{props.text}}</li>
</template>
</my-component>
</div>
Vue.component('my-component',{
template:`
<ul>
<slot name="list" v-for="item in items" :text="item"></slot>
</ul>
`
new Vue({
el: '#app',
data: {
items: ["a","b","c","d","e"]
}
})
//顯示
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
</ul>