從0開始探究vue-組件化-組件之間傳值

理解

Vue中有個(gè)非常重要的核心思想,就是組件化,組件化是為了代碼復(fù)用

什么是組件化

組件化,就像一個(gè)電腦主機(jī)里的主板,有內(nèi)存條的插口,有硬盤,光驅(qū)等等的插口,我們的項(xiàng)目,就像一個(gè)電腦主機(jī),通過各種組件化的模塊(硬盤、內(nèi)存等),來拼合成一個(gè)完整的電腦。


vue組件化

(圖片來源 vue-組件化應(yīng)用構(gòu)建

如圖,每一個(gè)塊都是一個(gè)組件,由許許多多的組件拼合而成,可以無限的嵌套下去

組件化的好處

  1. 模塊復(fù)用,提高效率,讓重復(fù)的代碼只寫一遍。
  2. 預(yù)留個(gè)性化設(shè)置,可以保證模塊,既通用,又可變。
  3. 提高可維護(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

此處為觀察者模式

  1. 子組件調(diào)用this.$emit('confirm','點(diǎn)擊了確定')來派發(fā)confirm事件
  2. 父組件中<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)搭橋

  1. 使用公共父級(jí)組件$parents或者$root
//組件一
this.$parents.$on('foo',(e)=>{
    console.log(e);//此處e為$emit時(shí)傳入的值
})
//組件二
this.$parents.$emit('foo','bar');//控制臺(tái)輸出bar
  1. 使用任意兩個(gè)組件之間傳值的方案 點(diǎn)擊查看

跨輩分傳值

概念,所謂跨輩分傳值,就是

祖輩->父輩->子輩->孫輩->...
其中,垮了一個(gè)輩分或多個(gè)輩分的就是跨輩分傳值,例如,祖輩及孫輩

provide/inject

由于多級(jí)嵌套,使用props傳遞顯然是不現(xiàn)實(shí)的

針對這種情況,vue提供了 provide/inject兩個(gè)API來完成這件事

  1. 祖輩使用provide聲明一個(gè)變量
  2. 孫輩使用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ù)淖兞?    }
}

注意

  1. 此方法多用來制作組件庫時(shí)使用。
  2. 此方法不建議直接在孫輩修改祖輩的數(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

VuexVue提供的一種,專門用來管理vue中的公共狀態(tài),事件等等。詳見 從0開始探究vue-公共變量的管理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容