组件二次封装,通过属性事件透传,插槽使用,组件实例方法的绑定,深入理解 Vue.js 组件扩展与插槽

透传,插槽,组件实例方法的绑定,深入理解 Vue.js 组件扩展与插槽

前言

        Vue.js 提供了强大的组件化系统,允许开发者构建可复用、可组合的UI组件。在实际项目中,直接使用第三方库提供的基础组件(如Element UI)往往不能完全满足定制化需求。这时,对这些基础组件进行二次封装,使其更加符合项目需求就显得尤为重要。

目标组件:hsk-input

        本示例的目标是创建一个名为HSK-Input的组件,它基于Element UIel-input,但增加了额外的功能和灵活性,比如自动绑定el-input的所有实例方法,并提供一个自定义方法customMethod

核心知识点

属性与事件的透传

        v-bind="$attrs" v-on="$listeners":这是Vue中用于透传所有未被组件自身声明使用的属性和事件的关键技巧。$attrs包含所有没有被作为props声明的属性,$listeners则包含了父组件传递给当前组件的所有事件监听器。这样,我们就可以无需明确列出所有可能的属性和事件,而让HSK-Input能够自由接受并传递任何来自父组件的额外配置或交互逻辑。

 <el-input v-bind="$attrs" v-on="$listeners" ref="inputRef"></el-input>

使用插槽(Slots)

        v-for="(_, slotName) in $slots" 和 v-slot:[slotName]:这部分代码展示了如何动态地遍历并渲染传递给组件的所有插槽内容。Vue的插槽机制允许我们在封装组件时保留高度的灵活性,即用户可以在封装后的组件内部插入任意内容或组件,这对于保持UI组件通用性可定制性至关重要。

<el-input v-bind="$attrs" v-on="$listeners" ref="inputRef"><template v-for="(_, slotName) in $slots" v-slot:[slotName] ><slot :name="slotName"></slot></template></el-input>

父组件使用

<hsk-inputv-model="inputValue"placeholder="请输入"ref="customInputRef"@focus="handleFocus"type="text"clearable><template v-slot:prepend><span>http://</span></template><template v-slot:suffix><i class="el-input__icon el-icon-date"></i></template><template v-slot:append><el-button @click="handleButtonClick">Submit</el-button></template></hsk-input>

其子组件中打印this.$slots,就会出现父组件传递过来的插槽,只需要遍历一下this.$slots即可使用。
在这里插入图片描述
使用效果:
组件二次封装,通过属性事件透传,插槽使用,组件实例方法的绑定,深入理解 Vue.js 组件扩展与插槽

组件实例方法的绑定

        mounted() 钩子中的方法绑定:通过遍历el-input实例的方法并绑定到HSK-Input组件上,我们确保了所有原生输入框的功能都能在封装组件中直接调用。这种方法利用了JavaScriptbind()函数来改变函数执行时的上下文(this),使得在封装组件外部也能访问和控制基础组件的内部方法。

子组件添加ref,然后进行实例方法的绑定

<el-input v-bind="$attrs" v-on="$listeners" ref="inputRef"><template v-for="(_, slotName) in $slots" v-slot:[slotName]><slot :name="slotName"></slot></template></el-input>

打印this.$refs.inputRef,可以看出一些el-input自带的属性方法都在$refs.inputRef
组件二次封装,通过属性事件透传,插槽使用,组件实例方法的绑定,深入理解 Vue.js 组件扩展与插槽
主要代码:

<template><div><el-input v-bind="$attrs" v-on="$listeners" ref="inputRef"><template v-for="(_, slotName) in $slots" v-slot:[slotName]><slot :name="slotName"></slot></template></el-input></div>
</template><script>
export default {name: "hsk-input",mounted() {this.$nextTick(() => {// 在 mounted 钩子中通过遍历绑定 el-input 的实例方法到 CustomInput 上const inputRef = this.$refs.inputRef;console.log("$slots",inputRef);const methodsToBind = Object.getOwnPropertyNames(Object.getPrototypeOf(inputRef));// 遍历子组件中用到的了el-input的所有方法施礼道customInput上面去methodsToBind.forEach((method) => {if (typeof inputRef[method] === "function") {this[method] = inputRef[method].bind(inputRef);}});// 如果需要添加自定义方法,可以在这里定义this.customMethod = () => {console.log("This is a custom method in CustomInput component");};});},created() {},methods: {},
};
</script>

父组件使用,并通过 @focus="handleFocus"调用子组件中elementui自带的focus方法的方法

<template><div><hsk-inputv-model="inputValue"placeholder="请输入"ref="customInputRef"@focus="handleFocus"type="text"clearable></hsk-input></div>
</template><script>
import HskInput from "../package/hsk-input/index.vue";
export default {components: {HskInput,},data() {return {inputValue: "",};},methods: {handleButtonClick() {console.log("handleButtonClick");},handleFocus() {console.log("我是获取焦点");},},
};
</script>

组件二次封装,通过属性事件透传,插槽使用,组件实例方法的绑定,深入理解 Vue.js 组件扩展与插槽

代码解释

const inputRef = this.$refs.inputRef;其中this.$refs是一个对象,保存着模板中使用ref属性定义的引用信息。这里通过inputRef获取到了el-input组件的DOM引用。

const methodsToBind = Object.getOwnPropertyNames(Object.getPrototypeOf(inputRef));这段代码用来获取inputRef(即el-input组件实例)的所有可枚举属性名,包括原型链上的方法。这样做是为了之后遍历并绑定这些方法到当前组件实例上。

methodsToBind.forEach((method) => { ... })遍历从inputRef获取到的所有方法名称,对于每个方法,检查是否为函数类型。如果是函数,则通过bind(inputRef)将其绑定到当前组件实例(this)上。这意味着你可以在自定义组件实例上调用这些原本属于el-input的方法,而不需要直接操作DOM或引用el-input的实例,提高了代码的抽象层次和可维护性。

自定义方法的添加

        customMethod:除了透传和绑定原有方法外,我们还可以在封装组件中添加自定义功能,进一步增强组件的能力。这展示了组件封装不仅仅是简单的“转发”,更是对原始功能的拓展和创新。

this.customMethod = () => { ... }定义了一个新的方法customMethod作为自定义组件的扩展。这个方法简单地打印一条消息到控制台,演示了如何在封装组件时添加额外的业务逻辑或功能。

mounted() {this.$nextTick(() => {.........// 如果需要添加自定义方法,可以在这里定义this.customMethod = () => {console.log("This is a custom method in CustomInput component");};});},

实践意义

        通过这样的封装,HSK-Input组件不仅继承了el-input的所有特性,还提供了额外的便利性和可扩展性。开发者在使用这个组件时,不仅可以像使用原生el-input那样配置和交互,还能享受到自定义方法带来的便利,以及通过插槽灵活插入内容的能力,大大提升了开发体验和维护性。

结语

        组件封装是Vue开发中的一个重要实践,它要求开发者不仅要熟悉Vue的基础知识,还要具备良好的设计思维,以实现组件的高复用性和易用性。本文通过HSK-Input组件的实例,展示了如何通过属性透传、事件绑定、插槽使用以及方法扩展等技术点,高效且优雅地完成组件的封装与升级。希望这一实践能为你的Vue项目开发带来新的启示和帮助。

所有代码

子组件所有代码:

<template><div><el-input v-bind="$attrs" v-on="$listeners" ref="inputRef"><template v-for="(_, slotName) in $slots" v-slot:[slotName]><slot :name="slotName"></slot></template></el-input></div>
</template><script>
export default {name: "hsk-input",mounted() {this.$nextTick(() => {// 在 mounted 钩子中通过遍历绑定 el-input 的实例方法到 CustomInput 上const inputRef = this.$refs.inputRef;console.log("$slots",inputRef);const methodsToBind = Object.getOwnPropertyNames(Object.getPrototypeOf(inputRef));// 遍历子组件中用到的了el-input的所有方法施礼道customInput上面去methodsToBind.forEach((method) => {if (typeof inputRef[method] === "function") {this[method] = inputRef[method].bind(inputRef);}});// 如果需要添加自定义方法,可以在这里定义this.customMethod = () => {console.log("This is a custom method in CustomInput component");};});},created() {},methods: {},
};
</script>

父组件所有代码

<template><div><hsk-inputv-model="inputValue"placeholder="请输入"ref="customInputRef"@focus="handleFocus"type="text"clearable><template v-slot:prepend><span>http://</span></template><template v-slot:suffix><i class="el-input__icon el-icon-date"></i></template><template v-slot:append><el-button @click="handleButtonClick">Submit</el-button></template></hsk-input></div>
</template><script>
import HskInput from "../package/hsk-input/index.vue";
export default {components: {HskInput,},data() {return {inputValue: "",};},mounted() {this.$nextTick(() => {console.log("this.$refs.customInputRef", this.$refs.customInputRef);});},methods: {handleButtonClick() {console.log("handleButtonClick");},handleFocus() {console.log("我是获取焦点");},},
};
</script><style>
</style>

最终效果:

组件二次封装,通过属性事件透传,插槽使用,组件实例方法的绑定,深入理解 Vue.js 组件扩展与插槽

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Internet Download Manager(IDM6.41)软件下载-详细安装教程视频

Internet Download Manager有一个智能下载逻辑加速器&#xff0c;具有智能动态文件分割和安全的多部分下载技术&#xff0c;可以加速下载。与其他下载加速器和管理器不同&#xff0c;Internet下载管理器在下载开始之前对文件进行分段&#xff0c;而Internet下载管理器在下载过程…

用TensorRT-LLM进行LLama的推理和部署

Deploy an AI Coding Assistant with NVIDIA TensorRT-LLM and NVIDIA Triton | NVIDIA Technical BlogQuick Start Guide — tensorrt_llm documentation (nvidia.github.io) 使用TensorRT-LLM的源码&#xff0c;来下载docker并在docker里编译TensorRT-LLM&#xff1b; 模型…

Android Calculator2源码分析与修改

private CalculatorDisplay mDisplay; private Symbols mSymbols new Symbols(); -41,6 44,7 class Logic { private int mLineLength 0; private static final String INFINITY_UNICODE “\u221e”; private static final String ZMS_NUMBER “55555”; public stat…

Linux构建本地时间同步ntp

环境介绍&#xff1a; 主机名 IP地址 系统发行版 环境 Node01 192.168.100.102 Centos 7.4 可联网、已关闭防火墙selinux Node02 192.168.100.103 Centos 7.4 已关闭防火墙selinux 1.主节点同步阿里云标准时间 在保证连接外网的情况下&#xff0c;同步阿里服务器的…

Spring的SmartLifecycle可以没用过,但没听过就不好了! - 第517篇

历史文章&#xff08;文章累计500&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

three.js开发3D地图记录(一)

关键代码部分&#xff1a; <template><div class"center-map-box" id"contant"></div> </template><script> import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/control…

springboot小型超市商品展销系统-计算机毕业设计源码01635

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

EIQ-ABC 分析法在配送中心储位分配中的应用

配送中心运作效率的高低主要取决于仓储业务流程的作业效率&#xff0c;在配送作业流程中&#xff0c;储位分配的是否合理性成为影响配送运作效率的重要因素。为实现储位的合理分配&#xff0c;提出通过对订单信息的分析&#xff0c;并应用 EIQ-ABC 分析法&#xff0c;以此实现缩…

白酒:茅台镇白酒的品牌合作与跨界营销案例

云仓酒庄豪迈白酒&#xff0c;作为茅台镇的知名品牌&#xff0c;在品牌合作与跨界营销方面也有着杰出的表现。通过与不同领域品牌的合作&#xff0c;豪迈白酒进一步拓宽了市场渠道&#xff0c;提升了品牌曝光度和影响力。 首先&#xff0c;云仓酒庄豪迈白酒与品质餐产品牌的合作…

量子革命 “不负众望“!即将见证首个商业量子应用案例?

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨沛贤/浪味仙 排版丨沛贤 深度好文&#xff1a;1000字丨5分钟阅读 摘要&#xff1a;雀巢、联合利华和德国能源巨头 E.ON 表示&#xff0c;距离首个商用量子案例出现可能只需三年时间。 近…

tracetcp下载 安装 使用 网络工具 windows trace工具 tcp协议

省流 Tracetcp是一个类似于Tracert的工具&#xff0c;使用如下&#xff1a; 1. 安装winpcap &#xff0c; 下载链接&#xff1a;WinPcap Download 2.下载tracetcp软件&#xff0c;下载链接&#xff1a; https://github.com/0xcafed00d/tracetcp/releases 命令&#xff1a;…

期末考试老师怎样发成绩

期末成绩的公布&#xff0c;总是让老师感到焦虑。成绩&#xff0c;这一张张的数字&#xff0c;承载着学生一学期的努力&#xff0c;也牵动着家长们的心。 传统的成绩公布方式&#xff0c;写成绩条让学生带回家&#xff0c;或是通过私发家长的方式&#xff0c;都存在一定的弊端。…

六、Nginx-正向代理和反向代理

目录 一、正向代理 1、参数详解 2、常用变量详解 3、配置示例 二、反向代理 三、 Nginx的安全控制 1、如何使用SSL对流量进行加密 2、nginx添加SSL的支持 3、 Nginx的SSL相关指令 &#xff08;1&#xff09;ssl &#xff08;2&#xff09;ssl_certificate &#xff0…

【Kaggle量化比赛】Top讨论

问: 惊人的单模型得分,请问您使用了多少个特征来获得如此高的得分?我也在使用LGB模型。 答 235个特征(180个基本特征+滚动特征) 问: 您是在使用Polars进行特征工程还是仅依赖于Pandas+Numba/多进程?即使进行了Numba优化,我也发现当滚动特征过多时,推理速度会非常慢。在…

淘宝商品评论API接口测试实例(获取淘宝商品评论,翻页展示、支持并发)

item_review-获得淘宝商品评论 测试页 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop…

设计灵感源泉!7个令人赞叹的网页界面设计展示

网页的界面设计主要是指视觉设计和风格设计。高质量的界面更容易吸引用户的注意力&#xff0c;从而更准确地向用户传达信息。对于设计师来说&#xff0c;他们需要从高质量的作品中获得稳定的灵感&#xff0c;以帮助他们更高效地实现设计目标。在本文中&#xff0c;梳理了7个高质…

人工智能抢走了他们的工作。现在他们得到报酬,让它听起来像人类

人工智能抢走了他们的工作。现在他们得到报酬&#xff0c;让它听起来像人类 如果你担心人工智能会如何影响你的工作&#xff0c;那么广告文案的世界或许能让你窥见未来。 作家本杰明米勒(化名)在2023年初非常红火。他领导了一个由60多名作家和编辑组成的团队&#xff0c;发表博…

一文了解Java 中的String、StringBuffer 与StringBuilder

String结构剖析 String是final 类&#xff0c;不能被其他的类继承 String有属性private final char vaLue[]; 用于存放字符串内容 注意: value 是个final类型&#xff0c; 不可以修改: 即value不能指向新的地址&#xff0c;但是单个字符内容是可以变化 两种创建String对象的区…

24执业药师报名时间汇总及报名流程!

24执业药师报名时间汇总&#xff01;报名流程&#xff01; &#x1f55b;️各省市报名时间汇总&#xff08;共9地&#xff09; 西藏&#xff1a;6月29日-7月8日 新疆&#xff1a;6月25日10:30-7月9日19:00 内蒙古&#xff1a;6月20日9:00-7月3日24:00 新疆兵团&#xff1a;6月2…

RPG游戏完整指南

环境&#xff1a;unity2021urp 本教程教大家如何使用Unity创建一个RPG游戏&#xff0c;玩家可以在城镇场景中进行导航并寻找战斗&#xff0c;并在战斗中遇到不同类型的敌人。玩家可以向敌人施加不同的动作&#xff0c;如&#xff1a;常规攻击和撤离。这会是一个十分有趣的体验。…