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

2019-10-07  本文已影响0人  GX_路

官方文档地址
$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
这样就不用为每一个监听器写一个监听函数

上一篇下一篇

猜你喜欢

热点阅读