通過大頭兒子和小頭爸爸,給女朋友講明白了vue中父子組件的傳值

寫在前面: 我是「揚帆向海」,這個暱稱來源於我的名字以及女朋友的名字。我熱愛技術、熱愛開源、熱愛編程。技術是開源的、知識是共享的

這博客是對自己學習的一點點總結及記錄,如果您對 Java算法 感興趣,可以關注我的動態,我們一起學習。

用知識改變命運,讓我們的家人過上更好的生活


女朋友:“揚帆,你給我上一次講了 vue中的組件
,我現在自己學習父子組件的傳值,可是官方文檔看不懂啊!你能不能通過父子組件傳值的知識實現大頭兒子和小頭爸爸互相通信呢?”

: “可以呀!我先分別給你講父組件向子組件傳值和子組件向父組件傳值,最後在給你寫個案例,實現父子組件的相互通信。”

在這裏插入圖片描述

點擊【說話】按鈕,大頭兒子給小頭爸爸傳遞消息。

在這裏插入圖片描述

小頭爸爸收到消息,點擊【回覆】按鈕,給大頭兒子發送消息。

在這裏插入圖片描述


一、父組件向子組件傳值

1. 傳值步驟

① 子組件在props中創建一個屬性,用以接收父組件傳過來的數據;

② 父組件中註冊子組件。通過屬性綁定(v-bind:)的形式,把需要傳遞給子組件的數據傳遞到子組件的內部,供子組件使用;

③ 在子組件標籤中添加子組件props中創建的屬性;

④ 把需要傳給子組件的值賦給該屬性

2. 代碼示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>父組件向子組件傳值</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 父組件中註冊子組件 -->
        <!-- 在子組件標籤中添加子組件props中創建的屬性, 把需要傳給子組件的值賦給該屬性 -->
        <mycom :parent-msg='pmsg' :content='hello'></mycom>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: '父組件中的內容',
                hello: '我是父組件傳過來的'
            },
            components: {
                mycom: {
                    data: function () {
                        return {
                            msg: '我是子組件本身的數據'
                        }
                    },
                    // 子組件在props中創建一個屬性,用以接收父組件傳過來的值
                    props: ['parentMsg', 'content'],
                    template: '<h3>{{msg + "---" + parentMsg + "----" + content}}</h3>'
                }
            }
        });
    </script>
</body>

</html>

【效果如下】
在這裏插入圖片描述

3. 注意事項

prop 是子組件用來接受父組件傳遞過來的數據的一個自定義屬性。

② 父組件的數據需要通過 props 把數據傳給子組件,子組件需要顯式地用 props 選項聲明 “prop”:

prop 是單向綁定的:當父組件的屬性變化時,將傳導給子組件,但是不會反過來。

props中的數據都是隻讀的,無法進行重新賦值。

二、子組件向父組件傳值

1. 傳值步驟

① 子組件需要以某種方式例如點擊事件的方法來觸發一個自定義事件;

② 將需要傳遞的值作爲$emit的第二個參數,該值將作爲實參傳遞給響應自定義事件的方法;

③ 在父組件中註冊子組件,在子組件標籤上監聽該自定義事件,並添加一個響應該事件的處理方法

2. 代碼示例

點擊子組件中的按鈕,給父組件發送子組件的信息

<body>
    <div id="app">
        <h3>父組件</h3>
        <child @receive="handleEvent"></child>
    </div>
    <script>
        Vue.component('child', {
            template: `
                <div>
                    <h3>子組件</h3>
                    <button @click="sendMessage()">發送</button>
                </div>
            `,
            data() {
                return {
                }
            },
            methods: {
                sendMessage() { // 按鈕的點擊事件
                    this.$emit("receive","父組件您好,我是子組件!") // 調用父組件傳遞過來的方法,並且把數據傳遞出去
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            methods: {
                // 定義在子組件中通過 this.$emit() 調用的方法
                handleEvent(val) {
                    console.log("父組件收到的消息是:",val)
                }
            }
        })
    </script>
</body>

【效果如下】
在這裏插入圖片描述

3. 注意事項

① 父組件是使用 props 傳遞數據給子組件,但如果子組件要把數據傳遞回去,就需要使用自定義事件!

② 我們可以使用 v-on 綁定自定義事件, 每個 Vue 實例都實現了事件接口(Events interface),即:

使用 $on(eventName) 監聽事件
使用 $emit(eventName) 觸發事件

③ 父組件可以在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件。

三、大頭兒子小頭爸爸案例

這個案例實現了文章開頭:大頭兒子和小頭爸爸之間的通信

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>父子組件通信</title>
    <script src="js/vue.js"></script>
    <style>
        .father,
        .son {
            width: 150px;
            height: 100px;
        }

        .info {
            color: #446ee4;
            font-size: 20px;
            font-size: bold;
        }

        .desc {
            font-size: 18px;
        }

        .btn {
            width: 100px;
            float: left;
            height: 40px;
            font-size: 18px;
            color: #fff;
            font-weight: bold;
            background: #446ee4;
            margin-top: 15px;
        }

        .parent,
        .child {
            display: inline-block;
            width: 550px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="parent">
            <img class="father" src="images/father.jpg">
            <div class="info">我是小頭爸爸</div>
            <div v-if="msg !== ''" class="desc">小頭爸爸接收到的消息:【{{msg}}】</div>
            <div v-if="replyMsg !== ''" class="desc">小頭爸爸回覆說:【{{replyMsg}}】</div>
            <button class="btn" @click="reply()">回覆</button></button>
        </div>
        <div class="child">
            <child :reply-msg="replyMsg" @listen="listenHandle($event)"></child>
        </div>
    </div>
    <script>
        Vue.component('child', {
            props: {
                replyMsg: {
                    type: String,
                    default: ''
                }
            },
            template: `
                <div>
                    <img class="son" src="images/son.jpg">
                    <div class="info">我是大頭兒子</div>
                    <div v-if="msg !== ''" class="desc">大頭兒子說:【{{msg}}】</div>
                    <div v-if="replyMsg !== ''" class="desc">大頭兒子接收到的消息:【{{replyMsg}}】</div>
                    <button class="btn" @click="say()">說話</button>
                </div>
            `,
            data() {
                return {
                    msg: ''
                }
            },
            methods: {
                say() {
                    this.msg = '小頭爸爸好!'
                    this.$emit("listen", this.msg)
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            data() {
                return {
                    msg: '',
                    replyMsg: ''
                }
            },
            methods: {
                listenHandle(val) {
                    this.msg = val
                },
                reply() {
                    this.replyMsg = '小頭兒子好,消息已收到'
                }
            },

        })
    </script>
</body>

</html>

【效果如下】

在這裏插入圖片描述

四、總結

在這裏插入圖片描述

在組件傳值過程中,無論是父傳子、還是子傳父,它們都有一個共同點就是有一箇中間介質。父傳子的介質是props中的屬性,子傳父的介質是自定義事件。

父子組件的關係可以總結爲prop向下傳遞,事件向上傳遞。父組件通過prop給子組件下發數據,子組件通過事件給父組件發送信息。

父組件通過 v-bind:綁定參數傳給子組件,子組件通過props接受這個參數。

在組件的最底層開始寫事件,由最底層組件逐步向上$emit事件流,並攜帶相應參數,最後在父組件內完成總的數據處理。


由於水平有限,本博客難免有不足,懇請各位大佬不吝賜教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章