0%

踩坑|Vue子传父引发的v-on的传参疑惑

Vue事件监听v-on的参数传递和父子组件通信

首先看看v-on的传参方式

  1. 当函数没有参数时,调用可以不用带()

  2. 当函数有参数,调用时不带(),自动触发event事件,原生dom事件

  3. 当函数有参数,正常调用要带()

  4. 当函数有多个参数,但是少传参时,没有传参的会报undefined,不会触发event事件

  5. 当函数想要触发event事件,实参需要传$event

    即以下代码

    <div id="app">
            <!-- 当函数没有参数时,调用可以不需要带() -->
            <button @click="btnClick">按钮1</button>
            <!-- 当函数有参数,调用时不带()时,自动触发event事件 -->
            <button @click="btnClick1">按钮2</button>
            <!-- 当函数有参数,正常调用调用带() -->
            <button @click="btnClick1(1)">按钮3</button>
            <!-- 函数有多个参数,但是少传参时,没传参的会报undefined,不会触发event事件 -->
            <button @click="btnClick2(1)">按钮4</button>
            <!-- 函数想要触发event事件,实参需要传$event -->
            <button @click="btnClick2(1,$event)">按钮5</button>
        </div>
    
        <script src="../js/vue.js"></script>
        <script>
            const app = new Vue({
                el: '#app',
                data: {
    
                },
                methods: {
                    btnClick(){
                        console.log("按钮")
                    },
                    btnClick1(event){
                        console.log(event)
                    },
                    btnClick2(abc,event){
                        console.log("++++++")
                        console.log(abc)
                        console.log(event)
                    },
                },
                computed: { 
                }
            })
        </script>

在组件通信中,子传父

<div id="app">
    <!-- 父组件监听事件 -->
    <cpn @itemclick="cpnclick"></cpn>
</div>
<template id="cpn">
<div>
    <button v-for="item in categories" @click="submit(item)">{{item.name}}</button>
    </div>
</template>
<script src="../js/vue.js"></script>
<script>
    const cpn = {
        template: "#cpn",
        data() {
            return {
                categories: [
                    {id: "aaa",name: "笔记本"},
                    {id: "bbb",name: "手机"},
                    {id: "ccc",name: "平板"},
                    {id: "ddd",name: "风扇"}
                ]
            }
        },
        props: {
        },
        methods: {
            submit(item){
                // 子组件发出去这个事件
                this.$emit('itemclick',item)
            }
        }
    }

    const app = new Vue({
        el: "#app",
        data: {
        },
        components: {
            cpn,
        },
        methods: {
            cpnclick(item) {
                console.log(item)
            }
        }
    })
</script>

在上面的代码中,父组件中@itemclick="cpnclick"监听子组件发送事件itemclick,子组件发送itemclick的同时也发送了item

当时关于如何监听item产生了疑惑,为什么要调用cpnclick却不带()和参数,于是进行一下测试

  • 当带了实参(item),结果打印undefined

    @itemclick="cpnclick(item)"

  • 当不带(),能正常打印

    @itemclick="cpnclick"

  • 当实参传入$event,能正常打印

    @itemclick="cpnclick($event)"

总结,实际上传递的是event事件,但是不是浏览器的event事件,所以传递的发送的第二个参数