首页 > 其他分享 >vue3父子组件通信小结

vue3父子组件通信小结

时间:2023-08-22 13:55:16浏览次数:47  
标签:console log vue3 attrs props 组件 return 小结

父子组件中的attrs props 理解/继承

首先,父组件可以给子组件传入属性、监听函数(类似onClick),class,style,id,总结起来就是大三类-属性,监听函数,样式

爷爷组件 -- 有两个监听函数

import { computed, defineComponent, reactive, ref } from "vue";
import { css } from "@emotion/css";
import Child from "./test/Child";

export default defineComponent({
  props: {},
  setup: (props, { emit }) => {
    return () => {
      return (
        <>
          <Child
            onHei={(val) => {
              console.log("祖父组件", val);
            }}
            onTest={() => {
              console.log("祖父Test");
            }}
          />
        </>
      );
    };
  },
});

父组件 -给子组件传入了name,age以及onTest,style等属性,函数或者样式等。

import { defineComponent, reactive, ref } from "vue";
import Sun from "./Sun";

export default defineComponent({
//   emits: ["hei"],
  props: {},
  setup: (props, { emit, attrs }) => {
    const a = ref("test");
    console.log("父组件中props", props);
    console.log("父组件中attrs", attrs);
    return () => {
      return (
        <Sun
          name={a.value}
          age="18"
          onTest={() => {
            console.log("父级test监听执行");
          }}
          // {...attrs}
          onHei={(val) => {
            console.log("父级hei组件", val);
          }}
          style={{
            color: "red",
          }}
          class="test"
        />
      );
    };
  },
});

子组件-可通过props和attrs看出父组件中的属性或者函数都能拿到。

import { defineComponent, reactive, ref } from "vue";

export default defineComponent({
  props: {
    name: String,
  },
  setup: (props, { emit, attrs }) => {
    console.log("props", props); // {name: 'test'}
    console.log("attrs", attrs);  //   {age: "18",onHei:()=>{}, onTest:()=>{},style:{color:'red'}}
    
    return () => {
      return (
        <div
          onClick={() => {
            emit("hei");
          }}
        >
          点击最底层
        </div>
      );
    };
  },
});

通过这种层层嵌套的组件关系,我们可以观察出以下结论

  1. 我们可以看到,父组件传入的属性或者监听函数都能被props和attrs、emits,具体可以用如下表达式来体现
    **父组件传入的所有内容 = 子组件中props + 子组件声明的emits + 子组件中attrs **
  2. 如果不声明props、emits,则所有内容都可以用attrs拿到,包括style属性等。声明一个props,或者声明一个emits,attrs就少一个内容。
  3. 一般我们子组件中不直接用on监听的事件,只是用到传递过来的属性值,父组件中的事件监听,可以靠emit主动派发出去。
  4. 如果子组件中不声明props,emits,attrs可以拿到所有的内容,而attrs的内容,又默认都给了子组件继承下去了!!!
  5. 基于第4点,子组件中声明的props或者emits无非不就是截胡的意思(也就是props和emits是你的肉,attrs是子孙的汤,你吃肉,别人喝汤),也就是把父辈的东西截胡了,props声明的属性只有到了我这一辈能用,子孙别想用;emits声明的事件,只有我触发了,父辈能监听到,你子孙触发这些事件,父辈是监听不到的。

我们通过以上案例发现,父组件中的内容会默认通过attrs继承给子组件(或者是根元素),那么我们如果不想这么默认,该怎么操作?因为实际情况下,确实我们子组件中正常能通过props拿到属性,emit可以正常派发事件,其他的我不想这么默认继承下去。

以下,我们通过inheritAttrs: false将默认attrs传递给子组件的操作给关闭了。注意,这里虽然关闭了默认继承,但是attrs里面的值还是正常能拿到。

export default defineComponent({
  inheritAttrs: false, //关闭继承
  setup: (props, { emit, attrs }) => {
    const a = ref("test");
    console.log("父组件中props", props);
    console.log("父组件中attrs", attrs);
    return () => {
      return (
        <Sun
          name={a.value}
          age="18"
          onTest={() => {
            console.log("父级test监听执行");
          }}
          // {...attrs}
          onHei={(val) => {
            console.log("父级hei组件", val);
          }}
          style={{
            color: "red",
          }}
          class="test"
        />
      );
    };
  },
});

因为有这种默认的继承,会出现两种现象1、对应属性来说,父辈的属性能够出现在子子孙孙里面的(除非有人中间截胡);2、对应监听函数来说,这样一直传下去,会有一个现象是子孙里面派发一个事件处理,父辈的监听事件都能监听到(也是除非中间有人截胡)
以上这个信息很关键,在vue3封装高阶组件的时候,能体会到,你包装了一层其他的组件,那么其他组件本身派发的事件,你包装的那一层也能监听到,就是因为这种父辈给子孙事件继承的原因!!!这种设计也方便了组件的封装!!!

子组件派发事件与传入函数回调处理对比

父组件 -通过属性传递了一个函数进行

export default defineComponent({
  props: {},
  setup: (props, { emit }) => {
    return () => {
      return (
        <>
          <Child
            hei={(val) => {
              console.log("祖父组件", val);
            }}
          />
        </>
      );
    };
  },
});

子组件 -子组件中利用执行props传入的函数来实现类似emit派发事件的效果。


export default defineComponent({
  props: {
    hei: Function,
  },
  setup: (props, { emit, attrs }) => {
    return () => {
      return (
        <div
          onClick={() => {
            props.hei(666);
          }}
        >
          点击
        </div>
      );
    };
  },
});

可以发现,利用传入一个函数同样可以实现emit的效果,但是还是建议用官方的emit。

标签:console,log,vue3,attrs,props,组件,return,小结
From: https://www.cnblogs.com/teamemory/p/17648326.html

相关文章

  • 组件传值
    父组件向子组件传值props只能是父组件向子组件进行传值,props使得父子组件之间形成了一个单向下行绑定。子组件的数据会随着父组件不断更新。props可以显示定义一个或一个以上的数据,对于接收的数据,可以是各种数据类型,同样也可以传递一个函数。props属性名规则:若在props中使用......
  • 界面组件DevExpress Reporting——增强的SQL和实体框架数据源引入
    DevExpressReporting是.NETFramework下功能完善的报表平台,它附带了易于使用的VisualStudio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表。本文总结了v23.1中针对DevExpress报表和BIDashboard产品中使用的SQL和实体框架数据源引......
  • 【爬虫案例小结】
    【案例】登陆博客园【1】思路分析打开cnblogs点进登录页面输入用户名密码点登录(可能会出现验证码)----手动操作跳过验证码登录成功后拿到cookie保存到本地关闭浏览器开启selenium,打开浏览器把本地的cookie写入到当前浏览器中当前浏览器就是登录状态【2】......
  • 阿里相关组件-阿里Cola状态机相关
    使用State:状态Event:事件,状态由事件触发,引起变化Transition:流转,表示从一个状态到另一个状态ExternalTransition:外部流转,两个不同状态之间的流转InternalTransition:内部流转,同一个状态之间的流转Condition:条件,表示是否允许到达某个状态Action:动作,到达某个状态之后,可以做什......
  • VUE3单页面应用开发常用工具
    Vite一种新型的前端构建工具,它主要由两个部分做成一个开发服务器,它基于 原生ES模块 提供了 丰富的内建功能,如速度快到惊人的 模块热更新(HMR)。一套构建指令,它使用 Rollup 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。社区模......
  • Spring Cloud微服务网关Gateway组件
    网关简介大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。  这样的架构,会存在着诸多的问题:每个业务都会需要鉴权、限流、权限校验、跨域等逻......
  • keep-alive组件的作用与原理
    什么是keep-alive“keep-alive”是Vue.js中的一个特殊组件,用于缓存组件的状态,以提高应用性能。在Vue.js中,组件通常是动态创建和销毁的,当切换到另一个页面或组件时,之前的组件会被销毁,再次进入时会重新创建和初始化。这样可能导致组件的状态丢失,需要重新初始化,增加了资源的消耗......
  • vue3 watch 监听响应式数据变化 改变img的src
    目标:用一个图片来监视全局websocket对象的连接状态  全局websocket的写法详见:https://www.cnblogs.com/hailexuexi/p/17577818.htmlmain.js全局对象 websocket的连接状态//全局对象constglobalData=reactive({ websockStatus:"open",})app.provide('globalData',......
  • 在Vue3后台管理系统中使用watch和watcheffect
    ​ 1、watch在Vue3中的组合式API中,watch的作用和Vue2中的watch作用是一样的,他们都是用来监听响应式状态发生变化的,当响应式状态发生变化时,都会触发一个回调函数。constmessage=ref("test");watch(message,(newValue,oldValue)=>{console.log("新值:",ne......
  • OpenTiny Vue 3.10.0 版本发布:组件 Demo 支持 Composition 写法,新增4个新组件
    我们非常高兴地宣布,2023年8月14日,OpenTinyVue发布了v3.10.0 ......