Vue-组件二次封装

news2024/11/24 3:40:17

本次对el-input进行简单封装进行演示

  • 封装很简单,就给激活样式的边框(主要是功能)

本次封装主要使用到vue自带的几个对象

  • $attrs:获取绑定在组件上的所有属性
  • $listeners: 获取绑定在组件上的所有函数方法
  • $slots: 获取应用在组件内的所有插槽

1、属性传递

element 的input组件有很多属性,

  • 想要实现在封装好后的组件上使用el-input组件的属性,会直接传递到el-input组件上,包括v-model
  • 在组件中,可以使用this.$attrs获取所有绑定在组件上的属性(不包括方法)
  • 这样,我们就可以在封装的组件内,使用v-bind="$attrs",直接把属性传递到内部组件上。
  • 在下列案例中,由于v-model:value 和 @input两个组合的语法糖,$attrs只能获取属性,所以只能传递:value属性

1.1、父组件

<template>
  <div class="wrapper"> 
    <my-input v-model="val">
    </my-input>
  </div>
</template>

<script>
  import MyInput from '@/components/MyInput'
  export default {
    components: {
      MyInput,
    },
    data() {
      return {
        val: '111',
      }
    },
    methods: {
      inputChange(val){
        console.log(val);
      }
    }
  }
</script>

<style lang="scss" scoped>
  .wrapper {
    padding: 10vh;
  }
</style>

1.2、子组件

<template>
  <el-input v-bind="$attrs"></el-input>
</template>
<script>
  export default {
    created() {
      console.log("attrs:",this.$attrs);
    }
  }
</script>
<style lang="scss" scoped>
::v-deep {
  .el-input__inner:focus {
    border-color: red;
}
}

</style>

1.3、效果

  • 这时候给输入框输入值是无效的,因为目前只能把value属性绑定到el-input上,并没有把input函数绑定上去,所以不能修改父组件传过来的value的值。

在这里插入图片描述

2、方法传递

element的组件,也有很多方法,比如:change等函数

  • 想要实现在封装好后的组件上使用el-input组件的方法,会直接传递到el-input组件上。
  • 在组件中,可以使用this.$listeners获取所有绑定在组件上的属性(不包括属性)
  • 这样,我们就可以在封装的组件内,使用v-on="$listeners",直接把方法传递到内部组件上。
  • 在下列案例中,由于v-model:value 和 @input两个组合的语法糖,$listeners只能获取属性,所以结合上面$attrsjiu可以完整的实现v-model的效果了

2.1、父组件

<template>
  <div class="wrapper"> 
    <my-input v-model="val" @change="inputChange">
    </my-input>
  </div>
</template>

<script>
  import MyInput from '@/components/MyInput'
  export default {
    components: {
      MyInput,
    },
    data() {
      return {
        val: '111',
      }
    },
    methods: {
      inputChange(val){
        console.log("inputChange:", val);
      }
    }
  }
</script>

2.2、子组件

<template>
  <el-input v-bind="$attrs" v-on="$listeners"></el-input>
</template>
<script>
  export default {
    created() {
      console.log("attrs:",this.$attrs);
      console.log("listeners:",this.$listeners);
    }
  }
</script>
<style lang="scss" scoped>
::v-deep {
  .el-input__inner:focus {
    border-color: red;
  }
}

</style>

2.3、效果

这时候搭配$attrs就可以实现v-model的完整效果了,以及@change函数也会传递过去

在这里插入图片描述

3、插槽传递

element的组件,也包括了很多的插槽

  • 想要给封装好后的组件,使用的插槽,传递到el-input
  • 在组件中,可以使用this.$attrs获取所有绑定在组件上的插槽
  • 这样,我们就可以在封装的组件内,使用v-for="(val, key) in $slots",所有插槽,遍历放到组件中,当作组件的插槽
  • 注意插槽传参也要处理(我这里没处理)

3.1、父组件

<template>
  <div class="wrapper"> 
    <my-input v-model="val" @change="inputChange">
      <template slot="prepend">Http://</template>
      <el-button slot="append" icon="el-icon-search"></el-button>
    </my-input>
  </div>
</template>

<script>
  import MyInput from '@/components/MyInput'
  export default {
    components: {
      MyInput,
    },
    data() {
      return {
        val: '111',
      }
    },
    methods: {
      inputChange(val){
        console.log("inputChange:", val);
      }
    }
  }
</script>

<style lang="scss" scoped>
  .wrapper {
    padding: 10vh;
  }
</style>

3.2、子组件

<template>
  <el-input v-bind="$attrs" v-on="$listeners">
    <template v-for="(val, key) in $slots">
      <slot :name="key"></slot>
    </template>
  </el-input>
</template>
<script>
  export default {
    created() {
      console.log("attrs:",this.$attrs);
      console.log("listeners:",this.$listeners);
      console.log("slots",this.$slots);
    }
  }
</script>
<style lang="scss" scoped>
::v-deep {
  .el-input__inner:focus {
    border-color: red;
  }
}

</style>

3.3、效果

在这里插入图片描述

4、ref伪传递(适用于vue3)

  • 为什么说伪传递呢,因为在vue中,根本就拿不到外层组件的ref属性,所以只能另换思路
  • 你要用ref,无非就是想调用组件里面的函数。那我封装的组件里面,可以把被封装的组件的函数,直接提取出来,当作我封装组件的函数即可实现
  • 适用于Vue3,vue2会卡死

4.1、父组件

<template>
  <div class="wrapper"> 
    <my-input ref="muInput" v-model="val" @change="inputChange">
      <template slot="prepend">Http://</template>
      <el-button slot="append" icon="el-icon-search"></el-button>
    </my-input>
  </div>
</template>

<script>
  import MyInput from '@/components/MyInput'
  export default {
    components: {
      MyInput,
    },
    data() {
      return {
        val: '111',
      }
    },
    mounted() {
      this.$refs.muInput.focus()
    },
    methods: {
      inputChange(val){
        console.log("inputChange:", val);
      }
    }
  }
</script>

<style lang="scss" scoped>
  .wrapper {
    padding: 10vh;
  }
</style>

4.2、子组件

<template>
  <el-input ref="input" v-bind="$attrs" v-on="$listeners">
    <template v-for="(val, key) in $slots" #[key]>
      <slot :name="key"></slot>
    </template>
  </el-input>
</template>
<script>
  export default {
    mounted() {
      console.log("attrs:",this.$attrs);
      console.log("listeners:",this.$listeners);
      console.log("slots",this.$slots);

      for (const [key, value] of Object.entries(this.$refs.input)) {
        this[key] = value
      }
    }
  }
</script>
<style lang="scss" scoped>
::v-deep {
  .el-input__inner:focus {
    border-color: red;
  }
}

</style>

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

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

相关文章

MATLAB的设置路径

在主页下的 或者在命令行输入path&#xff0c;命令行会出现所有路径 必须要将某些函数.m文件以及一些类文件包含在路径当中&#xff0c;否则在脚本代码中输入代码时&#xff0c;不会有代码提示

【Azure】office365邮箱测试的邮箱账号因频繁连接邮箱服务器而被限制连接 引起邮箱显示异常

azure微软office365邮箱会对频繁连接自身邮箱服务器的IP地址进行&#xff0c;连接邮箱服务器IP限制&#xff0c;也就是黑名单&#xff0c;释放时间不确定&#xff0c;但至少一天及以上。 解决办法&#xff0c;换一个IP&#xff0c;或者新注册一个office365邮箱再重试。 以下是…

Mysql5.7 、MySQL 8.0 加密、解密函数

PASSWORD 8.0版本取消了&#xff0c;只能在5.7中使用 返回字符串str的加密版本&#xff0c;41位长的字符串&#xff0c;加密结果不可逆 格式 select PASSWORD(xxx) from DUAL;MD5 5.7和8.0 都支持 返回字符串str的MD5加密后的值&#xff0c;若参数为null&#xff0c;则…

不同风格Tabs

风格 通过type设置风格&#xff0c;支持三种风格card、borderCard、line 核心代码 组件双向绑定 modelVal: {type: Number | String,required: true}, model: {prop: modelVal,event: change} this.$emit(change, this.active) 代码 <template><div:class"[…

【链表OJ 1】移除链表元素val

大家好&#xff0c;欢迎来到我的博客&#xff0c;此题是关于链表oj的第一题&#xff0c;此后还会陆续更新博客&#xff0c;如有错误&#xff0c;欢迎大家指正。 来源:https://leetcode.cn/problems/remove-linked-list-elements/description/ 题目: 方法一:定义prev和cur指针…

基于STM32微控制器的物联网(IoT)节点设计与实现

基于STM32微控制器的物联网(IoT)节点的设计和实现。我们讨论物联网节点的基本概念和功能,并详细介绍了STM32微控制器的特点和优势。然后,我们将探讨如何使用STM32开发环境和相关的硬件模块来设计和实现一个完整的物联网节点。最后,我们将提供一个示例代码,展示如何在STM3…

侯捷 C++面向对象编程笔记——9 复合 委托

9 复合 委托 9.1 Composition 复合 类似于c中结构里有结构——class里有class deque 是一个已经存在的功能很多的类&#xff08;两头进出的队列&#xff09;&#xff1b;利用deque的功能来实现queue的多种操作 该例只是复合的一种情况——设计模式 Adapter 9.1.1 复合下的构造…

【JavaEE进阶】Spring创建与使用

文章目录 一. 创建 Spring 项目1.1 创建一个Maven项目1.2 添加Spring依赖1.4. 创建一个启动类 二. 将 Bean 对象存放至 Spring 容器中三. 从 Spring 容器中读取到 Bean1. 得到Spring对象2. 通过Spring 对象getBean方法获取到 Bean对象【DI操作】 一. 创建 Spring 项目 接下来使…

实时服务器监控

为 IT 基础架构建立适当的监控系统的重要性不容低估&#xff0c;管理员使用的监控解决方案可确保通过消除瓶颈和优化资源使用以获得最佳性能来充分发挥基础架构的潜力。 多年来&#xff0c;IT 基础架构变得越来越复杂&#xff0c;对网络监控的需求也随之增加&#xff0c;虽然网…

R语言3_安装SeurateData

环境Ubuntu22/20, R4.1 在命令行中键入&#xff0c; apt-get update apt install libcurl4-openssl-dev libssl-dev libxml2-dev libcairo2-dev libgtk-3-dev # libcairo2-dev :: systemfonts # libgtk :: textshaping进入r语言交互环境&#xff0c;键入&#xff0c; instal…

运动蓝牙耳机哪个最好、最好用的运动蓝牙耳机推荐

在奔跑的律动中&#xff0c;一款优秀的运动耳机能为我们带来动力。今天&#xff0c;我为大家推荐五款经过精心挑选的运动耳机&#xff0c;它们不仅具备卓越的音质和稳定的连接性&#xff0c;还采用舒适的佩戴设计和耐用的防水功能&#xff0c;可以让我们在运动中畅享音乐的同时…

数据结构之栈和队列---c++

栈和队列的简单介绍 栈 栈是一个“先进后出”结构 队列 入队演示 队列是一种“先进先出”的结构 出队演示 接下来我们开始本次的内容 栈实现队列 分析 1.我们可以老老实实的写一个栈然后将所有的接口函数实现出来&#xff0c;最后再进行实现队列&#xff0c;但是显然…

git开发过程中的使用

1、先创建本地分支&#xff0c;然后修改代码 2、本地提交 push 3、合并为主分支 回到master分支

【【萌新的STM32 学习-6】】

萌新的STM32 学习-6 BSP 文件夹&#xff0c;用于存放正点原子提供的板级支持包驱动代码&#xff0c;如&#xff1a;LED、蜂鸣器、按键等。 本章我们暂时用不到该文件夹&#xff0c;不过可以先建好备用。 CMSIS 文件夹&#xff0c;用于存放 CMSIS 底层代码&#xff08;ARM 和 ST…

Linux——设备树

目录 一、Linux 设备树的由来 二、Linux设备树的目的 1.平台识别 2.实时配置 3.设备植入 三、Linux 设备树的使用 1.基本数据格式 2.设备树实例解析 四、使用设备树的LED 驱动 五、习题 一、Linux 设备树的由来 在 Linux 内核源码的ARM 体系结构引入设备树之前&#x…

Vue——webpack

webpack 一、Install1.全局安装2.局部安装 二、总结1.打包2.定义脚本3.配置文件定义&#xff08;webpack.config.js)4.项目重新加载依赖5.webpack打包Css6.style-loader 一、Install 1.全局安装 npm install webpack webpack-cli -g2.局部安装 以项目为单位&#xff0c;一个项…

2023中国数字人力峰会|用「消失的Ta」解读数字化人效管理

7月28日&#xff0c;DHR公会主办的「2023中国数字人力峰会」在北京顺利举办。盖雅工场联合创始人兼CEO章新波带来主题为「消失的它」的精彩分享。以下为分享内容&#xff1a; 近期&#xff0c;大家都在讨论消失的Ta&#xff0c;我也想借此话题举几个例子&#xff0c;聊聊对于企…

thinkphp8.0多应用模式下提示控制器不存在

thinkphp 8.0 开启多应用模式 1、按照官方文档说明 &#xff0c;已经安装了 think-multi-app composer require topthink/think-multi-app 2、控制器的命名空间也没写错。 3、访问路径与目录名、控制器、方法名一样&#xff0c;访问地址是没错的。 4、网上有说&#xff0c;在…

实现vscode上用gdb调试stm32

实现vscode上用gdb调试stm32 这周负责编写设备的某个模块&#xff0c;其中遇到了一些变量地址不正确的错误&#xff0c;按理这种底层变量错误用gdb一类的调试器就能很快查到&#xff0c;可是初入嵌入式一行&#xff0c;此C语言非彼C语言&#xff0c;对于gdb怎么对接到项目上根…

冠达管理投资前瞻:三星加码机器人领域 大信创建设提速

上星期五&#xff0c;沪指高开高走&#xff0c;盘中一度涨超1%打破3300点&#xff0c;但随后涨幅收窄&#xff1b;深成指、创业板指亦强势震动。截至收盘&#xff0c;沪指涨0.23%报3288.08点&#xff0c;深成指涨0.67%报11238.06点&#xff0c;创业板指涨0.95%报2263.37点&…