VUE3 之 組件間事件通信 - 這個系列的教程通俗易懂间雀,適合新手

1. 概述

相關(guān)定律告訴我們:這個世界上的任何事物之間都會存在一定聯(lián)系,“城門失火涵亏,殃及池魚”就是一個很好的例子宰睡。因此如果我們能夠盡早發(fā)現(xiàn)這些看不見的聯(lián)系,就能很好的解決更多遇見的難題气筋。

言歸正傳拆内,之前我們聊過如何在子組件中去修改主組件傳遞的參數(shù)的值,當時是在子組件中重新聲明一個新數(shù)據(jù)宠默,初始值為父組件傳參的值麸恍,然后對子組件的數(shù)據(jù)進行計算。

今天我們使用事件的方式來實現(xiàn)對父組件的傳參進行修改搀矫。

2. 組件間事件通信

2.1 子組件接收參數(shù)并實現(xiàn)自增

<body>
    <div id="myDiv"></div>
</body>
<script>
    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        template:`
            <div>
                <test :num="num" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        methods : {
            incrNum() {
                this.num++;
            }
        },
        template:`
            <div @click="incrNum" >{{num}}</div>
        `
    });
    const vm = app.mount("#myDiv");

這個例子咱們之前聊過抹沪,父組件有一個數(shù)據(jù) num,父組件將這個參數(shù)傳給 test 子組件瓤球,子組件使用 props:['num'] 的方式接收后融欧,在事件方法中對其自增

image.png

很明顯,自增時會報錯冰垄,因為父組件傳過來的 num 是只讀的蹬癌,子組件不能對其進行修改权她。

2.2 子組件中聲明新的數(shù)據(jù)虹茶,將父組件的num作為初始值

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        template:`
            <div>
                <test :num="num" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        data() {
            return {
                myNum : this.num
            }
        },
        methods : {
            incrNum() {
                // this.num++;
                this.myNum++;
            }
        },
        template:`
            <div @click="incrNum" >{{myNum}}</div>
        `
    });

這是我們上節(jié)課的解決方案,在子組件中聲明 myNum隅要,把num當做初始值蝴罪,然后自增 myNum,顯示時也顯示 myNum

image.png

很明顯步清,這樣做是可以的

2.3 子組件調(diào)用父組件的方法

既然子組件無權(quán)修改父組件傳過來的參數(shù)要门,那我們就讓父組件自己去修改這個參數(shù)

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        methods : {
            handleIncr() {
                this.num++;
            }
        },
        template:`
            <div>
                <test :num="num" @incrNum="handleIncr" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        methods : {
            incrNum() {
                this.$emit('incrNum')
            }
        },
        template:`
            <div @click="incrNum" >{{num}}</div>
        `
    });

這個例子中虏肾,父組件在使用子組件時,綁定了一個事件 incrNum欢搜,這個事件會調(diào)用父組件的 handleIncr 方法封豪,這個方法中對數(shù)據(jù) num 進行了自增。

子組件在自己的 incrNum 方法中使用 this.$emit('incrNum') 觸發(fā)了父組件的 incrNum 事件炒瘟,然后該事件調(diào)用父組件的 handleIncr 方法吹埠,對父組件的數(shù)據(jù) num 進行修改。

父組件修改了數(shù)據(jù) num疮装,這個數(shù)據(jù) num 修改后的值會傳遞給子組件缘琅,從而實現(xiàn)對 num 參數(shù)的修改。

說了這么一大堆廓推,簡單看就是子組件通過某種手段調(diào)用了父組件的方法刷袍。

image.png

經(jīng)試驗,完全沒用問題樊展,可以修改 num 的值

2.4 子組件調(diào)用父組件的方法呻纹,且傳參

光調(diào)用還不行,我們還要傳參

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        methods : {
            handleIncr(param1) {
                this.num += param1;
            }
        },
        template:`
            <div>
                <test :num="num" @incrNum="handleIncr" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        methods : {
            incrNum() {
                this.$emit('incrNum', 2)
            }
        },
        template:`
            <div @click="incrNum" >{{num}}</div>
        `
    });

這個例子中专缠,我們根據(jù)傳參的值居暖,決定自增多少。

在 this.$emit('incrNum', 2) 這句代碼中藤肢,除了指明觸發(fā)的事件太闺,還傳了一個參數(shù),父組件的 handleIncr(param1) 這個方法嘁圈,就可以接收這個參數(shù)省骂,并使用

2.5 子組件調(diào)用父組件的方法,且傳多個參數(shù)

這次我們要傳多個參數(shù)最住,當然也是可以的

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        methods : {
            handleIncr(param1, param2) {
                this.num += param2;
            }
        },
        template:`
            <div>
                <test :num="num" @incrNum="handleIncr" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        methods : {
            incrNum() {
                this.$emit('incrNum', 2, 3)
            }
        },
        template:`
            <div @click="incrNum" >{{num}}</div>
        `
    });

這么傳:this.$emit('incrNum', 2, 3)钞澳,這么收:handleIncr(param1, param2),以此類推

2.6 計算邏輯放在子組件中

自增本來是子組件的業(yè)務涨缚,我們不想把這個邏輯放到父組件中轧粟,耦合性太強了,我們可以這么寫

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        methods : {
            handleIncr(param1) {
                this.num = param1;
            }
        },
        template:`
            <div>
                <test :num="num" @incrNum="handleIncr" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        methods : {
            incrNum() {
                this.$emit('incrNum', this.num + 1)
            }
        },
        template:`
            <div @click="incrNum" >{{num}}</div>
        `
    });

其實就是傳參時在子組件中計算好了脓魏,然后父組件直接賦值就好

2.7 通過 v-model 的方式兰吟,修改父組件數(shù)據(jù)的值

上面的例子中,我們通過子組件調(diào)用父組件的方法去修改父組件數(shù)據(jù)的值茂翔,耦合性還是有點強混蔼,父組件需要去為子組件寫一個方法。

其實還有一個更簡潔的辦法珊燎,就是通過 v-model 的方式惭嚣,來看下面的例子

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        template:`
            <div>
                <test v-model="num" />
            </div>
        `
    });
    app.component("test", {
        props:['modelValue'],
        methods : {
            incrNum() {
                this.$emit('update:modelValue', this.modelValue + 1);
            }
        },
        template:`
            <div @click="incrNum" >{{modelValue}}</div>
        `
    });

這個例子中遵湖,父組件使用 test 子組件時,使用 v-model="num" 的方式來傳參晚吞。

test 子組件接收時延旧,使用 props:['modelValue'] 的方式接收,注意:modelValue 是一個固定寫法槽地。

在子組件的自增方法中使用 this.$emit('update:modelValue', this.modelValue + 1); 的形式去修改 modelValue 的值垄潮,注意:update:modelValue 是固定寫法。

2.8 使用 num 替換 modelValue

上面的例子有點不好理解闷盔,無緣無故蹦出個 modelValue弯洗,父組件明明傳的是 num,為啥我接受要用 modelValue逢勾,太奇怪了

下面的例子更易于我們的理解

    const app = Vue.createApp({
        data() {
            return {
                num : 1
            }
        },
        template:`
            <div>
                <test v-model:num="num" />
            </div>
        `
    });
    app.component("test", {
        props:['num'],
        methods : {
            incrNum() {
                this.$emit('update:num', this.num + 1);
            }
        },
        template:`
            <div @click="incrNum" >{{num}}</div>
        `
    });

這個例子就好理解多了牡整,首先父組件使用 test 子組件時慷蠕,使用 v-model:num="num" 進行傳參浅役。

子組件接收時旁蔼,接收的就是 num覆获,使用 props:['num'] 接收。

最后使用 this.$emit('update:num', this.num + 1); 代碼對接收到的 num 進行修改欧芽。

顯示時顯示的也是 num症脂,{{num}}

這樣寫就清爽很多织鲸,父組件沒有 method句占,子組件相當于自己對接收到的參數(shù) num 進行操作沪摄,耦合度降低了很多。

3. 綜述

今天聊了一下 VUE3 的 組件間事件通信纱烘,希望可以對大家的工作有所幫助杨拐,下一節(jié)我們繼續(xù)講組件的相關(guān)知識,敬請期待

歡迎幫忙點贊擂啥、評論哄陶、轉(zhuǎn)發(fā)、加關(guān)注 :)

關(guān)注追風人聊Java哺壶,每天更新Java干貨屋吨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市山宾,隨后出現(xiàn)的幾起案子至扰,更是在濱河造成了極大的恐慌,老刑警劉巖塌碌,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渊胸,死亡現(xiàn)場離奇詭異旬盯,居然都是意外死亡台妆,警方通過查閱死者的電腦和手機翎猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來接剩,“玉大人切厘,你說我怎么就攤上這事“萌保” “怎么了疫稿?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鹃两。 經(jīng)常有香客問我遗座,道長,這世上最難降的妖魔是什么俊扳? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任途蒋,我火速辦了婚禮,結(jié)果婚禮上馋记,老公的妹妹穿的比我還像新娘号坡。我一直安慰自己,他們只是感情好梯醒,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布宽堆。 她就那樣靜靜地躺著,像睡著了一般茸习。 火紅的嫁衣襯著肌膚如雪畜隶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天号胚,我揣著相機與錄音代箭,去河邊找鬼。 笑死涕刚,一個胖子當著我的面吹牛嗡综,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杜漠,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼极景,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驾茴?” 一聲冷哼從身側(cè)響起盼樟,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锈至,沒想到半個月后晨缴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡峡捡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年击碗,在試婚紗的時候發(fā)現(xiàn)自己被綠了筑悴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡稍途,死狀恐怖阁吝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情械拍,我是刑警寧澤突勇,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站坷虑,受9級特大地震影響甲馋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迄损,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一摔刁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧海蔽,春花似錦共屈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至幌衣,卻和暖如春矾削,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背豁护。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工哼凯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人楚里。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓断部,卻偏偏與公主長得像,于是被迫代替她去往敵國和親班缎。 傳聞我的和親對象是個殘疾皇子蝴光,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容