在vue中通过使用$attrs实现组件之间的数据传递

  组件之间传递数据的方式有很多种,之所以有这么多种方式,是为了满足在不同场景不同条件下的使用。
  
  一般有三种方式:
  
  通过 props 的方式向子组件传递(父子组件)
  
  vuex 进行状态管理
  
  非父子组件的通信传递 Vue Event Bus,使用Vue的实例,实现事件的监听和发布,实现组件之间的传递
  
  本文介绍的是使用$attrs的方式。
  
  这个api是在2.4版本中添加的,那么为什么要添加这个特性呢?
  
  看看官网是怎么解释的
  
  包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
  
  当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),
  
  并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
  
  第一次看的话真是不容易看懂,这里是既包含用法又隐晦的说明了为什么使用,还是我来解释一下吧。
  
  意思就是:$attrs 可以收集父组件中的所有传过来的属性除了那些在组件中没有通过 props 定义的。
  
  引申说明一下,如果组件的嵌套层级有点深但又不那么深,比如三层。
  
  我们如果使用props的话,最里面的组件想要获取最外层组件的数据,就要通过中间的组件的props来传递,
  
  但是这个props对于中间的这个组件没啥用处,它就是做了一个桥梁而已。我们平时写代码时候其实经常碰到
  
  这种场景,写起来有时候觉得挺烦的。所以就有了这个$attrs来帮助我们,不必在中间组件中写props就可以让
  
  最里面的组件拿到最外面组件传进来的数据。
  
  那么,具体怎么使用呢?
  
  看看下面的代码吧,很简单就懂了
  
  准备三个组件
  
  里面的代码如下
  
  //grandfather
  
  <template>
  
  <div style="background: blue">
  
  father in grandfather
  
  <father :father-age="50" :child-time="`${time}`"></father>
  
  </div>
  
  </template>
  
  <script>
  
  import father from ‘./father‘
  
  export default {
  
  components: {
  
  father
  
  },
  
  data () {
  
  return {
  
  time: new Date().getTime()
  
  }
  
  }
  
  }
  
  </script>
  
  //father
  
  <template>
  
  <div style="background: red">
  
  child in father
  
  <div>
  
  <span>father age:</span>{{fatherAge}}
  
  </div>
  
  <child v-bind="$attrs"></child>
  
  </div>
  
  </template>
  
  <script>
  
  import child from ‘./child‘
  
  export default {
  
  components: {
  
  child
  
  },
  
  props: {
  
  fatherAge: {
  
  type: Number,
  
  default: 0
  
  }
  
  }
  
  }
  
  </script>
  
  //child<template>
  
  <div style="background: green">
  
  <div>child</div>
  
  <div>time: {{childTime}}</div>
  
  </div>
  
  </template>
  
  <script>
  
  export default {
  
  props: {
  
  childTime: {
  
  type: String,
  
  default: ‘‘
  
  }
  
  }
  
  }
  
  </script>
  
  需要从爷爷组件直接传给子组件的数据,不要在父组件中的props中声明。
  
  在子组件上通过v-bind的方式就可以把父组件中未声明而子组件需要从爷爷组件中获取的数据传给子组件。
  
  当然,子组件props肯定是要声明的,还是props的用法啦。
  
  最后需要注意的一点是,$attrs是要配合inheritAttrs: false使用的哦,具体为什么可以看下官网教程https://cn.vuejs.org/v2/guide/components-props.html#%E9%9D%9E-Prop-%E7%9A%84%E7%89%B9%E6%80%A7禁用特性教程这一小节,但是其实讲的也是不清楚,建议google一下吧。
  
  const type = nodes[val].type;
  
  if (type === ‘a‘) {
  
  // 如果type为a的话,则保存到数组 nodeTypeIsA 中,之后判断数组 nodeTypeIsA 是否长度为0
  
  // 如果不为0则表示这一层级中有节点 type 为 a,则总数可加一,再取出所有type为a的节点的子
  
  // 节点进行下一轮计算,直到该层级中没有 type 为 a 的节点为止
  
  nodeTypeIsA.push(val);
  
  const n = nodes[val].childNodeIds ? Object.keys(nodes[val].childNodeIds) : [];
  
  childNodeIds = [...childNodeIds, ...n];
  
  }
  
  });
  
  if (nodeTypeIsA.length === 0) {
  
  return total;
  
  }
  
  ++total;
  
  return statisticalNextNodeNumber(childNodeIds, total);
  
  }
  
  function statisticalBeforeNodeNumber(nodeIds, num) {
  
  let total = num;
  
  let nodeTypeIsA = [];
  
  let beforeNodeIds = [];
  
  const nodes = nodes; // 获取所有节点信息的方法或对象
  
  nodeIds.forEach((val) => {
  
  const type = nodes[val].type;
  
  if (type === ‘a‘) {
  
  nodeTypeIsA.push(val);
  
  const n = nodes[val].parentNodeIds ? Object.keys(nodes[val].parentNodeIds) : [];
  
  beforeNodeIds = [...beforeNodeIds, ...n];
  
  }
  
  });
  
  if (nodeTypeIsA.length === 0) {
  
  return total;
  
  }
  
  ++total;
  
  return statisticalNextNodeNumber(beforeNodeIds, total);
  
  }
  
  复制代码
  
  上面两个函数最重要想法就是按照层级去查找,只有该层级中有 type 为 a 时,则数量加 1,并只对 type 为 a 的节点的子节点进行后续的计算。所以就可以查出在两个节点相连时,相邻的节点type为a的最长数量是多少。
  
  以上就是这次分享的内容,希望对大家有所帮助。
  
  比如数据总线有32位,它访存只能4个字节4个字节地进行。 0-3,4-7,8-11,12-15,…… 即使我们需要的数据只占一个字节,也是一次读取4个字节。 一个字节的数据不管地址是什么,都能通过一次访存读取出来。 而如果要读取的数据是一个字节以上,比如两个字节, 如果该数据的内存地址是0x03,则需要两次才能读取该数据, 第一次读0x00-0x03,第二次读0x04-0x07。 这个数据就跨越了访存边界。而相对CPU的运算来说,访存是非常慢的,所以要尽量减少访存次数。 为了减少跨越访存边界的数据引起的访存开销, 所以编译器会进行内存对齐,即把变量的地址做一些偏移, 目的是一次访存就读出数据,不然的话也要以尽可能少地访存次数读出数据。如上一个例子中那样,整型成员i的地址做4个字节的偏移, 而Sample对象的地址也会做4字节边界的对齐, 这样i的地址始终是4的倍数,从而使得i不跨越访存边界, 能一次读出它的值。
  
  <dependencies>
  
  <!--###############时间日期操作################-->
  
  <dependency>
  
  <groupId>joda-time</groupId>
  
  <artifactId>joda-time</artifactId>
  
  </dependency>
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
  
  </dependency>
  
  <dependency>
  
  <groupId>cn.hutool</groupId>
  
  <artifactId>hutool-all</artifactId>
  
  </dependency>
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter<www.xintiandiyule1.com /artifactId>
  
  </dependency>
  
  <!--###############springboot-aop模块################-->
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-aop</artifactId>
  
  </dependency>
  
  <!--###############test模块################-->
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-test</artifactId>
  
  <scope>test</scope>
  
  </dependency>
  
  <!--###############web模块################-->
  
  <dependency>
  
  <groupId>org.www.haishenggw.com springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-www.zheshengyule.com web</artifactId>
  
  </dependency>
  
  <!--###############lombok################-->
  
  <dependency>
  
  <groupId>org.projectlombok</groupId>
  
  <artifactId>lombok</artifactId>
  
  </dependency>
  
  <!--fast json-->
  
  <dependency>
  
  <groupId>com.alibaba<www.hongyaoyuL.cn /groupId>
  
  <artifactId>fastjson</artifactId>
  
  </dependency>
  
  <dependency>
  
  <groupId>com.google.guava</groupId>
  
  <artifactId>guava<www.jintianxuesha.com /artifactId>
  
  </dependency>
  
  </dependencies>
  
  基于maven dependencyManagement 版本控制如下:
  
  <dependencyManagement>
  
  <dependencies>
  
  <dependency>
  
  <groupId>org.springframework.boot<www.fengmingpt.com /groupId>
  
  <artifactId>spring-boot-dependencies</artifactId>
  
  <version>2.1.2.RELEASE</version>
  
  <type>pom</type>
  
  <scope>import</scope>
  
  </dependency>
  
  <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  
  <dependency>
  
  <groupId>mysql</groupId>
  
  <artifactId>mysql-connector-java</artifactId>
  
  <version>5.1.48</version>
  
  </dependency>
  
  <dependency>
  
  <groupId>cn.hutool</groupId>
  
  <artifactId>hutool-all<www.fengminpt.cn /artifactId>
  
  <version>4.5.16</version>
  
  </dependency>
  
  <!--mybatis-->
  
  <dependency>
  
  <groupId>org.mybatis.www.jiuhaoyulept.com spring.boot</groupId>
  
  <artifactId>mybatis-spring-boot-starter</artifactId>
  
  <version>2.0.0</version>
  
  </dependency>
  
  <!--fast json-->
  
  <dependency>
  
  <groupId>com.alibaba</groupId>
  
  <artifactId>fastjson</artifactId>
  
  <version>1.2.56</version>
  
  </dependency>
  
  <!-- druid -->
  
  <dependency>
  
  <groupId>com.alibaba</groupId>
  
  <artifactId>druid-spring-boot-starter</artifactId>
  
  <version>1.1.9</version>
  
  </dependency>
  
  <dependency>
  
  <groupId>com.google.guava</groupId>
  
  <artifactId>guava<www.jiuhaozhuce.cn /artifactId>
  
  <version>19.0</version>
  
  </dependency>
  
  </dependencies>
  
  </dependencyManagement>
  
  Sample1占多少空间呢?仍然是8个字节。 a在第0个字节,b在第1个字节,i占4-7字节。 这是内存对齐的原则,占用尽量少的内存。 如果在b之后,还有char类型的成员c和d,同样是占8个字节。 a,b,c,d在0-3字节。

原文地址:https://www.cnblogs.com/dakunqq/p/11443718.html

时间: 2024-10-07 17:41:02

在vue中通过使用$attrs实现组件之间的数据传递的相关文章

Vue 爬坑之路(二)—— 组件之间的数据传递

Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,components 文件夹下都是子组件. 一.父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据. 子组件部分: 这是 header.vue 的 HTML 部分,logo 是在 data 中定义的变量. 如果需要从父组件获取 logo 的值,就需要使用 props: ['lo

vue组件之间的数据传递

Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,components 文件夹下都是子组件. 一.父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据. 子组件部分: 这是 header.vue 的 HTML 部分,logo 是在 data 中定义的变量. 如果需要从父组件获取 logo 的值,就需要使用 props: ['lo

Vuex 组件之间的数据传递

在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用  props 或者 $emit 等方式 http://www.cnblogs.com/wisewrong/p/6266038.html 但是如果是大型项目,很多时候都需要在子组件之间传递数据,使用之前的方式就不太方便.Vue 的状态管理工具 Vuex 完美的解决了这个问题. 一.安装并引入 Vuex 项目结构: 首先使用 npm 安装 Vuex cnpm install vuex -S 然后在 main.js 中引入

Vue2.x 兄弟组件之间的数据传递

兄弟组件之间的数据传递 思路:创建三个组件分别是<my-aaa>.<my-bbb>.<my-ccc>,在<my-ccc>中接收<my-aaa>与<my-bbb>发送的数据,当改变<my-aaa>或<my-bbb>所发送的数据时,<my-ccc>接收的数据也随之改变 html <body> <div id="box"> <my-aaa></

react.js从入门到精通(五)——组件之间的数据传递

一.组件之间在静态中的数据传递 从上面的代码我们可以看出,两个组件之间的数据是分离,但如果我们有某种需求,将数据从一个组件传到另一个组件中,该如何实现? 场景设计: 将Home.js中的HomeData传递到MyScreen.js中 import React,{ Component } from 'react' import MyScreen from "./MyScreen"; class Home extends Component { constructor(props) { s

vue2.0 组件之间的数据传递

组件间的数据传递// 父组件<template><div class="order"><dialog-addpro v-on:closedialog="close" :proinfo="proinfo"></dialog-addpro></div></template><script>import daddpro from '../../daddpro' expo

Vue(5)- 子父级组件之间的数据传递

父组件 向 子组件 传递数据 1 Parent.vue 文件 2 3 <template> 4 <div> 5 <h2>Parent Component</h2> 6 <p> 7 <Child :ParentToChild="ParentToChildMsg" /> 8 </p> 9 </div> 10 </template> 11 12 <script> 13 im

Vue中利用$emit实现子组件向父组件通信

Vue中利用$emit实现子组件向父组件通信 父组件 <template> <div> <p>我是父组件</p> <child :isShow="show" @hidechild="hidechild"></child> <button @click="show=true">显示子组件</button> </div> </templa

Vue组件注册与数据传递

父子组件创建流程 1.构建父子组件 1.1 全局注册 (1)构建注册子组件 //构建子组件child var child = Vue.extend({ template: '<div>这是子组件</div>' }); //注册名为'child'的组件 Vue.component('child',child); (2)构建注册父组件 //构建父组件parent,在其中嵌套child组件 var parent = Vue.extend({ template: '<div>这