Vue 組件詳解之組件通信

組件中的關(guān)系可分為父子組件通信、兄弟組件通信和跨級(jí)組件通信。

一、自定義事件 ---- 子組件給父組件傳遞數(shù)據(jù)

我們用 props 來(lái)接收父組件傳遞給子組件的數(shù)據(jù),那么子組件如何給父組件傳遞數(shù)據(jù)呢?
JavaScript 的一種設(shè)計(jì)模式 一一 觀察者模式,包含 dispatchEventaddEventListener 這兩個(gè)方法。Vue 組件也有與之類(lèi)似的一套模式,子組件用 $emit() 來(lái)觸發(fā)事件,父組件用 $on() 來(lái)監(jiān)聽(tīng)子組件的事件 。

  • v--on 除了監(jiān)聽(tīng) DOM 事件外,還可以用于組件之間的自定義事件。
  • 第一步:在子組件標(biāo)簽上自定義事件
  • 第二步: 在子組件的方法中用 $emit() 觸發(fā)事件,第一個(gè)參數(shù)是事件名,后面的參數(shù)是要傳遞的數(shù)據(jù)(可以有 n 個(gè)參數(shù))
  • 第三步:在父組件的 methods 的自定義事件中用一個(gè)參數(shù)來(lái)接受
<div id="app">
    您現(xiàn)在的銀行卡余額是:{{total}} 元
    <son-component @change="handleTotal"></son-component> <!-- change為自定義事件 -->
</div>
<script>
    var app = new Vue({
        el: "#app", 
        data: {
            total: 2000
        },
        // 需求: 通過(guò)加號(hào)按鈕和減號(hào)按鈕來(lái)給父組件傳遞數(shù)據(jù)
        components: {
            'son-component': {
                template: '<div>\
                            <button @click="handleincrease">+1000</button>\
                            <button @click="handlereduce">-1000</button>\
                        </div>',
                data: function(){
                    return {
                        count: 2000
                    }
                },
                methods: {
                    handleincrease: function(){
                        this.count = this.count + 1000
                        // 觸發(fā)change事件,并把 this.count 傳遞過(guò)去
                        this.$emit('change',this.count) 
                    },
                    handlereduce: function(){
                        this.count = this.count - 1000
                        this.$emit('change',this.count)
                    }
                },
            }
        },
        methods: {
            handleTotal: function(value){
                // 此處的形參 value 就是傳遞過(guò)來(lái)的數(shù)據(jù) count
                this.total = value
            }
        }
    })
</script>

二、在組件中使用 v--model

  1. v--model 其實(shí)是一個(gè)語(yǔ)法糖,這背后其實(shí)做了兩個(gè)操作:
  • v--bind 指令綁定一個(gè) value 屬性
  • v--on 指令給當(dāng)前元素綁定 input 事件
  1. 使用 v--model 要做到:
  • 接收一個(gè) value 屬性
  • 在有新的 value 時(shí)觸發(fā) input 事件
<div id="app">
    您現(xiàn)在的銀行卡余額是:{{total}} 元
    <son-component v-model="total"></son-component>
    v-model 其實(shí)就是綁定了 input 事件, 當(dāng)觸發(fā) input 時(shí),<br>
    input 事件就會(huì)自動(dòng)接收傳遞過(guò)來(lái)的參數(shù), 并賦值給已經(jīng)綁定的 total。
</div>
<script>
    var app = new Vue({
    el: "#app", 
    data: {
        total: 2000
    },
    components: {
        'son-component': {
            template: '<div>\
                    <button @click="handleincrease">+1000</button>\
                    </div>',
                data: function(){
                    return {
                        count: 2000
                    }
                },
                methods: {
                    handleincrease: function(){
                        this.count = this.count + 1000
                        this.$emit('input',this.count)
                    }
                },
        }
    }
  })
</script>

this.$emit('input',this.count) 這行代碼會(huì)觸發(fā)一個(gè) input 事件,后面的參數(shù)就是傳遞給 v--model 綁定的屬性 total 的值。

三、非父組件之間的通信

  • 官網(wǎng)描述:
    官網(wǎng)描述
  • 圖形實(shí)例:子組件 A 與子組件 B 之間的通信
    圖形實(shí)例
  1. 非父組件之間進(jìn)行通信時(shí)(如將 A 組件數(shù)據(jù)傳遞給 B 組件),首先需要在根組件中定義一個(gè) bus 中介,然后在 A 組件中觸發(fā)一個(gè)事件并將參數(shù)傳遞過(guò)去 ,B 組件在實(shí)例創(chuàng)建的時(shí)候就監(jiān)聽(tīng)這個(gè)事件,并接收傳遞進(jìn)來(lái)的參數(shù)。
<div id="app">
    <my-acomponent></my-acomponent>
    <my-bcomponent></my-bcomponent>
</div>
<script>
    var app = new Vue({
        el: "#app", 
        data: {
            bus: new Vue()
        },
        components: {
            'my-acomponent': {
                template: '<button @click="handle">點(diǎn)擊我向B組件傳遞數(shù)據(jù)</button>',
                data: function(){
                    return {
                        amessage: '我是來(lái)自組件 A 的內(nèi)容'
                    }
                },
                methods: {
                    handle: function(){
                        this.$root.bus.$emit('lala', this.amessage)
                    }
                }
            },
            'my-bcomponent': {
                template: '<div></div>',
                created: function(){
                    // A組件在實(shí)例創(chuàng)建的時(shí)候就監(jiān)聽(tīng)事件---lala事件
                    this.$root.bus.$on('lala', function(value){
                        alert(value)
                    })
                }
            }
        }
    })
</script>
  1. 父鏈:this.$parent
    子組件訪問(wèn)父組件的內(nèi)容:
<div id="app">
    <child-component></child-component> --- {{msg}}
</div>
<script>
    var app = new Vue({
        el: "#app", 
        data: {
            msg: '數(shù)據(jù)未修改'
        },
        components: {
            'child-component': {
                template: '<button @click="setParentData">點(diǎn)擊修改父組件內(nèi)容</button>',
                methods: {
                    setParentData: function(){
                        this.$parent.msg = "數(shù)據(jù)已經(jīng)修改了"
                    }
                }
            }
        }
    })
</script>
  1. 子鏈:this.$refs
    父組件訪問(wèn)子組件內(nèi)容,用 this.$children 會(huì)找到所有的子組件。Vue 提供了為子組件提供索引的方法,用 ref 來(lái)指定一個(gè)屬性名稱(chēng),即為其增加一個(gè)索引。
<div id="app">
    <my-acomponent ref="a"></my-acomponent>
    <button @click="getChildData">我是父組件的按鈕,我要拿到子組件內(nèi)容</button> --- {{fromChild}}
</div>
<script>
    var app = new Vue({
        el: "#app", 
        data: {
            fromChild: '還未拿到'
        },
        methods: {
            getChildData: function(){
                this.fromChild = this.$refs.a.amessage
            }
        },
        components: {
            'my-acomponent': {
                template: '<div></div>',
                data: function(){
                    return {
                        amessage: '我是來(lái)自組件 A 的內(nèi)容'
                    }
                }
            }
        }
    })
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 組件(Component)是Vue.js最核心的功能,也是整個(gè)架構(gòu)設(shè)計(jì)最精彩的地方,當(dāng)然也是最難掌握的。...
    六個(gè)周閱讀 5,763評(píng)論 0 32
  • 父子組件通信 1、父子組件通過(guò)prop傳遞數(shù)據(jù) 父組件可以將一條數(shù)據(jù)傳遞給子組件,這條數(shù)據(jù)可以是動(dòng)態(tài)的,父組件的數(shù)...
    視覺(jué)派Pie閱讀 1,338評(píng)論 0 18
  • 對(duì)于vue來(lái)說(shuō),組件之間的消息傳遞是非常重要的,下面是我對(duì)組件之間消息傳遞的各種方式的總結(jié),總共有8種方式。 1....
    edc余悸閱讀 425評(píng)論 0 3
  • 那個(gè)時(shí)候,還沒(méi)有爺爺柱的拐杖般高的年紀(jì)。就已經(jīng)對(duì)未來(lái)充滿了憧憬,似乎帶著某種期盼,止不住想要長(zhǎng)大的欲望。想著尚未長(zhǎng)...
    甘十七閱讀 282評(píng)論 0 1
  • 觀音要考驗(yàn)三只猴子,在它們中間擺放了一些水果。三只猴子都想去拿,但一伸爪便下起了雨,將它們?nèi)苛軡窳?,它們急忙縮回...
    瑾小墨閱讀 148評(píng)論 0 2

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