
批改狀態(tài):合格
老師批語:
組件,從形式上看,組件就是一個自定義的 html 標(biāo)簽;組件本質(zhì)上來看是一個可復(fù)用的 Vue 實例,是構(gòu)造函數(shù) Vue 的一個子類;組件實現(xiàn)了代碼復(fù)用。從組件的層面上來理解,Vue 的掛載點就是一個組件,不過它是一個隱式聲明根組件。
創(chuàng)建一個組件需要進(jìn)行兩個步驟
child-component
的新組件(使用 Vue.component 創(chuàng)建的組件為全局組件)
<!-- 創(chuàng)建一個新組件 -->
<script>
Vue.component("child-component", {
template: `<h1>Helo World</h1>`,
data() {
return {};
},
});
</script>
其中 “child-component” 是創(chuàng)建的組件的名字(用戶自定義的 html 標(biāo)簽),后邊的對象{}
中的內(nèi)容是組件的配置項,其中 template
中的內(nèi)容是一個字符串模板,作為 Vue 實例的標(biāo)識使用。模板將會替換掛載的元素,也就是掛載點上的<child-component></child-component>
這一對自定義 html 標(biāo)簽。掛載元素的內(nèi)容都將被忽略,除非模板的內(nèi)容有分發(fā)插槽。由于組件是一個 Vue 的子類,所以它的屬性也是由一個函數(shù)data(){return{}}
返回一個對象來實現(xiàn)的。
2.掛載,將自定義的 html 標(biāo)簽放到 Vue 掛載點的子結(jié)點上
<body>
<!-- 掛載點是一個隱式聲明根組件, -->
<div class="app">
<!-- 自定義html標(biāo)簽 -->
<child-component></child-component>
</div>
<script>
// 將組件名放到掛載點的子結(jié)點中
const vm = new Vue({
el: ".app",
data() {
return {};
},
});
</script>
</body>
聲明組件的目的就是實現(xiàn)代碼復(fù)用,將這個組件可以重復(fù)的放置在已經(jīng)掛載好的根節(jié)點中
例如
<body>
<!-- 掛載點是一個隱式聲明根組件, -->
<div class="app">
<!-- 自定義html標(biāo)簽 -->
<child-component></child-component>
<child-component></child-component>
<child-component></child-component>
</div>
</body>
上述示例中,組件的創(chuàng)建是通過Vue.component
來實現(xiàn)的。這樣聲明的組件是全局組件,它在全局可見,聲明在 Vue 實例外部,全局組件可以在多個 Vue 實例中共享,不過盡可能不要去聲明一個全局組件,減少全局污染。因為通常一個項目只有一個 Vue 實例,所以盡可能不要用全局組件,而應(yīng)該使用局部組件代替。
局部組件的聲明
局部組件是屬于 Vue 實例的,使用 components 聲明。
<body>
<div class="app">
<child-hello></child-hello>
</div>
<script>
const vm = new Vue({
el: ".app",
data() {
return {};
},
// 聲明一個局部組件
components: {
childHello: {
template: `<p>Hello {{site}}</p>`,
data() {
return {
site: "php中文網(wǎng)",
};
},
},
});
</script>
</body>
<child-hello></child-hello>
,是定義的局部組件。但是在 dom 結(jié)構(gòu)中是找不到的。
父組件向子組件傳參
父組件是通過自定義屬性的方式將參數(shù)傳到子組件中的, 然后子組件中用固定屬性名稱 props 來接收父組件自定義的屬性名。
現(xiàn)在我們來聲明一個子組件,將其放到掛載點下,然后在子組件中不進(jìn)行屬性聲明,所有的屬性在父組件中聲明定義,然后試著將這些父組件中的屬性傳遞到子組件中。
<body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<!-- 父組件,父組件是通過自定義屬性的方式將參數(shù)傳到子組件中的 -->
<btn-inc :user-name="username" :parent-count="count"></btn-inc>
<p>{{count}}</p>
</div>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
username: "父組件的變量",
count: 0,
};
},
// 局部組件
components: {
btnInc: {
// 使用固定屬性名稱props來接收父組件自定義的屬性名
props: ["userName", "parentCount"],
// 組件之間的數(shù)據(jù)傳遞是單向的,不允許在子組件中更新父組件中的數(shù)據(jù)
template: `<div>
<button @click="num++">點贊:+ {{num}}</button>
<span>{{userName}}</span>
</div>`,
data() {
return {
num: this.parentCount,
};
},
},
},
});
// 子組件中的數(shù)據(jù)變化更新父組件的數(shù)據(jù),通過消息傳遞(事件)實現(xiàn)
console.log(vm.count);
</script>
</body>
父組件中的自定義屬性的值可以來自根組件的 data,不過如果使用根組件上的變量就要對自定義屬性進(jìn)行 v-bind 綁定,父組件中的自定義屬性名盡量寫成”:user-name”,而在子組件中接收的時候應(yīng)該寫成”userName”的形式。
試著直接使用父組件data
中的count
直接使用在子組件的template
,會發(fā)現(xiàn)根本就不可以進(jìn)行渲染,根本就識別不出來。只能通過父組件自定義屬性綁定到父組件上,然后再傳參才可以在子組件中拿到父組件中的數(shù)據(jù)。而且父組件中的數(shù)據(jù)拿過來之后,也就是通過props
獲取到之后,不能對其進(jìn)行修改,如果想要進(jìn)行改變值的操作,就只能在子組件的data
中重新定義一個變量接收,然后對這個變量進(jìn)行修改,如果不這樣做,Vue 就會報錯。
在子組件的template
中直接使用父組件的屬性進(jìn)行修改,會出現(xiàn)如下報錯情況。
template:
<div> <button @click="parentCount++">點贊:+ {{parentCount}}</button> <span>{{userName}}</span> </div>
,
報錯情況
而且改變之后,對于父組件中的 count 是沒有影響的。
子組件向父組件傳參
子組件中的數(shù)據(jù)變化更新父組件的數(shù)據(jù),通過消息傳遞(事件)實現(xiàn),子組件向父組件傳參是通過聲明同名事件來實現(xiàn)的。
在子組件的template
html 字符串中定義事件,必須對事件使用$emit()事件方法,$emit(父組件中要使用的方法名稱,子組件要傳給父組件的值)
。
現(xiàn)在來列舉一個子組件向父組件傳參的例子
<body>
<div id="app">
<btn-inc
:user-name="username"
:parent-count="count"
@click-count="handle"
></btn-inc>
</div>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
username: "父組件的變量",
count: 0,
};
},
// 局部組件
components: {
btnInc: {
// 使用固定屬性名稱props來接收父組件自定義的屬性名
props: ["userName", "parentCount"],
// 必須使用$emit()事件方法
// $emit(父組件中要使用的方法名稱,子組件要傳給父組件的值)
template: `<div>
<button @click="$emit('click-count',num)">點贊:+ {{parentCount}}</button>
<span>{{userName}}</span>
</div>`,
data() {
return {
num: 1,
};
},
},
},
// 父組件更新數(shù)據(jù)的方法
methods: {
handle(value) {
console.log(this.count);
this.count += value;
},
},
});
</script>
</body>
父組件中通過定義同名事件,來對子組件中的數(shù)據(jù)進(jìn)行接收,另外,這個子組件傳遞的參數(shù)可以是任何類型。
總結(jié):
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號