Vue子組件向父組件傳參(事件傳參)

1.自定義事件

1.1 認識自定義事件

處理可以使用原生的 DOM 事件, v-on 也可以觸發組件內部的自定義事件,調用 this.$emit("事件名") 就可以觸發一個自定義事件.

$emit() 觸發事件函數接受一個自定義事件的事件名以及其他任何給事件函數傳遞的參數. 然後就可以在組件上使用 v-on 來綁定這個自定義事件

this.emit("事件名",參數1,參數2.....)

在這裏插入圖片描述
與自定義事件相關的命令有以上四個:

  1. $emit 觸發自定義事件
  2. $on 綁定自定義事件,可以調用無數次
  3. $once 綁定自定義事件,只能觸發一次
  4. $off 取消自定義事件的綁定

基本語法:

this.emit("事件名",參數1,參數2.....)

實例.$on("事件名",function(參數1,參數2....){})

實例.$once("事件名",function(參數1,參數2....){})

this.$off("事件名")

1.2自定義事件的基本使用

實例代碼如下:

<div id="app">
        {{count}}
        <button @click="clickBtn ">綁定事件</button>
        <button @click = "clickBtn2">取消事件綁定</button>
    </div>

    <script>
        let vm = new Vue({
            el:"#app",
            data:{
                count:0,
            },
            methods:{
                clickBtn() {
                    //觸發事件
                    this.$emit("add");

                    // this.$emit("count")
                },
                clickBtn2() {
                    this.$off("add")
                }
            },
            components: {
                // MyCom,
            }
        })

        //綁定一個自定義事件
        vm.$on("add",function () {
            this.count++
        })
        
        //綁定事件只觸發一次
        vm.$once("count",function () {
            this.count++
        })

現在我們就可以利用自定義事件讓子組件改變父組件的值或者想父組件傳參

2.子組件觸發父組件數據的改變

通過父組件向子組件傳值的學習,我們已經知道了 Vue 是單向下行數據流, 子組件更改 props 中的數據不會觸發父組件數據的改變, 但是由於響應式原理,父組件數據的改變會導致子組件 props 中值的改變

那麼我們怎麼才能在子組件中改變父組件中的數據呢???

  1. 子組件中沒有辦法改變父組件中的數據,那麼我們就讓父組件的函數改變自己的數據
  2. 這樣我們就可以在子組件中觸發父組件的函數來改變數據,就要通過我們的自定義事件
  3. 子組件在函數中觸發自定義事件,將父組件中更改數據的函數綁定爲自定義事件函數.
  4. 然後父組件中的數據會發生變化,因爲響應式原理,子組件中的數據也會發生變化.

看下面的示例代碼:
我們通過在子組件中調用父組件的方法,從而達到改變父組件數據的目的:

<div id="app">
    <!-- 3.在子組件中綁定自定義事件, 將父組件的方法綁定爲自定義事件的處理函數-->
    <my-com
            :count = "count"
            @count="addCount"
    ></my-com>
</div>

<template id="mycom">
    <div>
        <h3>我被點擊了{{count}}</h3>
        <!-- 1. 子組件通過原生click事件觸發子組件自己的函數 -->
        <button @click="add">點擊+1</button>
    </div>
</template>

<script>
    let MyCom = ({
        props:["count"],
        template: "#mycom",
        methods: {
            add() {
                // 2.子子組件函數中觸發自定義事件
                this.$emit("count");
            }
        }
    })

    let vm = new Vue({
        el: "#app",
        data: {
            count: 0
        },
        components: {
            MyCom,
        },
        methods: {
            // 4. 在父組件函數中修改父組件中的數據
            addCount() {
                this.count++;
            }
        }
    })
</script>

點擊數字會增加:
在這裏插入圖片描述
當點擊子組件按鈕時,在子組件處理函數中觸發父組件中的自定義事件,進而觸發父組件中自定義事件的自定義函數,然後就會在父組件中修改父組件中的數據.
進而通過 props 響應式,當父組件中的數據改變,子組件中的數據也會發生相應的改變.

我們也知道$emit方法在觸發自定義事件的時候,還可以給自定義事件傳參, 這樣就可以實現子組件像父組件傳參.

3.子組件給父組件傳參

通過前面的介紹,我們瞭解到,我們是在子組件中通過自定義事件觸發父組件中的函數, 在父組件中修改數據,

同樣我們也可以在子組件中修改數據,然後將修改後的數據通過自定義事件傳參的方式,傳遞給父組件函數,在父組件函數中直接用子組件傳過來修改後的數據直接替換父組件中的數據

示例代碼如下:
當我們每次點擊都讓它加2

<div id="app">
    <!-- 3.在子組件中綁定自定義事件, 將父組件的方法綁定爲自定義事件的處理函數-->
    <my-com
            :count = "count"
            @count="addCount"
    ></my-com>
</div>

<template id="mycom">
    <div>
        <h3>我被點擊了{{count}}</h3>
        <!-- 1. 子組件通過原生click事件觸發子組件自己的函數 -->
        <button @click="add">點擊+1</button>
    </div>
</template>

<script>
    let MyCom = ({
        props:["count"],
        template: "#mycom",
        methods: {
            add() {
                // 2.子子組件函數中觸發自定義事件
                this.$emit("count",2);
            }
        }
    })

    let vm = new Vue({
        el: "#app",
        data: {
            count: 0
        },
        components: {
            MyCom,
        },
        methods: {
            // 4. 在父組件函數中修改父組件中的數據
            addCount(value) {
                console.log(value);
                this.count +=2;
            }
        }
    })
</script>

在這裏插入圖片描述
案例二:

    <div id="app">
        <!--   3.在子組件中綁定自定義事件, 將父組件的方法綁定爲該自定義事件的處理函數   -->
        <my-com :menu = "menu"  @add = "addMenu"></my-com>
    </div>
    <template id = "MyCom">
        <div>
            <ol >
                <li v-for = "(food,index) in menu" :key="index">
                    {{food.name }}: {{ food.price}}
                </li>
            </ol>
            <!-- 1.子組件通過原生的click觸發子組件中的自定義函數-->
            <button @click = "addSon">點擊添加菜品</button>
        </div>
    </template>

    <script>
        let MyCom = ({
            props:["menu"],
            template:"#MyCom",
            methods:{
                addSon(){
                    // 2.子組件函數中觸發自定義事件,有傳參
                   this.$emit("add",{
                        name:"酸辣土豆絲",
                        price:9,
                   })
                }
            }
        })

        let vm = new Vue({
            el:"#app",
            data:{
                menu:[
                    {
                        name:"西紅柿炒雞蛋",
                        price:10,
                    },
                    {
                        name:"辣椒炒肉",
                        price:15,
                    },
                ]
            },
            methods:{
                //4. 在父組件函數中修改父組件的數據,value就是傳遞的參數
                addMenu(value) {
                    console.log(value);
                    this.menu.push(value)
                }
            },
            components: {
                MyCom,
            }
        })

        //綁定一個自定義事件
        vm.$on("add",function () {
            // this.count++
            console.log(111)
        })

初始顯示結果:
在這裏插入圖片描述
點擊之後的結果:
在這裏插入圖片描述
打印的參數 value 的結果:
在這裏插入圖片描述

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