Vue中如何更好地封装组件?

news2024/11/26 21:31:35
  • 子组件接受父组件传递的事件

1.子组件使用@事件名="$emit('父组件中传递的事件名',想给父组件传递的参数(可选))"
@click="$emit('click')"
2.子组件使用
v-on="$listeners"

 父组件:

<template>
  <div id="app">
    <myComponents :msg="form.msg" @click="a"/>
  </div>
</template>

<script>
import myComponents from "./components/myComponents";

export default {
  name: 'App',
  components: {
    myComponents
  },
  data(){
    return {
      form:{
        msg: "10"
      }
    }
  },
  methods:{
    a(){
      console.log('哈哈哈')
    },
  }
}
</script>

<style>

</style>

 子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <!-- v-on="$listeners" 和 @click="$emit('click')" 效果一样  两者选一即可-->
    <h1 v-on="$listeners" @click="$emit('click')">{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  props: {
    msg: {
      type: String,
      default: "18"
    }
  },
  created() {
    console.log(this.$listeners)  //一个对象,里面包含父组件传递过来的所有事件
  },
  methods: {}
}
</script>
<style scoped>
</style>
  • 父组件传值给子组件

1.子组件使用props声明想要的属性,再将该属性动态绑定给子组件
props: {
  msg: {
    type: String,
    default: "18"
  },
},
     然后子组件中绑定数据即可
    父组件使用prop声明,就可以传递给子组件

:prop="msg"

2.子组件使用$attrs,这个组件包含了被传入,但没有声明的prop

 子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
//不声明msg
  // props: {
  //   msg: {
  //     type: String,
  //     default: "18"
  //   },
  // },
  created() {
    console.log(this.$attrs)   //一个对象,包含父组件中被传入,但没有声明的prop
  },
  methods: {}
}
</script>

<style scoped>
</style>

打印结果: 

 此时h1标签上就有msg属性:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

页面显示结果:

 

 需要注意的一点是:Vue会将被传入,但未声明的prop作为html属性,绑定到组件的根元素上:

可以设置属性 inheritattrs为false,将这些默认行为去掉,来解决这个问题。

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  inheritAttrs:false,
}
</script>

<style scoped>
</style>

  • 对外暴露子组件插槽

1.直接向子组件转发插槽,使用父组件的 $slots 
该组件包含了传递给父组件的非作用域插槽
使用$scopeSlots可传递给父组件的作用域插槽,这个组件包含了组件接受的所有插槽

子组件:

<template>
<el-input
v-model="innerVal"
v-bind-"$attrs
@input="$emit('input", $event)"v-on-"$listeners

//子组件中写两个插槽
<template #append>
<slot name="append"></slot></template>
<template #prepend>
<slot name="prepend"></slot></template>
</el-input>
</template>

 打印this.$slots

  • props validator

一般我们会用对象的形式声明prop,可以在对象中指定prop的默认值,也可以指定类型,对prop进行验证。
一个更灵活的的方式是,传入并编写一个验证函数,prop会作为参数传入该函数,函数返回fals时,会抛出控制台警告,这种方式特别适合验证枚举值,

 子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-on="$listeners" @click="$emit('click')" v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  inheritAttrs:false,
  props:{
    numberIs:{
      default: '1',
      //当传入的prop值不是1,2,3时,控制台会抛出警告
      validator: prop => ['1', '2', '3'].includes(prop)
    }
  },
}
</script>
<style scoped>
</style>

 父组件:

<template>
  <div id="app">
    <!--  传入numberIs的值为4  -->
    <myComponents :msg="form.msg" @click="a" numberIs="4"/>
  </div>
</template>

<script>
import myComponents from "./components/myComponents";

export default {
  name: 'App',
  components: {
    myComponents
  },
  data() {
    return {
      form: {
        msg: "10"
      },
    }
  },
  methods: {
    a() {
      console.log('哈哈哈')
    },
  }
}
</script>

<style>

</style>

$refs用于父组件获取整个子组件实例,然后可以使用子组件的方法和属性(暴露子组件方法)

父组件:

<template>
  <div id="app">
    <!--  ref相当于给当前子组件设置了一个id,可以使用refs根据ref的值获取该组件  -->
    <myComponents :msg="form.msg" @click="a" numberIs="1" ref="bb"/>
  </div>
</template>

<script>
import myComponents from "./components/myComponents";

export default {
  name: 'App',
  components: {
    myComponents
  },
  data() {
    return {
      form: {
        msg: "10"
      },
    }
  },
  methods: {
    a() {
      //获取ref值为bb的子组件,并调用该子组件上的show方法
      this.$refs.bb.show()
    },
  }
}
</script>

<style>

</style>

子组件:

<template>
  <div>
    <!-- 子组件接收父组件传来的参数-->
    <h1 v-on="$listeners"  v-bind="$attrs"> {{this.$attrs.msg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'my-Components',
  inheritAttrs:false,
  props:{
    numberIs:{
      default: '1',
      //当传入的prop值不是1,2,3时,控制台会抛出警告
      validator: prop => ['1', '2', '3'].includes(prop)
    }
  },
  created() {
  },
  methods: {
    show(){
      console.log('1111')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

打印 this.$refs 显示为:

 

 点击之后,控制台输出:

但在封装子组件后,如果不对子组件的方法进行暴露,调用时,我们往往需要通过ref先获取父组件实例,再获取子组件实例,这种方式导致组件代码难以维护:

//获取父组件bb之后,再获取子组件aa,最后使用aa中的show方法
this.$refs.bb.$refs.aa.show()

我们可以再父组件中提供与子组件同名的方法, 对外暴露,让使用者只通过父组件就可以进行调用:

子组件中:

methods:{
    show() {
        this.$refs.aa.show()
    }
}

父组件中:

methos: {
    show() {
        this.$refs.bb.show()
    }
}

总结:

1. $attrs 简化多层组件之间props传值;
2. $listeners 简化多层组件之间事件传递;
3. $Slots 更多拓展自定义组件传值,包括自定义html元素,及对象;
4. props validator 增强组件传值稳健性,可自定义业务代码效验参数;
5. $refs 对外提供API 增强组件灵活度和可控性; 

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

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

相关文章

Ceph分布式存储系统优化分析

Ceph支持多种存储访问接口&#xff0c;现有的多种性能测试工具都可用于Ceph的性能测试&#xff0c;如测试块接口性能的fio&#xff0c;iometer等&#xff1b;测试CephFS接口的filebench&#xff0c;fio等;测试对象接口的cosbench等。Ceph有专用的基准测试集CBT&#xff0c;其包…

并查集的原理与实现

1.概念 2.生活中的例子 小弟-老大&#xff1b; 帮派识别 3.实现 3.1 初始化 3.2 中间过程 3.3合并 3.4 并查集路径优化 直接把下面的节点指向最终的老大。 3.5 伪代码实现 3.6JAVA实现 findRoot: 谁是帮派的老大。例如山鸡的老大是陈浩南 connected: 我们是不是同一个大…

【机器学习 | 数据预处理】 提升模型性能,优化特征表达:数据标准化和归一化的数值处理技巧探析

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

勇敢牛牛,爱吃青草

牛顿问题&#xff08;牛吃草问题 / 消长问题&#xff09; 牛顿问题&#xff08;牛吃草问题/消长问题&#xff09; 牛顿问题&#xff08;牛吃草问题/消长问题&#xff09; 牧场上有一片青草&#xff0c;每天都生长得一样快。这片青草供给 10 头牛吃&#xff0c;可以吃 22 天&…

元宇宙时代超高清视音频技术白皮书关于流媒体协议和媒体传输解读

流媒体协议 元宇宙业务场景对流媒体传输的实时性和互动性提出了更高的要求&#xff0c;这就需要在传统的 RTMP、SRT、 HLS 等基础上增加实时互动的支持。实时互动&#xff0c;指在远程条件下沟通、协作&#xff0c;可随时随地接入、实时地传递虚实融合的多维信息&#xff0c;身…

LangChain-ChatGLM在WIndows10下的部署

LangChain-ChatGLM在WIndows10下的部署 参考资料 1、LangChain ChatGLM2-6B 搭建个人专属知识库中的LangChain ChatGLM2-6B 构建知识库这一节&#xff1a;基本的逻辑和步骤是对的&#xff0c;但要根据Windows和现状做很多调整。 2、没有动过model_config.py中的“LORA_MOD…

Idea中使用statement接口对象,显示mysql版本号,所有库和表名

使用statement 接口对象&#xff0c;进行以下操作&#xff1a; 显示数据库版本号显示所有库显示所有库中的table表 显示数据库版本号&#xff1a; public class StatementDemo {Testvoid showall(){try{Statement st conn.createStatement();ResultSet rs st.executeQuery(…

C++_模板初阶

在面向对象中&#xff0c;我们可以使用重载来实现多态。 但是问题在于&#xff0c;重载的函数仅仅是类型不同&#xff0c;代码复用率比较低&#xff0c;只要有新的类型出现时&#xff0c;就要增加对应的函数&#xff1b;另一方面它的代码可维护性比较低&#xff0c;一个出错可…

python递归实现逆序输出数字

一、问题描述 编程实现将输入的整数逆序输出 二、问题分析 逆序输出数字实际是一个数值问题的递归 三、算法设计 该问题要求输入任意一个整数&#xff0c;实现它的逆序输出。首先判断输入的整数是正整数还是负整数&#xff0c;如果是负整数&#xff0c; 则在逆序输出前应先…

1059 Prime Factors

个人学习记录&#xff0c;代码难免不尽人意。 Sample Input: 97532468 Sample Output: 975324682^211171011291 下面是我第一次自己写的错误代码&#xff0c;虽然测试点都通过了&#xff0c;但是是因为测试样例有限的原因。 #include<cstdio> #include<iostream> #…

防御第九次作业

一、根据以下问题总结当天内容 1. SSL工作过程是什么&#xff1f; 当客户端向一个 https 网站发起请求时&#xff0c;服务器会将 SSL 证书发送给客户端进行校验&#xff0c;SSL 证书中包含一个公钥。校验成功后&#xff0c;客户端会生成一个随机串&#xff0c;并使用受访网站的…

OSI七层模型及TCP/IP四层模型

目录 OSI七层模型 TCP/IP四层模型 OIS七层模型和TCP/IP模型图 七层详解 两种模型比较 为什么OSI七层体系结构不常用 四层详解 网络为什么要分层&#xff1f; 说说 OSI 七层模型和 TCP/IP 四层模型的关系和区别 OSI七层模型 OSI&#xff08;Open System Interconnect&a…

5.3 个人隐私保护

数据参考&#xff1a;CISP官方 目录 一、数据泄露与隐私保护问题二、信息的泄露途径三、个人隐私信息保护四、组织机构敏感信息保护 一、数据泄露与隐私保护问题 1、数据泄露事件 数据的价值已经得到高度的认可不可避免的面临安全威胁2018年华住集团数据泄露事件中国电信…

代码控制鼠标光标移动并点击和代码模拟键盘按下(C#)

前面介绍过通过代码的方式模拟键盘按下&#xff0c;博文如下&#xff1a; C#通过代码的方式模拟键盘按下_c# 模拟键盘输入_zxy2847225301的博客-CSDN博客 这个博文是通过win32的keybd_event实现&#xff0c;可能会未来的window版本中被淘汰(不是我说的&#xff0c;看到老外一…

简单线性回归:预测事物间简单关系的利器

文章目录 &#x1f340;简介&#x1f340;什么是简单线性回归&#xff1f;&#x1f340;简单线性回归的应用场景使用步骤&#xff1a;注意事项&#xff1a; &#x1f340;代码演示&#x1f340;结论 &#x1f340;简介 在数据科学领域&#xff0c;线性回归是一种基本而强大的统…

Failed to start LVS and VRRP High Availability Monitor.

Keepalive启动报错&#xff0c;Fail to start LVS and VRRP High Availability Monitor. 解决方法 &#xff1a; cd /etc/keepalived/cp keepalived.conf.sample keepalived.conf vim keepalived.conf //找到这个模块并修改接口名称 vrrp_instance VI_1 {state MASTERinterfac…

Jeecg-boot JDBC任意代码执行漏洞

漏洞描述 JeecgBoot是一款开源的企业级低代码平台&#xff0c;提供了表单、视图、流程等一键生成代码功能&#xff0c;目前在GitHub具有 35.5k star。 在V3版本中&#xff0c;由于未对JDBC连接字符串进行限制&#xff0c;未授权的攻击者可配置恶意的连接字符串&#xff0c;通…

岛屿的最大面积(力扣)递归 JAVA

给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&#xff09;包围着。 岛屿的面积是岛上值为 1 的…

Redis的数据结构到底是一种什么样的结构?

有了上一篇NoSQL的基础&#xff0c;我们也都知道了Redis就是一种典型的NoSql&#xff0c;那我们就先简简单单的介绍一下Redis&#xff1a; Redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的使用ANSI C语言编写的高性能键值存储系统…

Kalman Filter VS Particle Filter

概率图模型 时间 -------->动态模型 动态模型有下面三种&#xff1a; 如果状态是离散的&#xff0c;就是我们上一节提到了Hidden Markov Model (HMM)&#xff1b; 如果状态是连续的&#xff0c;如果状态之间的关系是线性的&#xff0c;就是Linear Dynamic System (Kalman …