深入了解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
这样就不用为每一个监听器写一个监听函数

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 组件注册 在注册一个组件的时候,我们始终需要给它一个名字。比如: 该组件名就是 Vue.component 的第一...
    胜过夜的美阅读 1,031评论 0 5
  • 组件注册 组件名 在注册一个组件的时候,我们始终需要给它一个名字。 该组件名就是Vue.component的第一个...
    oWSQo阅读 411评论 0 1
  • 什么是组件? 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装...
    youins阅读 9,533评论 0 13
  • 此文基于官方文档,里面部分例子有改动,加上了一些自己的理解 什么是组件? 组件(Component)是 Vue.j...
    陆志均阅读 3,868评论 5 14
  • http://liuxing.info/2017/06/30/Spring%20AMQP%E4%B8%AD%E6%...
    sherlock_6981阅读 16,015评论 2 11