深入了解vue自定义组件之$listeners

官方文档地址
$listeners是vue提供的一个对象,里面包含了所有作用在这个组件上的监听器。
比如你要自定义一个input组件,需要监听input获取焦点的事件
你可以这样做
自定义组件代码

<template>
    <div>
        <input type="text" v-on:focus="handleFocus" v-on:input="handleInput" />
    </div>
</template>

<script>
    export default {
        name: "ListenersDemo",
        props:{
            value: String
        },
        methods:{
            handleFocus(event){
                this.$emit("focused",event)
            },
            handleInput(event){
                this.$emit("input",event)
            }
        }
    }
</script>

父组件代码

<listeners-demo class="my-btn" v-on:focused="handleFocus" v-on:input="input" ></listeners-demo>

这样就可以实现预期的功能,但是你也可以使用更优雅的做法
修改之后
自定义组件代码

<template>
    <div>
<!--        接管所有原生监听事件-->
<!--        <input type="text" v-on="$listeners" />-->
<!--        自定义监听器 接管所有原生监听事件 可添加自定义监听事件并可以配合v-model使用-->
        <input type="text" v-on="inputListeners" v-bind:value="value" />
    </div>
</template>

<script>
    export default {
        name: "ListenersDemo",
        props:{
            value: String
        },
        computed:{
            inputListeners(){
                var vm = this
                // `Object.assign` 将所有的对象合并为一个新对象
                return Object.assign({},
                    // 我们从父级添加所有的监听器
                    this.$listeners,
                    // 然后我们添加自定义监听器,
                    // 或覆写一些监听器的行为
                    {
                        // 这里确保组件配合 `v-model` 的工作
                        input: function (event) {
                        	// 重写了input监听器,你也可以理解为自定义了一个名为input的监听器
                            vm.$emit('input', event.target.value)
                        }
                    }
                )
            }
        },
    }
</script>

父组件完整代码

<template>
    <div>
        <listeners-demo v-on:focus="handleFocus" v-on:input="handleInput" v-model="value" ></listeners-demo>
    </div>
</template>

<script>
    import ListenersDemo from "@/components/ListenersDemo";
    export default {
        name: "home",
        components: {
            ListenersDemo
        },
        data: () => ({
            value: '111111'
        }),
        methods:{
            handleInput(value){
                // eslint-disable-next-line no-console
                console.log(value)
            },
            handleFocus(event){
                // eslint-disable-next-line no-console
                console.log(event)
            }
        }
    }
</script>

使用v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素
也可以使用一个计算属性重写$listeners,上面代码中使用inputListeners重写了$listeners
这样就不用为每一个监听器写一个监听函数

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bdawn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值