【Vue】组件封装小技巧 — 利用$attrs和v-bind接收传递未定义的属性

本文介绍了如何在Vue.js中使用$attrs和v-bind进行组件的二次封装,以传递父组件的属性和事件,以及如何在组件内添加额外样式和功能。通过实例演示了如何在elementUI组件上进行样式修改并保持灵活性。
摘要由CSDN通过智能技术生成

使用介绍

在Vue.js中,$attrsv-bind可以用于组件的二次封装,以在封装的组件中传递父组件的属性和事件。这对于创建高度可定制的通用组件非常有用。

下面是一些示例代码:

假设你有一个名为MyButton的自定义按钮组件,它接受一些常见的按钮属性(如disabledtype等),然后你想将其二次封装,以添加一些额外的样式和功能。以下是如何使用$attrs和v-bind来实现这个目标的示例:

<template>
  <button
    class="my-custom-button"  <!-- 添加自定义样式 -->
    v-bind="$attrs"  <!-- 将父组件传递的属性绑定到这个按钮 -->
    :class="{ 'my-special-class': special }"  <!-- 添加额外的类名 -->
    @click="handleClick"  <!-- 添加点击事件处理函数 -->
  >
    <slot></slot>  <!-- 保留插槽内容 -->
  </button>
</template>

<script>
export default {
  props: {
    special: Boolean,
  },
  methods: {
    handleClick() {
      // 处理点击事件
      this.$emit('click');
    },
  },
};
</script>

在这个示例中,MyButton组件接受一个名为special的属性,这个属性用于指定是否要添加额外的特殊样式。$attrs用于将所有未明确声明的父组件传递的属性绑定到按钮元素上。然后,我们使用:class来添加额外的类名,使用@click来添加点击事件处理函数,同时保留插槽内容以确保父组件可以插入任何需要的内容。

在父组件中,你可以像使用普通按钮一样使用MyButton组件,并将需要的属性和事件传递给它:

<template>
  <div>
    <MyButton
      disabled="true"
      type="submit"
      special="true"
      @click="handleSpecialClick"
    >
      Click me
    </MyButton>
  </div>
</template>

<script>
import MyButton from './MyButton.vue';

export default {
  components: {
    MyButton,
  },
  methods: {
    handleSpecialClick() {
      // 处理特殊按钮的点击事件
    },
  },
};
</script>

通过这种方式,你可以将MyButton组件进行二次封装,以添加额外的功能和样式,同时仍然能够从父组件传递属性和事件。这种方法可以创建更加灵活和可定制的组件,适应不同的需求。

需要注意!!!

如果不设置 inheritAttrs: false,则属性如下所示
在这里插入图片描述
而设置 inheritAttrs: false可以来避免这种行为,这样后将不继承未明确声明的属性。clearable属性也就不见了。
在这里插入图片描述

使用案例

组件二次封装,修改 elementUI 的样式:

<template>
  <el-date-picker v-model="innerVal" v-bind="$attrs"></el-date-picker>
</template>
<script>
export default {
  name: 'myDatePicker',
  components: {},
  props: {},
  inheritAttrs: false,  // 不继承未明确声明的属性
  data () {
    return {
      innerVal: this.$attrs.value //这里获取 v-model 内容
    }
  },
  methods: {},
  created () { },
  mounted () { }
}
</script>
<style lang="less" scoped>
/deep/.el-input__inner {
  background: #071e52;
  border: 2px solid #36a6f1;
  border-radius: 2px;
  color: #fff;
  cursor: pointer;
  height: inherit;
}
/deep/.el-input__icon {
  line-height: 27px;
}
</style>

具体使用:

<!-- 这里的selectDate也就是组件中所写的 this.value -->
<my-date-picker v-model="selectDate" type="date" placeholder="选择日期"
                          style="margin-left: 15px;height: 27px;" :clearable="false">
</my-date-picker>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
组件封装时,使用`v-bind="$attrs"`可以将父组件中除了子组件自身props以外的所有属性绑定到子组件的根元素上。这在组件封装时非常有用,因为它允许子组件接收来自父组件的所有属性,同时又不需要将这些属性全部手动定义为props,减少了重复劳动。 举个例子,假设我们有一个组件`MyButton`,它包含一个`button`元素和一些自定义props。我们想让这个组件能够接收来自父组件的所有属性,并将它们绑定到`button`元素上。这时,我们可以这样写: ```vue <template> <button v-bind="$attrs" :class="['my-button', { disabled: isDisabled }]" @click="onClick"> <slot></slot> </button> </template> <script> export default { name: 'MyButton', props: { isDisabled: { type: Boolean, default: false } }, methods: { onClick() { this.$emit('click'); } } }; </script> ``` 在这个例子中,我们使用了`v-bind="$attrs"`将所有来自父组件属性绑定到了`button`元素上。同时,我们定义了一个名为`isDisabled`的prop,用于控制按钮是否可用。我们还定义了一个点击事件`onClick`,当按钮被点击时触发,并通过`$emit`方法向外部发送`click`事件。 这样,我们就可以在父组件中这样使用`MyButton`组件: ```vue <template> <div> <MyButton class="btn btn-primary" :disabled="isLoading" @click="onButtonClick"> {{ isLoading ? 'Loading...' : 'Click me!' }} </MyButton> </div> </template> <script> import MyButton from './MyButton.vue'; export default { name: 'MyPage', components: { MyButton }, data() { return { isLoading: false }; }, methods: { onButtonClick() { this.isLoading = true; // do something... } } }; </script> ``` 在这个例子中,我们将`MyButton`作为子组件引入,并给它传递了一个名为`isLoading`的属性,用于控制按钮是否处于加载状态。此外,我们还可以传递其他任何属性,例如`class`、`style`等,这些属性都会被正确地绑定到`button`元素上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值