vue2 二次封装element 组件,继承组件原属性,事件,插槽 示例;多组件事件处理

本文介绍了如何在Vue.js中封装组件时使用v-bind=$attrs、v-on=$listeners和inheritAttrs=false选项,以确保属性和事件传递,并展示了如何处理多组件事件以及自定义el-input的属性和插槽。
摘要由CSDN通过智能技术生成

目录

测试页面代码

组件的封装代码

v-bind="$attrs"

v-on="$listeners"

inheritAttrs: false

多组件事件处理

组件实例代码

测试页面代码



测试页面代码

这里主要记录如何封装element的el-input

并且封装后具有el-input原本的属性 事件 插槽

下面为测试页面即组件调用

<script>
import CustomInput from '@/components/CustomInput.vue';

export default {
    name: 'TestPage',
    components: { CustomInput },
    data() {
        return {
            testInput: 'Hello World'
        }

    },

};
</script>

<template>
    <div style='margin-left: 50px;width: 600px'>
        <!--            测试代码-->
        <CustomInput v-model='testInput' placeholder='Hello World'>
            <template slot='append'>
                <el-button>搜索</el-button>
            </template>
        </CustomInput>
    </div>
</template>

<style scoped lang='scss'>

</style>

组件的封装代码

先看看实际效果和是否生效

在 Vue.js 中,v-bind="$attrs"v-on="$listeners"inheritAttrs: false 是与组件的属性 (props) 和事件监听器相关的选项,它们通常用于自定义组件中以确保父组件传递的所有属性和事件能够正确地应用到子组件上。以下是每个选项的详细解释:

v-bind="$attrs"

  • v-bind="$attrs" 是一个 Vue 指令,用于将父组件传递给子组件的非 prop 属性 (即普通 HTML 属性和自定义属性,但不包括 class 和 style) 绑定到子组件的根 DOM 元素上。
  • 使用 $attrs 变量可以获得父组件传递下来的所有属性 (除了通过 props 定义的属性之外),然后一次性绑定到内部元素上。

v-on="$listeners"

  • v-on="$listeners" 也是一个 Vue 指令,用于添加父组件在子组件上设置的所有事件监听器。
  • $listeners 对象包含了在子组件上侦听的所有事件 (这些事件还没有配置相应的方法或尚未作为 prop 被识别)。使用这个指令可以方便地将所有父组件绑定的事件监听器添加到子组件的根 DOM 元素上。

inheritAttrs: false

  • inheritAttrs: false 是一个组件选项,使得所有的非 prop 属性 (比如 classstyle 等) 不会默认绑定到组件的根 DOM 元素上。
  • 默认情况下,Vue 会将任何不被识别为 prop 的属性自动添加到组件的根元素上。当你不希望建立这种默认行为时(比如你希望手动确定哪些属性应该被添加到哪个元素上),可以设置 inheritAttrs: false

此处为了继承原组件的所有插槽

需要依次声明它们

<template>
    <el-input
        v-bind="$attrs"
    v-on="$listeners"
    :value="inputValue"
    @input="updateValue"
    >
        <!-- 默认插槽 -->
        <slot></slot>
        <!-- 具名插槽 -->
        <slot name="prepend" slot="prepend"></slot>
        <slot name="append" slot="append"></slot>
        <slot name="prefix" slot="prefix"></slot>
        <slot name="suffix" slot="suffix"></slot>
    </el-input>
</template>

<script>
export default {
    name: 'CustomInput',

    // 使用 inheritAttrs: false 选项,避免 attribute 被自动应用到组件根元素上
    inheritAttrs: false,

    props: ['value'], // 如果需要处理 value 属性,需要显式声明

    computed: {
        inputValue: {
            get() {
                return this.value;
            },
            set(value) {
                this.$emit('update:value', value);
            }
        }
    },

    methods: {
        updateValue(value) {
            this.$emit('input', value); // 当输入时触发 input 事件,并将新值通过事件发送给父组件
        }
    }
};
</script>

多组件事件处理

下面示例如何处理一个组件中封装了多个子组件并且有相同子组件时,如何处理相同子组件的事件。

组件<CustomInput.vue>实例代码

此组件中有两个<el-button 组件,需要处理两个el-button的click事件

<template>
    <el-input
        v-bind="$attrs"
    v-on="$listeners"
    :value="inputValue"
    @input="updateValue"
    >
        <!-- 默认插槽 -->
        <slot></slot>
        <!-- 具名插槽 -->
        <slot name="prepend" slot="prepend"><el-button @click="handleClickA">搜索A</el-button></slot>
        <slot name="append" slot="append"><el-button @click="handleClickB">搜索B</el-button></slot>
        <slot name="prefix" slot="prefix"></slot>
        <slot name="suffix" slot="suffix"></slot>
    </el-input>
</template>

<script>
export default {
    name: 'CustomInput',

    // 使用 inheritAttrs: false 选项,避免 attribute 被自动应用到组件根元素上
    inheritAttrs: false,

    props: ['value'], // 如果需要处理 value 属性,需要显式声明

    computed: {
        inputValue: {
            get() {
                return this.value;
            },
            set(value) {
                this.$emit('update:value', value);
            }
        }
    },

    methods: {
        updateValue(value) {
            this.$emit('input', value); // 当输入时触发 input 事件,并将新值通过事件发送给父组件
        },
        handleClickA() {
            this.$emit('click-a');
        },
        handleClickB() {
            this.$emit('click-b');
        }
    }
};
</script>
测试页面代码
<script>
import CustomInput from '@/components/CustomInput.vue';

export default {
    name: 'TestPage',
    components: { CustomInput },
    data() {
        return {
            testInput: 'Hello World'
        }

    },
    methods: {
        clickA() {
            console.log('click A');
            this.testInput = '.........click A';
        },
        clickB() {
            console.log('click B');
            this.testInput = '.........click B';
        }
    }

};
</script>

<template>
    <div style='margin-left: 50px;width: 600px'>
        <!--            测试代码-->
        <CustomInput v-model='testInput' placeholder='Hello World' @click-a="clickA" @click-b="clickB">
        </CustomInput>
    </div>
</template>

<style scoped lang='scss'>

</style>

测试运行

成功触发两个组件的事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Franciz小测测

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

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

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

打赏作者

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

抵扣说明:

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

余额充值