Vue 父子組間通訊(props、$ref、$emit)

在簡紹通信之前,我么你先來建兩個組間father.vue和child.vue作為實例的基礎。

//父組件
<template>
    <div>
        <img src="../../assets/img.jpeg">
        <h1>我是父花花</h1>
        <child></child>
    </div>
</template>

<script>
    import Child from './child'
    export default {
        name: "father",
        components:{
            Child
        }
    }
</script>

//子組件
<template>
    <div>
        <h3>我是子花花</h3>
    </div>
</template>

這兩部分代碼很清楚,父組間通過import的方式導入子組件,并在components屬性中注冊,然后就可以以標簽<child>的形式嵌套進父組件,運行father.vue后,如圖:

效果圖1

1、通過prop實現通信

子組件的props能接受父組件的數據,僅僅是接受,props是單向綁定的,即只能父組間向子組件傳值,不能反向。具體可查看官方文檔

prop的專遞方式有兩種:

(1)靜態傳遞

子組件通過props選項聲明一個自定義屬性,父組件可以在嵌套標簽的時候,通過這個屬性往子組件傳遞數據。

//父組件
<template>
    <div>
        <img src="../../assets/img.jpeg">
        <h1>我是父花花</h1>
        <child message="我是子花花"></child><!--通過自定義屬性傳遞數據-->
    </div>
</template>

<script>
    import Child from './child'
    export default {
        name: "father",
        components:{
            Child
        }
    }
</script>

//子組件
<template>
    <div>
        <h3>{{message}}</h3>
    </div>
</template>

<script>
    export default {
        name: "child",
        props:[
            'message'//聲明一個自定義的屬性
        ]
    }
</script>

(2)動態傳遞

我們可以像上面一樣給props傳入一個靜態的值,但更多時候需要動態傳數據,這時候我們可以通過v-bind動態傳值,使用v-bind綁定props的自定義屬性,傳遞過去的就不是靜態字符串了,還可以傳遞數字、布爾值、對象、數組等任何類型的值,具體可查看官方文檔

//父組件
<template>
    <div>
        <img src="../../assets/img.jpeg">
        <h1>我是父花花</h1>
        <child message="我是子花花"></child>
        <child :message="msg"></child><!-- 用一個變量進行動態賦值。-->
        <child :message="msg1+msg2"></child>
    </div>
</template>

<script>
    import Child from './child'

    export default {
        name: "father",
        components: {
            Child
        },
        data() {
            return {
                msg:'我是子花花二'+Math.random(),
                msg1:'我是子花花三',
                msg2:'xiahuahua',

            }
        }
    }
</script>

//子組件
<template>
    <div>
        <h3>{{message}}</h3>
    </div>
</template>

<script>
    export default {
        name: "child",
        props:[
            'message'//聲明一個自定義的屬性
        ]
    }
</script>

效果如圖:


效果圖2

2、通過$ref實現通信

對于ref,官方的解釋是:ref 被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $ref 對象上。
對于官方的解釋,可以這樣理解:

  • 如果ref用在子組件上,指向的是組間實例,可以理解為子組件的索引,通過$ref可以獲取到在子組件里定義的屬性和方法。
  • 如果ref用在DOM元素上,引用指向的就是DOM元素,通過$ref 可以獲取DOM元素的屬性集合,作用與JQ選擇器類似。
//父組件
<template>
    <div>
        <img src="../../assets/img.jpeg">
        <h1>我是父花花</h1>
        <child ref="msg"></child>
    </div>
</template>

<script>
    import Child from './child'
    export default {
        name: "father",
        components:{
            Child
        },
        mounted(){
            console.log(this.$refs.msg);
            this.$refs.msg.getMessage('我是子花花!~');
        }
    }
</script>

//子組件
<template>
    <div>
        <h3>{{message}}</h3>
    </div>
</template>

<script>
    export default {
        name: "child",
        data() {
            return {
                message:''
            }
        },
        methods: {
            getMessage(msg) {
                this.message = msg;
            }
        }
    }
</script>

從上面代碼可以看出,通過ref=‘msg’可以將子組件child的實例給ref,并且通過this.refs.msg.getMessage(),就能使用子組件定義的getMessage()方法并將參數傳遞給子組件,從而實現數據傳遞,下面是console.log(this.refs.msg)打印出來的數據,如圖所示:

console.log

最后效果如圖:


效果圖3

補充:prop和$ref之間的區別

  • prop注重數據的傳遞,它并不能調用子組件里的屬性和方法。像創建文章組間時,自定義標題和內容這樣的場景,最適合使用prop。
  • $ref注重于索引,主要用來調用子組件里的屬性和方法,其并不擅長數據傳遞;而ref用在DOM元素時,能當做選擇器的使用,這個功能比作為索引更常用到。

3、通過$emit實現通信

上面兩種方法主要是父組件向子組件通信,而通過emit實現子組件向父組件通信。emit在官網上解釋的很朦朧,按我的理解,就是子組件中的$emit就是發送參數,父組件中的“@關鍵名”就是接受參數,然后基于這個邏輯豐富代碼,實現想要的功能效果。

//父組件
<template>
    <div>
        <img src="../../assets/img.jpeg">
        <h1>{{msg}}</h1>
        <child @getMessage="showMsg"></child>
    </div>
</template>

<script>
    import Child from './child'

    export default {
        name: "father",
        components: {
            Child
        },
        data() {
            return {
                msg: ''
            }
        },
        methods:{
            showMsg(msg){
                this.msg = msg;
            }
        }
    }
</script>

//子組件
<template>
    <div>
        <h3>我是子花花!~</h3>
    </div>
</template>

<script>
    export default {
        name: "child",
        mounted(){
            this.$emit('getMessage','我是父花花@-@');
        }
    }
</script>
效果圖4
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容