注冊組件
必須要有一個(gè)根元素
data 須是一個(gè)function,防止使用多個(gè)組件時(shí)驳遵,引用的是相同的數(shù)據(jù)
局部注冊的組件使用時(shí)需要在components里聲明下。
注冊局部組件
const Bar = {
data() {
return {
count: 0,
};
},
template: `<div>Bar
{{count}}
<button @click="count++"></button>
</div>`,
};
注冊全局組件和使用局部組件
Vue.component("Foo", {
//需要在components里聲明下局部組件
components: {
Bar,
},
template: `<div>foo
<Bar></Bar>
<Bar></Bar>
</div>`,
});
使用全局組件
const app = new Vue({
el: "#app",
//全局組件不需要聲明
template: `
<div>app
<Foo></Foo>
</div>
`,
data: {},
});
組件生命周期
beforeCreate() {
// 實(shí)例剛在內(nèi)存中被創(chuàng)建出來山涡,此時(shí)堤结,還沒有初始化好 data 和 methods 屬性
},
created() {
// 實(shí)例已經(jīng)在內(nèi)存中創(chuàng)建,data 和 methods 已經(jīng)創(chuàng)建鸭丛,但是還沒有開始 編譯模板霍殴,可以在這調(diào)用接口獲取數(shù)據(jù)
},
beforeMount() {
//已經(jīng)完成了模板的編譯,但是還沒有掛載到頁面中系吩,頁面里還是沒解析好的數(shù)據(jù)。
},
mounted() {
// 掛載完成 妒蔚,可以獲取dom元素了
// window.addEventListener("")
},
beforeUpdate() {
// 狀態(tài)更新之前執(zhí)行此函數(shù)穿挨, 此時(shí) data 中的狀態(tài)值是最新的月弛,但是界面上顯示的數(shù)據(jù)還是舊的,因?yàn)榇藭r(shí)還沒有開始重新渲染DOM節(jié)點(diǎn)
},
updated() {
// 更新完成
},
beforeDestroy() {
// 銷毀前
},
destroyed() {
// window.removeEventListener
// 銷毀完
},
父子組件生命周期執(zhí)行順序
father: beforeCreate
father: created
father: beforeMount
child: beforeCreate
child: created
child: beforeMount
child: mounted
father: mounted
父子組件傳值
父組件
<div id="app">
<p>father{{ counter }}</p>
<button-counter @increment="fatherIncrement" :counter="counter"></button-counter>
</div>
<script>
const app = new Vue({
el: "#app",
data: {
counter: 0
},
methods: {
fatherIncrement(value) {
this.counter += value
}
},
});
</script>
子組件
Vue.component('button-counter', {
props: ['counter'],
template: '<button @click="incrementHandler">child{{ counter }}</button>',
methods: {
incrementHandler() {
this.$emit('increment', 10)
}
},
})
.sync 修飾符:
用來簡寫子組件給父組件傳值科盛,不再需要父組件特意定一個(gè)方法接受子組件參數(shù)
<div id="app">
<div id="counter-event-example">
<p>father{{ counter }}</p>
<button-counter :counter.sync="counter"></button-counter>
</div>
</div>
<script>
Vue.component('button-counter', {
props: ['counter'],
template: '<button @click="changeCounter">child{{ counter }}</button>',
methods: {
changeCounter() {
this.$emit('update:counter', 100)
}
},
})
const app = new Vue({
el: "#app",
data: {
counter: 0
},
});
</script>
插槽
實(shí)現(xiàn)將父組件里分發(fā)內(nèi)容給子組件
<!--父組件-->
<!--引用子組件時(shí)內(nèi)標(biāo)簽內(nèi)寫內(nèi)容-->
<navigation-link url="/profile">
Your Profile
</navigation-link>
<!--子組件-->
<!--子組件里預(yù)寫了slot標(biāo)簽帽衙,最終會渲染為父組件傳過來的“Your Profile”-->
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
給插槽命名,以使用多個(gè)插槽,沒有命名的為默認(rèn)插槽贞绵。
<!--子組件-->
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<!--父組件-->
<base-layout>
<!--v-slot:header 可以被縮寫為 #header-->
<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 v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
如果父組件想要訪問子組件的數(shù)據(jù)厉萝。可以通過bind向父組件傳遞數(shù)據(jù)榨崩。
<!--子組件-->
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
<!--父組件谴垫,接收對應(yīng)插槽default的數(shù)據(jù)并定義一個(gè)名稱。-->
<!--獲取到一個(gè)對象母蛛,里面有子組件傳過來的user翩剪,key為user-->
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
<!--解構(gòu)插槽對象-->
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
混入
出現(xiàn)命名沖突時(shí):
數(shù)據(jù)對象在內(nèi)部會進(jìn)行遞歸合并,并在發(fā)生沖突時(shí)以組件數(shù)據(jù)優(yōu)先彩郊。
同名鉤子函數(shù)將合并為一個(gè)數(shù)組前弯,因此都將被調(diào)用。另外秫逝,混入對象的鉤子將在組件自身鉤子之前調(diào)用恕出。
值為對象的選項(xiàng),例如 methods
违帆、components
和 directives
浙巫,將被合并為同一個(gè)對象。兩個(gè)對象鍵名沖突時(shí)前方,取組件對象的鍵值對狈醉。
局部混入
// 定義局部混入
const fooMixin = {
data() {
return {
valueMixin: "foo - mixin",
};
},
};
const Foo = {
// 引入定義局部混入
mixins: [fooMixin],
data() {
return {
value: "foo - self",
};
},
mounted() {
console.log(this.value);//"foo - self"
console.log(this.valueMixin);//"foo - mixin"
},
}
全局混入
Vue.component("Foo", {
data() {
return {
myOption: "Foo - option",
};
},
template: `<div>Foo</div> `,
});
Vue.component("Bar", {
data() {
return {
myOption: "Bar - option",
};
},
template: `<div>Bar</div> `,
});
Vue.mixin({
created: function () {
console.log(this.myOption)
}
})
new Vue({
el: "#app",
myOption: 'hell11o!',
template: `<div> <Foo></Foo><Bar></Bar></div> `,
})
//控制臺輸出
Foo - option
Bar - option
動(dòng)態(tài)組件is
使用:is屬性來切換不同的子組件,is綁定的變量對應(yīng)的值為組件的名稱
<component :is="comName"></component>
keep-alive
失活的組件將會被緩存,切換組件保持頁面之前的狀態(tài),
keep-alive要求被切換到的組件都有自己的名字
include
和 exclude
prop 允許組件有條件地緩存
被換成的組件有activated和
deactivated兩個(gè)鉤子函數(shù)
<keep-alive include="a,b">
<component v-bind:is="currentTabComponent"></component>
</keep-alive>