3

案例一:native 绑定的input事件可以触发dosomething函数

<div id="app">
    <!-- native 将原生事件绑定到组件 -->
    <base-input label="姓名" value="Vue" placeholder="请输入名字" v-on:input.native="dosomething"></base-input>
</div>
<script>
    Vue.component('base-input', {
        inheritAttrs: false,
        props: ['label', 'value'],
        template: `
            <label>
                {{ label }}
                <input
                    v-bind="$attrs"
                    v-bind:value="value"
                >
            </label>
        `
    });
    new Vue({
        el: '#app',
        methods: {
            dosomething() {
                console.log('y');
            }
        }
    });
</script>

案例二:native 绑定的focus事件却不可以触发dosomething函数(下面案例三为解决方案)

<div id="app">
    <!-- native 将原生事件绑定到组件 -->
    <base-input label="姓名" value="Vue" placeholder="请输入名字" v-on:focus.native="dosomething"></base-input>
</div>
<script>
    Vue.component('base-input', {
        inheritAttrs: false,
        props: ['label', 'value'],
        template: `
            <label>
                {{ label }}
                <input
                    v-bind="$attrs"
                    v-bind:value="value"
                >
            </label>
        `
    });
    new Vue({
        el: '#app',
        methods: {
            dosomething() {
                console.log('y');
            }
        }
    });
</script>

案例三:不使用native,使用$listeners(将所有的事件监听器指向这个组件的某个特定的子元素),可以触发dosomething函数

<div id="app">
    <base-input label="姓名" value="Vue" placeholder="请输入名字" v-on:focus="dosomething"></base-input>
</div>
<script>
    Vue.component('base-input', {
        inheritAttrs: false,
        props: ['label', 'value'],
        template: `
            <label>
                {{ label }}
                <input
                    v-bind="$attrs"
                    v-bind:value="value"
                    v-on="$listeners"
                >
            </label>
        `
    });
    new Vue({
        el: '#app',
        methods: {
            dosomething() {
                console.log('y');
            }
        }
    });
</script>

案例四:重新定义$listeners,覆盖原有监听行为

<div id="app">
    <base-input label="姓名" value="Vue" placeholder="请输入名字" v-on:focus="dosomething"></base-input>
</div>
<script>
    Vue.component('base-input', {
        inheritAttrs: false,
        props: ['label', 'value'],
        computed: {
            listeners: function() {
                var vm = this
                // `Object.assign` 将所有的对象合并为一个新对象
                return Object.assign({},
                    // 我们从父级添加所有的监听器
                    this.$listeners,
                    // 然后我们添加自定义监听器,
                    // 或覆写一些监听器的行为
                    {
                        focus: function (event) {
                            console.log('z');
                        }
                    }
                )
            }
        },
        template: `
            <label>
                {{ label }}
                <input
                    v-bind="$attrs"
                    v-bind:value="value"
                    v-on="listeners"
                >
            </label>
        `
    });
    new Vue({
        el: '#app',
        methods: {
            dosomething() {
                console.log('y');
            }
            }
        });
    </script>

总结:一切都是为了支持组件自定义原生事件


洪定伦
604 声望14 粉丝