总结一下 vue2 组件之间的通信

start

  • 最近在学习 vue3,在学习 vue3 的 之前。先总结一下,vue2 中的组件之间的通信;

以下示例皆为 vue2

1.父组件传值给子组件,利用 props

父组件 app.vue

<template>
  <div id="app">
    <boxA :name="appName" :age="appAge" />
  </div>
</template>
​
<script>
import boxA from './boxA.vue'
​
export default {
  name: 'App',
  data() {
    return {
      appName: '我是app页面的name',
      appAge: '我是app页面的age 123',
    }
  },
  components: {
    boxA,
  },
}
</script>

子组件 boxA.vue

<template>
  <div class="box">
    我是 A盒子
    <pre>
     我有这些属性:
​
      {{ name }}
    </pre>
  </div>
</template>
​
<script>
export default {
  name: 'boxA',
  props: {
    name: {
      type: String, // 限制类型
      default: '', // 设置默认值
      require: true, // 是否必传
    },
  },
}
</script>

2.子组件和父组件通信 $emit

父组件 app.vue

<template>
  <div id="app">
    主应用
​
    <boxA @say="sayApp" />
  </div>
</template>
​
<script>
import boxA from './boxA.vue'
​
export default {
  name: 'App',
  components: {
    boxA,
  },
  methods: {
    sayApp(value) {
      console.log('hello', value)
    },
  },
}
</script>

子组件 boxA.vue

<template>
  <div class="box">
    <span @click="handleClick">你好</span>
  </div>
</template>
​
<script>
export default {
  name: 'boxA',
  methods: {
    handleClick() {
      this.$emit('say', '输出的参数')
    },
  },
}
</script>

3. 跨多级组件通信

/*新建一个Vue实例作为中央事件总线*/
let event = new Vue()
​
/*监听事件*/
event.$on('eventName', (val) => {
  //......do something
})
​
/*触发事件*/
event.$emit('eventName', 'this is a message.')

4.跨多级组件数据通信

vuex4.

5. 父-》子-》孙 三个层级之间的组件通信 $attrs $listeners

有这么一个场景,组件 A 中有组件 B,组件 B 中有 C。AC 之间通信怎么办?

  • 使用父子通信,B 组件中会有很多冗余代码。
  • 使用事件总线,不太利于管理;
  • 使用 vuex,有点大材小用;

在 vue2.4 版本之后,添加了这么几个属性:

  • $attrs
  • $listeners
$attrs

  • vm 上的属性。所以我们可以直接在组件中,this.$attrs打印出来;
  • 2.4.0 新增的属性;
  • 简单理解就是一个对象。所有父组件传递给子组件的值,当子组件没有用 prop 属性接收,就会存储在this.$attrs中。(class 和 style 除外)

在这里插入图片描述

$listeners
  • vm 上的属性。所以我们可以直接在组件中,this.$listeners打印出来;
  • 2.4.0 新增的属性;
  • 简单理解就是一个对象。所有父组件给子组件绑定到事件会存储在this.$listeners中,(不含 .native 修饰器的)

有什么用?

想象我们的场景:

  1. A 组件和 C 组件通信;
  2. A 传递数据给 B,绑定事件到 B 上。
  3. 可以在 B 中通过 this.$attrsthis.$listeners 拿到数据和事件
  4. 一起传递给 C 组件。

例如:

父组件 app.vue

<template>
  <div id="app">
    <boxA :name="appName" :age="appAge" @fn1="appFn1" @fn2="appFn2" />
  </div>
</template>
​
<script>
import boxA from './boxA.vue'
​
export default {
  name: 'App',
  data() {
    return {
      appName: '我是app页面的name',
      appAge: '我是app页面的age 123',
    }
  },
  components: {
    boxA,
  },
  methods: {
    appFn1(value) {
      console.log('appFn1', value)
    },
    appFn2(value) {
      console.log('appFn2', value)
    },
  },
}
</script>

子组件 boxA.vue

<template>
  <div class="box">
    我是 A盒子
    <pre>
     我有这些属性:
​
      {{ name }}
    </pre>
​
    <!-- !!!这里可以再来一个组件  boxB; 通过 v-bind="$attrs" v-on="$listeners" 就能在boxB中收到数据了-->
    <!-- <boxB v-bind="$attrs" v-on="$listeners"> -->
  </div>
</template>
​
<script>
export default {
  name: 'boxA',
  inheritAttrs: false,
  props: {
    name: {
      type: String, // 限制类型
      default: '', // 设置默认值
      require: true, // 是否必传
    },
  },
  created() {
    console.log(this)
    this.$emit('fn1', '触发父组件第一个函数')
  },
}
</script>

在这里插入图片描述

另外说个其他的小 tips

  • 没有被 父组件传递给子组件的值,如果没有被 props 接受。 默认会展示在 html 的标签上

在这里插入图片描述

可使用 inheritAttrs: false, 隐藏

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lazy_tomato

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值