vue组件通信的几种方式

vue组件通信
  1. 父传子
// 父组件 Parent
<template>
	  <div>
		 <Child1 :title=" '父组件中的值传递给子组件' " /> 
	  </div>
</template>
<script>
import Child1 from '@/components/child1'
export default {
	components: { Child1 }
}
</script>
// 子组件 Child1
<template>
	  <div>
	    	 {{ title }} 
	  </div>
</template>

<script>
export default {
  props:[ 'title' ]
}
</script>

这种方式是最基础、最简单的方式,详情参考官网即可(vuejs-prop

  1. 子传父
// 子组件 Child
<template>
	  <div>
	  	 	<div @click="paramTransfer">点击我传递数据到父组件</div>
	  </div>
</template>

<script>
export default {
	  methods: {
	  		paramTransfer() {
				this.$emit('parensEvent', '子元素中的数据')
			}
	  }
}
</script>
// 父组件
<template>
	  <div>
	      <Child @parentsEvent="eventHandleName" />
	  </div>
</template>

<script>
import Child from '@/components/child'
	export default {
		components: {Child},
		methods: {
			 eventHandleName	(param) {
			      console.log(param) // param就是子组件传递过来的
			 }
	  }
}
</script>

Vue推荐单项数据流,所以子组件想修改父元素传递的数据,需要通知父组件来修改,使用$emit触发父元素传递事件

  1. 兄弟组件通信
//  兄弟组件不能直接通信,只需要通过共同的父元素搭桥即可
  1. 祖先后代 provide & inject
//  父元素(这里的父元素可以是祖先元素,不一定是直接父级)
<template>
  <div>
    <Child1  />
  </div>
</template>

<script>
import Child1 from "@/components/child1"
export default {
  data () {
	return {
		param: { name: '初始化的值' }
	}
  },
  provide: {  // 在祖先组件中定义provide定义变量
    name: '我是祖先组件中的变量'
  },
  // provide () { // 传递一个对象,当对象中的数据变化的时候, 就会响应
  //   return {
  //	  param1: this.param
  //   }
  // }
  components: {Child1}
}
</script>
//  子孙组件
<template>
	  <div>
	    	<p>{{name}}</p>
	  </div>
</template>

<script>
export default {
	  inject: ['name'] // 在子孙组件中通过inject来注入,就可以获取到祖先传递过来的数据了
}
</script>

这里方式适合层级较多的,比如父子间通过props传递元素给子组件,比较简单,如果在App中需要传递一个数据给它的子子孙孙,那props就太麻烦了,这个时候provide & inject 就可以登场了(这个api在官网不推荐的原因是因为,它适合设计组件库,比如在element-ui的源码中就有使用的); 注意(provide & inject不是响应式的, 如果子元素想通知祖先,就需要hack一下, 按照官网所说,如果传递一个对象,那对象中的的数据还是可以响应的), 还有一点需要注意,在组件中要获取provide 要通过 this._provided才能拿到

  1. dispatch 子元素向祖先传递数据
main.js
// 使用该方法,需要使用辅助方法,并将辅助方法挂在到Vue原型上
// dispatch的用法,(下面这个方法可以实现,也可以参照element-ui的写法)
Vue.prototype.$dispatch = function (eventName, data) {
  // 递归查找父级, 向上传递
  let parent = this.$parent
  while (parent) { // 查找父元素是否存在
    parent.$emit(eventName, data) // 如果存在,则父元素用emit触发事件,并传参,这里的parent就是一个Vue实例
    parent = parent.$parent // 递归调用,如果父级存在,那就要把父级赋值给parent,
  }
}
传递参数的子组件
<template>
    <div class="btn" @click="clickNoticeApp">
   		 我是child1子组件,点击我的时候,传递一个参数到App.vue中,是我的祖先元素
    </div>
</template>
<script>
export default {
  methods: {
    clickNoticeApp () {
      this.$dispatch('dispatchName', '你好App,我是child1中传递过来的数据')
    }
  }
}
</script>
接收参数的祖先元素
export default {
  name: 'App',
  data () {
    return {
      msg: ''
    }
  },
  mounted () {
    this.$on('dispatchName', mes => {
      this.msg = mes // mes就是子组件传递过来的数据了
    })
  }
}
  1. boardcast 祖先元素想子元素传递数据
main.js
// boardcast的用法 (下面这个方法可以实现,也可以参照element-ui的写法)
Vue.prototype.$boardcast = function (eventName, data) {
  // 递归调用查找子元素, 向下传递
  boardcast.call(this, eventName, data)
}
function boardcast (eventName, data) {
  this.$children.forEach(child => {
    // child 触发事件并携带参数
    child.$emit(eventName, data)
    if (child) { // 如果子元素存在,则递归调用
      boardcast.call(child, eventName, data)
    }
  })
}
传递参数的祖先元素
<template>
    <div class="btn" @click="clickNoticeChild">我是App中的按钮,点击我传递消息给子孙组件</div>
</template>
<script>
export default {
  name: 'App',
  methods: {
    clickNoticeChild () {
      this.$boardcast('boardcastName', '我是App中的按钮,点击我可以想子元素传递消息')
    }
  }
}
</script>
接受参数的子孙元素
<template>
    <div style="text-align:center; color:green;">{{ message }}</div>
</template>
<script>
export default {
  data () {
    return {
      message: ''
    }
  },
  mounted () {
    this.$on('boardcastName', data => {
      this.message = data
    })
  }
}
  1. event-bus 通过event-bus给子元素或者祖先元素传递数据
main.js
// class Bus {
//   constructor () {
//     this.callbacks = {}
//   }
//   $on (name, fn) {
//     this.callbacks[name] = this.callbacks[name] || []
//     this.callbacks[name].push(fn)
//   }
//   $emit (name, args) {
//     if (this.callbacks[name]) {
      // 存在 遍历所有callback
//       this.callbacks[name].forEach(cb => cb(args))
//     }
//   }
// }

// Vue.prototype.$bus = new Bus()
// 上述是代码是阐述event-bus实现的机制,主要就是通过$on 和 $emit实现,
// 但是在vue中本身就有这两个方法,所以直接实例化vue就可以了

Vue.prototype.$bus = new Vue()
传递数据的组件
<template>
  <div id="app">
    <router-view />
    <div @click="clickEventBus">我是App中的按钮,点击我通过eventBus传递事件</div>
  </div>
</template>
<script>
export default {
  name: 'App',
  methods: {
    clickEventBus () {
      this.$bus.$emit('eventBus', '通过Event-bus传递数据')
    }
  },
}
</script>
接受数据的组件
<template>
  <div>
    我是子组件中,app通过Event-bus传递数据:  {{msg}}
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg: ''
    }
  },
  mounted () {
    this.$bus.$on('eventBus', mes => { // msg就是传递的数据
      this.msg = mes
    })
  }
}
</script>
  1. vuex(这种方式传递数据在项目中运用的也比较多,具体用法参照官网即可,这里就不举例了哈)

最近想把vue的一些知识梳理一下, 希望对大家有所帮助, 还有其他的通讯方式的童鞋,欢迎留言…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值