这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

先来看一个业务需求:

项目经常会遇到产品经理要求你做某组件一样的功能,还要在它的基础上增加东西。如何只用少量代码高效的二次封装组件呢?

例如我要做一个element-ui的input组件进行封装,以下是封装要求:

  1. 对el-input组件增加某些定制功能
  2. 调整el-input的原有css样式
  3. 封装后不得更改原有el-input的所有功能

文章最后会给出element-ui的input组件二次封装的示例。

先来介绍一下attrs吧

在 Vue2 中,attr 是指组件接收的 HTML 特性(attribute),通过 props 的方式传递给子组件。而在 Vue3 中,attr 的概念被引入了 Composition API 中,并且被用于管理各种配置项。

下面介绍一些 attr 的使用技巧:

Vue2 中使用 attr

  1. 使用 v-bind指令绑定 HTML 属性

在 Vue2 中,如果想将父组件传递的 HTML 属性传递给子组件进行使用,可以在子组件中通过 props 接收参数,并使用 v-bind 指令将其绑定到子组件的 HTML 元素上。例如:

<template>
<div class="demo-component" :style="styleObject">{{ message }}</div>
</template> <script>
export default {
name: "DemoComponent",
props: {
message: String,
styleObject: Object,
},
};
</script>

在父组件中使用该组件时,可以通过 v-bind 指令将 HTML 特性传递给子组件:

<template>
<demo-component message="Hello, world!" :style-object="{ color: 'red' }"></demo-component>
</template>
  1. 使用 $attrs 对象传递所有未被 props 所接收的特性

在 Vue2 中,可以通过 $attrs 对象获取父组件传递给子组件但未被 props 所接收的特性,从而实现组件复用和扩展的目的。例如:

<template>
<div class="demo-component" :style="styleObject" v-bind="$attrs">{{ message }}</div>
</template> <script>
export default {
name: "DemoComponent",
props: {
message: String,
styleObject: Object,
},
};
</script>

在父组件使用该组件时,可以像平常传递普通的 HTML 特性一样,同时还可以传递一些自定义的特性:

<template>
<demo-component
message="Hello, world!"
:style-object="{ color: 'red' }"
custom-attribute="something"
></demo-component>
</template>

在子组件中,可以通过 this.$attrs 属性获取父组件传递给子组件但未被 props 所接收的特性:

console.log(this.$attrs.customAttribute); // 输出:something

Vue3 中使用 attr

在 Vue3 中,可以通过 setup 函数中的第二个参数 context 来访问该组件的配置选项,其中包括了所有未被 props 所接收的特性:

<template>
<div class="demo-component" :style="styleObject" v-bind="$attrs">{{ message }}</div>
</template> <script>
export default {
name: "DemoComponent",
props: {
message: String,
styleObject: Object,
},
setup(props, context) {
console.log(context.attrs.customAttribute); // 输出:something
},
};
</script>

在 setup 函数中,通过 context.attrs 获取父组件传递给子组件但未被 props 所接收的特性。

除了 $attrs,Vue3 中还引入了 $props 对象,它是一个由 props 组成的响应式对象,在组件内部通过解构赋值可以快速地访问 props 的属性值:

<template>
<div class="demo-component" :style="styleObject">{{ message }}</div>
</template> <script>
export default {
name: "DemoComponent",
props: {
message: String,
styleObject: Object,
},
setup(props) {
const { message, styleObject } = props;
console.log(message, styleObject); // 输出:Hello, world! { color: 'red' }
},
};
</script>

在 setup 函数中,通过解构赋值可以快速地访问 props 的属性值。

利用 $attrs$listeners 可以在二次封装 element-ui 组件时非常方便地传递组件属性和事件。

示例代码

下面以 el-input 组件为例,演示一下vue2中如何高效地二次封装 element-ui 组件,从而达到只用少量代码在原有组件上升级的效果:

<template>
<el-input v-bind="$attrs" v-on="$listeners" :class="{ 'is-invalid': isError }">
<template v-if="isError" #append>
<i class="el-input__icon el-icon-circle-close"></i>
</template>
</el-input>
</template> <script>
export default {
name: "MyInput",
inheritAttrs: false,
props: {
isError: Boolean, // 是否显示错误提示
},
};
</script>
<style scoped lang="scss">
//这是写自己的样式内容
</style>

解释一下上面代码的内容吧:

  1. 使用 v-bind="$attrs" 将父级组件所有的未被 props 所接收的特性绑定到 el-input 组件上。

  2. 使用 v-on="$listeners" 将父级组件传递给当前组件的所有事件监听器绑定到 el-input 组件上。

  3. 在模板中可以很方便地使用 isError 属性来扩展组件,并且不需要在父组件中再次定义。

需要注意的是,由于 element-ui 组件本身也包含了一些默认的属性和事件,因此需要在组件中设置 inheritAttrs: false,以避免传递 element-ui 组件自带的属性和事件。

本文转载于:

https://juejin.cn/post/7221357811288260664

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--Vue中的$attrs你真的会用吗?的更多相关文章

  1. 记录vue中一些有意思的坑

    记录vue中一些有意思的坑 'message' handler took 401ms 在出现这个之前,我一直纠结于 是如何使用vue-router或者不使用它,通过类似的v-if来实现.结果却出现这个 ...

  2. vue中的$attrs属性和inheritAttrs属性

    一.vue中,默认情况下,调用组件时,传入一些没有在props中定义的属性,会把这些“非法”属性渲染在组件的根元素上(有一些属性除外),而这些“非法”的属性会记录在$attrs属性上. 二.如何控制不 ...

  3. [记录] Vue中的dom操作

    使用过Vue的同学都应该有这样一个感觉,在vue中页面是基于数据驱动的,不需要我们自己操作dom,框架帮我们完成了这一步,事实上Vue官方也建议我们这样做 在绝大多数情况下是不需要操作dom就可以完成 ...

  4. 新人 记录VUE中分页实现

    关于函数传值 this.getPurchaseHistoryData(index, num,timeType);第一位是显示的页数,第二是控制首页4上一页-1下一页是2末页是5 第三是是对昨天是1,今 ...

  5. vue 中 命名视图的用法

    今天主要记录  vue中命名视图的用法 先奉上官网网址:https://router.vuejs.org/zh/guide/essentials/named-views.html 一般情况下,一个页面 ...

  6. 问题记录---关于posiition脱离文档流及vue中this.$route信息

    1.关于position:fixed会脱离文档流 简单例子: 原型有三个div盒子: 将剥box1设置为position:fixed后 从上图可以看出:box1脱离了文档流,且层级显示优先于正常文档, ...

  7. 记录下vue 中引用echarts 出现 "TypeError: Cannot read property 'getAttribute' of undefined"问题

    今天做项目,用echarts展示数据 ,自己测试 先测试 了下.写的代码html: <div ref="myChart" style="height:300px;w ...

  8. 在 Vue 中使用 Typescript

    前言 恕我直言,用 Typescript 写 Vue 真的很难受,Vue 对 ts 的支持一般,如非万不得已还是别在 Vue 里边用吧,不过听说 Vue3 会增强对 ts 的支持,正式登场之前还是期待 ...

  9. Vue中组件间通信的方式

    Vue中组件间通信的方式 Vue中组件间通信包括父子组件.兄弟组件.隔代组件之间通信. props $emit 这种组件通信的方式是我们运用的非常多的一种,props以单向数据流的形式可以很好的完成父 ...

  10. vue中动态引入图片为什么要是require, 你不知道的那些事

    相信用过vue的小伙伴,肯定被面试官问过这样一个问题:在vue中动态的引入图片为什么要使用require 有些小伙伴,可能会轻蔑一笑:呵,就这,因为动态添加src被当做静态资源处理了,没有进行编译,所 ...

随机推荐

  1. Linux-nmon系统监控工具

    一.Nmon介绍 Nmon得名于 Nigel 的监控器,是IBM的员工 Nigel Griffiths 为 AIX 和 Linux 系统开发的,使用 Nmon 可以很轻松的监控系统的 CPU.内存.网 ...

  2. Hadoop-Operation category READ is not supported in state standby 故障解决

    在查询hdfs时或者执行程序向hdfs写入数据时遇到报错:Operation category READ is not supported in state standby 意思是:该主机状态为待机, ...

  3. 《AI驱动下的开发者新生态》-2024长沙.NET技术社区活动-诚邀大家报名

    回顾 2019年初,在.NET中文社区及包括苏州.广州.深圳等地区社区等大力推动.在众多企业的大力支持下,长沙地区的开发者们发起成立了长沙.NET技术社区,并组织了<2019年长沙开发者技术大会 ...

  4. [刺客伍六七&黑客] 魔刀千刃evilblade的使用手册与开源

    0x00 前言 2023.8.15 夜里 非常欢迎使用我的魔刀千刃,并且欢迎各位师傅对我的开源代码进行指导! -–Offense without defense, unparalleled in th ...

  5. 同一份代码怎能在不同环境表现不同?记一个可选链因为代码压缩造成的bug

    壹 ❀ 引 某一天,CSM日常找我反馈客户紧急工单,说有一个私有部署客户升级版本后,发现一个功能使用不太正常.因为我们公司客户分为两种,一种是SaaS客户,客户侧使用的版本被动跟随主版本变动,而私有部 ...

  6. JS leetcode 拥有最多糖果的孩子 题解分析,六一快乐。

    壹 ❀ 引 今天是六一儿童节,leetcode的每日一题也特别可爱,那么今天我们来解决一道与糖果有关的问题,题目来源1431. 拥有最多糖果的孩子,题目描述如下: 给你一个数组 candies 和一个 ...

  7. NC204871 求和

    题目链接 题目 题目描述 已知有 \(n\) 个节点,有 \(n-1\) 条边,形成一个树的结构. 给定一个根节点 \(k\) ,每个节点都有一个权值,节点i的权值为 \(v_i\) . 给 \(m\ ...

  8. nginx 剔除请求参数 $args 变量中任意指定参数之万金油

    剔除任意指定参数配置 只需要修改需要剔除的参数key(如:redirectUrl) #剔除$args中的redirectUrl 参数 server { listen 80; server_name w ...

  9. STM32 printf 方法重定向到串口UART

    在嵌入式系统中调试代码是很麻烦的一件事, 如果能方便地输出调试信息(与调试者交互), 能使极大加快问题排查的过程. 串口在嵌入式领域是一个比较重要的通讯接口. 因为没有显示设备, 在单片机的程序里调用 ...

  10. 【OpenGL ES】光影(光照与阴影)效果

    1 前言 ​ Blinn改进的冯氏光照模型 中只展示了光照效果,本文将进一步展示阴影效果. ​ 绘制阴影,需要用到深度纹理,即从光源角度看模型并绘制一张纹理图,纹理图的颜色代表了模型上的点离光源的深度 ...