组件二次封装,通过属性事件透传,插槽使用,组件实例方法的绑定,深入理解 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-input
      v-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-input
      v-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-input
      v-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.mfbz.cn/a/704916.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何筑牢防线,抵御.anony勒索病毒攻击?

引言 近年来&#xff0c;随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显。其中&#xff0c;勒索病毒作为一种新型的网络威胁&#xff0c;给企业和个人用户带来了极大的困扰。在众多勒索病毒中&#xff0c;.anony勒索病毒以其独特的加密方式和勒索手段&#xff0c;引…

2024/6/11 英语每日一段

They found that, regardless of culture, greater mental well-being is linked with feeling emotions that we believe are appropriate to our situation, rather than just having positive emotions regardless of context--“feeling right” as opposed to “feeling g…

深度学习500问——Chapter10:迁移学习(3)

文章目录 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 11.3.2 边缘分布自适应 11.3.3 条件分布自适应 11.3.4 联合分布自适应 11.3.5 概率分布自适应方法优劣性比较 11.3.6 特征选择 11.3.7 统计特征对齐方法 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 数据分布自适…

【配置教程】Linux在企业端为何如此重要

目录 本节重点 先见一下什么是Linux 后台vs前台 企业为何选择使用Linux作为后台服务器 国内企业后台和用户使用Linux现状 1. IT服务器Linux系统应用领域 2. 嵌入式Linux系统应用领域 3. 个人桌面应用领域 Linux时代发展 版本更新 ​编辑 就个人找工作/能力提升来说…

sklearn深度学习指南:掌握机器学习的利器

sklearn深度学习指南&#xff1a;掌握机器学习的利器&#xff01; 1. 简介1.1 什么是sklearn&#xff1f;1.2 sklearn的优势和应用领域1.3 为什么要学习和使用sklearn&#xff1f; 2. 安装和环境设置2.1 如何安装sklearn&#xff1f;安装Anaconda&#xff08;Windows/macOS/Lin…

利用泽攸科技原位TEM技术揭示真空击穿过程中电场与电极材料相互作用

在高能物理设备和许多其他设备中&#xff0c;真空击穿&#xff08;VBD&#xff09;现象对高能物理设备的性能造成了严重的阻碍&#xff0c;包括真空断路器、X射线源、聚变反应堆以及粒子加速器等。然而由于对导致VBD的机制缺乏足够的科学理解&#xff0c;这些问题至今无法得到缓…

618哪些数码产品比较好?2024超高人气产品推荐!

随着6.18大促的脚步渐近&#xff0c;你是否已经按捺不住内心的激动&#xff0c;想要在网络购物的海洋中畅游&#xff0c;尽情享受购物的狂欢&#xff1f;然而&#xff0c;面对繁多的商品和各式各样的优惠活动&#xff0c;你是否感到了一丝迷茫&#xff1f;作为一位经验丰富的网…

一带一路情 相逢《中国缘》-诗琳探访湘西墨戎苗寨交流有感

一带一路情 相逢《中国缘》 诗琳探访湘西墨戎苗寨交流有感 5月21日至25日&#xff0c;《中国缘》栏目组组织的走进湘西苗疆边陲的文化交流活动&#xff0c;在群山环抱、绿树成荫、人文厚重的湘西古丈墨戎苗寨美丽绽放。这场以民间角度推演的中国和中亚人民的文化交流活动&am…

沉降观测点的定义、重要性、建设与选择

沉降观测点&#xff0c;简称沉降点&#xff0c;是指在建筑物、构筑物或地基等结构物上设置的用于测量其垂直位移(沉降)的特定位置。这些点通常被标记并安装相应的监测设备&#xff0c;以便长期、连续地监测结构物的沉降情况。 点击输入图片描述&#xff08;最多30字&#xff09…

Kong AI Gateway 正式 GA !

Kong Gateway 3.7 版本已经重磅上线&#xff0c;我们给 AI Gateway 带来了一系列升级&#xff0c;下面是 AI Gateway 的更新亮点一览。 AI Gateway 正式 GA 在 Kong Gateway 的最新版本 3.7 中&#xff0c;我们正式宣布 Kong AI Gateway 达到了通用可用性&#xff08;GA&…

MySQL 5.7详细下载安装配置教程(MySQL 5.7安装包)_mysql5.7的安装教程

记录MySQL 5.7 的下载安装教程&#xff0c;并提供了Mysql 安装包 &#xff0c;以下是详细下载安装过程。 一、下载Mysql安装包 网盘下载&#xff1a; 下载MySQL 5.7安装包&#xff0c;网盘下载地址&#xff1a;点击此处直接下载 官网下载&#xff1a; 进入官网&#xff0c…

云消息队列 ApsaraMQ 成本治理实践(文末附好礼)

作者&#xff1a;家泽、稚柳 前言&#xff1a; 在 AI 原生应用架构浪潮中&#xff0c;消息队列需支持大规模数据和复杂 AI 模型训练与推理场景下的高效异步通信&#xff0c;其成本效益优化也日益受到重视。面对大模型或大数据量&#xff0c;消息量显著增加&#xff0c;云消息…

利用python爬虫采集苹果公司各产品销售收入统计报告

数据为2013年到2022年苹果公司各产品&#xff08;iPhone、iPad、Mac等&#xff09;及服务的销售收入。iPhone是苹果公司销售收入最高的产品。 数据统计单位为&#xff1a;亿美元 。 数据说明&#xff1a; 数据整理自苹果公司历年10-K文件&#xff0c;每年10-K文件可能对之前年…

构建企业核心竞争力:拥有自主大模型,引领行业未来

前言 随着人工智能技术的飞速发展&#xff0c;大模型技术已经成为推动行业进步的重要力量。在这个变革的时代&#xff0c;作为一位具有前瞻性的企业家&#xff0c;您深知拥有自主大模型对于提升公司竞争力、引领行业未来的重要性。本文将为您详细介绍大模型的市场现状以及企业…

SpringBoot的Mybatis-plus实战之基础知识

文章目录 MybatisPlus 介绍一、MyBatisPlus 集成步骤第一步、引入依赖第二步、定义mapper 二、注解TableNameTableldTableField 三、配置文件四、加解密实现步骤 在SpringBoot项目中使用Mybatis-plus&#xff0c;记录下来&#xff0c;方便备查。 MybatisPlus 介绍 为简化开发而…

亚信科技&用友,助力四川腾翔打通数据壁垒,跑出转型加速度

近日&#xff0c;亚信科技携手用友依托“AntDBU8C”联合产品&#xff0c;助力四川腾翔人力资源管理有限公司&#xff08;以下简称&#xff1a;腾翔&#xff09;打通“人力资源”与“财务”两大业务系统&#xff0c;实现高水平的数据互通、共享和应用&#xff0c;助力业务降本增…

【python】 pandas.DataFrame.to_json 函数

【python】 pandas.DataFrame.to_json 函数 写在最前面一、什么是 JSON&#xff1f;【性能对比】python读取json和直接从orcle数据库读&#xff0c;哪个更快&#xff1f;性能对比适用场景综合考虑 二、to_json 函数概述参数详解1. path_or_buf2. orient4. double_precision5. f…

基于开源模型搭建Agent系统教程

一篇非常基础非常基础的Agent博客 大型语言模型&#xff08;LLMs&#xff09;经过causal language modeling训练后&#xff0c;可以处理各种任务&#xff0c;但它们通常在逻辑、计算和搜索等基本任务上表现不佳。最糟糕的情况是&#xff0c;它们在某个领域&#xff08;如数学&…

MT2093 活动安排

贪心策略&#xff1a; 每次选择结束时间最早的活动 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 5e5 10; int n; struct pp {int a, b; } p[N]; bool cmp(pp x, pp y) {return x.b < y.b; } int ans 0;int main() {cin >>…

KafkaQ - 好用的 Kafka Linux 命令行可视化工具

鉴于并没有在网上找到比较好的linux平台的kafka可视化工具&#xff0c;今天为大家介绍一下自己开发的在 Linux 平台上使用的可视化工具KafkaQ 虽然简陋&#xff0c;主要可以实现下面的这些功能&#xff1a; 1&#xff09;查看当前topic的分片数量和副本数量 2&#xff09;查…