关于Vue组件之间通信的n种方式

关于Vue组件之间通信的n种方式(全)

1. 父组件向子组件传值(poops)
2. 子组件向父组件传值($emit)
3. 兄弟组件之间传值(eventBus)
4. 父组件操作子组件的实例(ref)
5. $parent 和 $children
6. 跨层级通信provide/inject
7. $attrs 和 $listeners
8. localStorage/sessionStorage
9. Vuex
10.v-model

我是用vue脚手架创建的项目,项目设计目录结构如下:
APP.vue包含三个子组件(children)
children各自包含自己的一个子组件(GrandSon)

在这里插入图片描述

  1. 父组件向子组件传值(poops)最常见
    APP.vue代码:
<ChildrenOne v-bind:value="value"></ChildrenOne>

ChildrenOne代码:

// 接收父组件传递过来的值
  props: ['value']

使用父组件传递过来的value值:

<span>这是父组件APP.vue歘递过来给我的=------{{value}}</span>

2: 子组件向父组件传值($emit)
childrenOne代码:

 <button @click="handleClick">点击按钮给我父亲发点消息</button>
 // .....................省略
 handleClick () {
      // 点击按钮触发事件给父亲发消息
      this.$emit('forMyFather', 'I am your daugther')
    },

App.vue里面进行监听子组件childreOne触发的事件,监听的名字和子组件$emit函数的第一个参数同:

<ChildrenOne v-bind:value="value" @forMyFather="handleClick"></ChildrenOne>
// .........................省略
// 这里直接用父组件在data中定义的变量接收就可以使用了
   handleClick (value) {
      this.fromMyDaugther = value
      console.log(value)
    }

3:兄弟组件之间传值(eventBus)
简要说明:兄弟组件之间需要中间人帮助传值,就是事件总线
事件总线通常是Vue的实例
3.1为了方便直接挂载到Vue原型prototype上面
main.js代码:

// 往后使用可以用this.$bus触发或者监听事件
Vue.prototype.$bus = new Vue()

3.2Chilren1中代码:

<button @click="handleClickOne">给我姐姐发点消息</button>
// ............................省略
// msg定义为一个对象,当触发事件是是可以传递多个值的。,只要放在对象里就可以
data () {
    return {
      msg: {
        msg1: 'to My young Sister',
        msg2: 'you so smart'
      }
    }
  }
  // ............................省略
 handleClickOne () {
      var msg = this.msg
      // 用挂载在Vue原型上面的$bus充当事件总线发送
      this.$bus.$emit('forMySister', { msg })
      console.log(msg)
    }

3.3Children2中相关代码:

mounted () {
    this.$bus.$on('forMySister', msg => {
    // Object.values是可以遍历对象拿到对应值组成的数组的,下列操作就是为了把msg中第一项对应的值拿出来
      this.fromMyYoungSister = Object.values(Object.values(msg)[0])[0] + ' ' + Object.values(Object.values(msg)[0])[1]
      console.log(this.fromMyYoungSister)
    })
  }
// 使用
<h3>这是我妹妹给我传递的消息----{{fromMyYoungSister}}</h3>

4:父组件操作子组件的实例(ref)
可以操作属性和方法(数据是响应式的)
Children2代码:

<!-- 第四种方式:给子组件添加ref属性,让父组件可以获取子组件的所有属性 -->
    <GrandSonTwo ref='forMyFather'></GrandSonTwo>
    // 操作子实例
     mounted () {
      console.log(this.$refs)
      // this.$refs.forMyFather.msg = 'kk'
      this.fromMyChildren = this.$refs.forMyFather.msg
      this.fromMyChildrenOne = this.$refs.forMyFather.SendMyFather()
    })
  }

Grandson2代码:

 data () {
    return {
      msg: '我是孙子组件2'
      // msg2: ''
    }
  }
  // ...........................................
   methods: {
    SendMyFather () {
      var msg1 = '我很快乐'
      return msg1
    }
  }

5:$parent 和 $children
GrandSon1代码:

<button @click='handerClick'>点击我更改父组件的值</button>
// .............................................
 data () {
    return {
      msg: '我要提供一个值给父组件修改'
    }
  },
  methods: {
    handerClick () {
      console.log(this.$parent)
      this.$parent.msg3 = '我修改了父组件的值'
    }
  }

Children1代码:

<button @click="handleClickTwo">点击我用$children修改子组件的值</button>
// ..........................................................
 data () {
    return {
      msg3: '我是即将被子组件修改的值'
    }
  }
// ...................................................
 handleClickTwo () {
      console.log(this.$children)
      this.$children[0].msg = '我修改了子元素的值'
    }

6:跨层级通信provide/inject

 data () {
    return {
      msg: {
        msg1: 'Hello My Grangson'
      }
  }
  // ..................................
  provide () {
    // 里面可以接收对象或者函数
    // provide: {
    // msg: '我是。。。'
    // } // 不是响应式的
    // 普通传值:不是响应式的
    return {
      // 这么给值设置成响应式的呢?
      // 给传递一个可遍历的对象,对象在data中声明,那么值就是可响应的,也就是修改后会影响子组件
      msg1: this.msg
    }
  }

GrandSon2代码:

inject: ['msg1']

使用:

<h4>来自GrandFather的问候--------{{msg1.msg1}}</h4>

7:$attrs 和 $listeners
先一次性给子组件传值(或者函数),然后可以在一次全部的往下传,不用一个个传
APP.vue代码:

<ChildrenThree :messageOne="messageOne" :messageTwo="messageTwo" @test1='test1' @test2='test2'></ChildrenThree>

Children3代码:直接用$attrs就可以接收:

<h4>展示通过attrs传递过来的值{{$attrs.messageOne}}</h4>
     <h4>展示通过attrs传递过来的值{{$attrs.messageTwo}}</h4>
// ......................................
 test1 (value) {
      // var msg5 = '我是test1事件传过去的'
      this.msg6 = value
      // this.test1 = msg5
      // return msg5
    },
    test2 () {
      var msg = '我是test2事件传递过来的'
      return msg
    }

Children3可以再全部往下传给GrandsSon3:

<!-- 通过v-bind可以继续往下传 -->
    <GrandSonThree v-bind="$attrs" v-on='$listeners'></GrandSonThree>

grandSon3代码:

<h5>这是App.vue通过Children3给我传递过来的值-----{{$attrs.messageOne}}</h5>
    <h5>这是App.vue通过Children3给我传递过来的值-----{{$attrs.messageTwo}}</h5>
    <button @click='handlerClick'>利用$listeners操纵父级的父级的数据</button>
    // ................................
     methods: {
    handlerClick () {
      this.$listeners.test1('------------------')
    }
  }

8 localStorage/sessionStorage
localStorage:本地存储
seesionStorage:会话存储

9 Vuex 状态数据管理

10.v-model***
v-model…
页面展示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值