在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字节。

猜你喜欢

转载自www.cnblogs.com/dakunqq/p/11443718.html