理解
Vue中有個(gè)非常重要的核心思想,就是組件化,組件化是為了代碼復(fù)用
什么是組件化
組件化,就像一個(gè)電腦主機(jī)里的主板,有內(nèi)存條的插口,有硬盤,光驅(qū)等等的插口,我們的項(xiàng)目,就像一個(gè)電腦主機(jī),通過各種組件化的模塊(硬盤、內(nèi)存等),來拼合成一個(gè)完整的電腦。

(圖片來源 vue-組件化應(yīng)用構(gòu)建)
如圖,每一個(gè)塊都是一個(gè)組件,由許許多多的組件拼合而成,可以無限的嵌套下去
組件化的好處
- 模塊復(fù)用,提高效率,讓重復(fù)的代碼只寫一遍。
- 預(yù)留個(gè)性化設(shè)置,可以保證模塊,既通用,又可變。
- 提高可維護(hù)性,如果一個(gè)項(xiàng)目多個(gè)頁面使用了同一個(gè)組件(例如消息彈框),如果修改彈框樣式,只需要修改這個(gè)模塊即可。
寫法
cli模式
組件部分
<template>
<div></div>
</template>
<script>
export default {
name:"myAlert"
};
<style></style>
使用者部分
<template>
<div>
<myAlert></myAlert> <!-- 實(shí)例中使用組件 -->
</div>
</template>
<script>
import myAlert from '@/components/alert.vue';//導(dǎo)入自己寫的組件
export default {
components:{myAlert}//在這個(gè)vue實(shí)例中注冊組件
};
</script>
<style></style>
引入vue.js模式
// 定義名為 todo-item 的新組件
Vue.component('myAlert', {
template: '<div>這是一個(gè)彈框</div>'
})
var app = new Vue(...)
html部分使用
<div>
<myAlert></myAlert>
</div>
組件傳值
Vue中存在的組件之間傳值的方案如下
父=>子
props
子組件中聲明props,父組件往對應(yīng)的props值中傳遞
$refs
父組件使用this.$refs.組件名.變量來選中子組件并修改子組件的內(nèi)容
$children
父組件使用this.$children[0].變量來選中并修改子組件的內(nèi)容
需要注意的是:由官網(wǎng)vm.$children得知
$children 并不保證順序,也不是響應(yīng)式的
所以一般不建議使用此方法來進(jìn)行傳值,因?yàn)椴荒芎芊€(wěn)定的找到指定組件的實(shí)例,除非這個(gè)頁面只有一個(gè)子組件
另外,此例中,this.$children[0]不是響應(yīng)式的this.$children[0].變量是響應(yīng)式的。
子=>父
$emit
此處為觀察者模式
- 子組件調(diào)用
this.$emit('confirm','點(diǎn)擊了確定')來派發(fā)confirm事件 - 父組件中
<myAlert @confirm='successCallback'></myAlert>來監(jiān)聽事件;
注意:此處為,誰派發(fā)就是誰監(jiān)聽,也就是說,confirm事件的派發(fā)者和監(jiān)聽者,都是myAlert組件,myAlert組件監(jiān)聽完畢后將調(diào)用父組件的successCallback回調(diào)事件,當(dāng)然這個(gè)監(jiān)聽的事件名和觸發(fā)的事件名都是可以自定義的。
兄弟組件之間互相傳值
使用公共節(jié)點(diǎn)搭橋
- 使用公共父級(jí)組件
$parents或者$root
//組件一
this.$parents.$on('foo',(e)=>{
console.log(e);//此處e為$emit時(shí)傳入的值
})
//組件二
this.$parents.$emit('foo','bar');//控制臺(tái)輸出bar
- 使用任意兩個(gè)組件之間傳值的方案 點(diǎn)擊查看
跨輩分傳值
概念,所謂跨輩分傳值,就是
祖輩->父輩->子輩->孫輩->...
其中,垮了一個(gè)輩分或多個(gè)輩分的就是跨輩分傳值,例如,祖輩及孫輩
provide/inject
由于多級(jí)嵌套,使用props傳遞顯然是不現(xiàn)實(shí)的
針對這種情況,vue提供了 provide/inject兩個(gè)API來完成這件事
- 祖輩使用
provide聲明一個(gè)變量 - 孫輩使用
inject來注入祖輩聲明的變量
寫法:
//祖輩
export default {
provide(){//此處可以傳入動(dòng)態(tài)變量,與data類似
return {
componentYeye:this
}
},
data(){
return {
yeyedeBianliang:'爺爺?shù)淖兞?
}
}
}
//孫輩
export default {
inject:['componentYeye'],//此處為數(shù)組,注入祖輩聲明的變量
mounted(){
console.log(this.componentYeye.yeyedeBianliang);//爺爺?shù)淖兞? }
}
注意
- 此方法多用來制作組件庫時(shí)使用。
- 此方法不建議直接在孫輩修改祖輩的數(shù)據(jù)。因?yàn)檫@些數(shù)據(jù)可能在多個(gè)子組件中使用,如果要修改,應(yīng)該調(diào)用祖輩組件變量的方法來修改,與
vuex中建議變量修改都是用commit類似
使用任意兩個(gè)組件之間傳值的方案 點(diǎn)擊查看
任意兩個(gè)組件之間傳值
<a id='evert-components'></a>
原型掛載
所謂原型掛載,就是在main.js中將公共變量,事件,都掛在到Vue原型上
//main.js
Vue.prototype.$globalData = {}
Vue.prototype.$sayName = function(e){
console.log('我的名字是',e)
}
new Vue({...})
//組件一
Vue.prototype.$globalData.name='小明';
this.$sayName('小王');//我的名字是小王
//組件二
console.log(this.$sayName.name);//小明
this.$sayName('小王');//我的名字是小王
事件總線
所謂事件總線,就是在當(dāng)前的Vue實(shí)例之外,再創(chuàng)建一個(gè)Vue實(shí)例來專門進(jìn)行變量傳遞,事件處理,管理回調(diào)事件等
//main.js中
Vue.prototype.$bus = new Vue();
new Vue({...})
//組件一
this.$bus.$on('sayName',(e)=>{
console.log('我的名字是',e)
})
//組件二
this.$bus.$emit('sayName','小明');//我的名字是 小明
vuex
Vuex是Vue提供的一種,專門用來管理vue中的公共狀態(tài),事件等等。詳見 從0開始探究vue-公共變量的管理