前言
- Vue提供了各种各样的通讯,其中包括兄弟间的通讯和非兄弟间的通讯以及后代之间的通讯,接下来就让我们一一解析吧。如果有喜欢的话可以点赞👍或者关注一下。
目标
- 学习Vue中的组件化通讯方式。
通讯方式
-
props
-
功能说明
- 父组件和子组件传递数据
-
目录结构
components ├── Parent.vue ├── Child.vue -
代码结构
父组件中使用子组件并传给子组件值。foo="foo"
<template> <div> parent comp <Child foo="foo" /> </div> </template> <script> import Child from './child' export default { components: { Child }, } </script>子组件通过props接收父组件传过来的值
<template> <div> child comp {{ foo }} </div> </template> <script> export default { props: { foo: { type: String, default: '' }, }, } </script>
-
-
emit/on
-
功能说明
- 子组件给父组件传值
-
目录结构
components ├── Parent.vue ├── Child.vue -
代码结构
子组件通过$emit触发父组件的方法 ,通过回调参数的方式进行传值
<template> <div> child comp <button @click="add">child 点击</button> </div> </template> <script> export default { methods: { add() { this.$emit('add', 'child add message') }, } } </script>父组件给子组件绑定一个自定义方法$on,接收回调参数。
<template> <div> parent comp <Child @add="add"/> </div> </template> <script> import Child from './child' export default { methods: { add(message) { console.log(message) // 打印child add message } }, components: { Child }, } </script>
-
-
event bus事件总线
-
功能说明
- Event Bus 可用于跨组件通知(简单项目可以使用这种方式)
-
实现方式
-
第一种直接使用Vue作用事件总线来使用
Vue.prototype.$bus = new Vue() -
第二种自定义实现
// 自定义Bus 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]) { this.callbacks[name].forEach((cb) => cb(args)) } } } export default Bus
-
-
目录结构
main.js components ├── Parent.vue ├── Goundson.vue -
代码结构
main.js
Vue.prototype.$bus = new Vue()Goundson.vue,组件使用$emit发送addbus方法并携带参数
<template> <div> goundson comp <button @click="addBus">bus goundson click</button> </div> </template> <script> export default { methods: { addBus() { this.$bus.$emit('addbus', 'add bus message') } }, } </script>Parent.vue 组件使用$on接收addbus方法并接收参数
<template> <div> parent comp </div> </template> <script> export default { mounted() { this.$bus.$on('addbus', (message) => { console.log(message) // 打印add bus message }) } } </script>
-
-
Vuex
-
$parent
-
功能说明
- 子组件可以该组件的父实例和组件
-
目录结构
components ├── Parent.vue ├── Child.vue -
代码结构
Parent.vue 定义参数
<template> <div> parent comp <Child /> </div> </template> <script> import Child from './child' export default { data() { return { baz: 'baz' } }, components: { Child }, } </script>Child.vue 使用$parent获取参数
<template> <div> child comp </div> </template> <script> export default { mounted () { console.log(this.$parent.baz); // baz } } </script>
-
-
$children
-
功能说明
- 父组件可以该组件的子实例和组件,多个子组件的时候是无序的。
-
目录结构
components ├── Parent.vue ├── Child.vue -
代码结构
Child.vue 定义参数
<template> <div> child comp </div> </template> <script> export default { data() { return { bar: 'bar' } } } </script>Parent.vue 使用$children获取参数
<template> <div> parent comp <Child /> </div> </template> <script> import Child from './child' export default { mounted() { console.log(this.$children[0].bar) // bar }, components: { Child }, } </script>
-
-
$root
-
功能说明
- 子组件可以访问该组件的根实例的属性和方法
-
目录结构
components ├── Root.vue ├── Child.vue -
代码结构
Root.vue 定义参数
<template> <div> root comp <Child /> </div> </template> <script> import Child from './child' export default { data() { return { bar: 'bar' } }, components: { Child }, } </script>Child.vue 使用$root获取参数
<template> <div> child comp </div> </template> <script> export default { mounted() { console.log(this.$root.bar) // bar }, } </script>
-
-
$refs
-
功能说明
- ref获取的是真实DOM元素,如果放到组件上就代表的是当前组件的实例。父组件中可以直接获取子组件的方法和数据。
-
目录结构
components ├── Parent.vue ├── Child.vue -
代码结构
Child.vue 定义参数和方法
<template> <div> child comp <button @click="add">child 点击</button> </div> </template> <script> import Goundson from './goundson' export default { data() { return { bar: '' } }, methods: { add() { console.log('child func') }, }, } </script>Parent.vue 使用ref获取参数和方法
<template> <div> parent comp <Child ref="child" /> </div> </template> <script> import Child from './child' export default { mounted() { this.$refs.child.bar = 'barrrrrrr' this.$refs.child.add() // 打印child func }, components: { Child }, } </script>
-
-
Provide/Inject
-
功能说明
- 隔代传参,允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件的层级有多深,并在其上下游关系成立的时间里始终生效。
- 这个方法使用之后会使结构比较混乱一般在开发项目中是不会使用,作用于封装组件库。
-
目录结构
components ├── Parent.vue // 父亲 ├── Child.vue // 儿子1 ├── Goundson.vue //孙子1 -
代码结构
Parent.vue 使用Provide注入数据
<template> <div> parent comp <Child /> </div> </template> <script> import Child from './child' export default { provide() { return { baz: 'baz' } }, components: { Child }, } </script>Child.vue 放入孙子组件
<template> <div> child comp <Goundson></Goundson> </div> </template> <script> import Goundson from './goundson' export default { components: { Goundson, }, } </script>Goundson.vue 孙子组件使用inject 获取注入下来的数据
<template> <div> goundson comp {{ baz }} </div> </template> <script> export default { inject: ['baz'], } </script>
-
-
$attrs
-
功能说明
- 批量向下传入属性。一般不在props定义的属性,都会放在里面。
-
目录结构
components ├── Parent.vue // 父亲 ├── Child.vue // 儿子 -
代码结构
Parent.vue 定义参数并传递给子组件
<template> <div> parent comp <Child :foo="foo" /> </div> </template> <script> import Child from './child' export default { data() { return { foo: 'foo' } }, components: { Child }, } </script>Child.vue 在不定义props时使用$attrs获取参数
<template> <div> child comp {{ $attrs.foo }} </div> </template> <script> export default {} </script>
-
-
$listeners
-
功能说明
- 批量向下传入方法,一般不在methods定义的属性,都会放在里面。
-
目录结构
components ├── Parent.vue // 父亲 ├── Child.vue // 儿子 ├── Goundson.vue // 孙子 -
代码结构
Parent..vue 定义方法
<template> <div> parent comp <Child @some-event="onSomeEvent" /> </div> </template> <script> import Child from './child' export default { components: { Child }, } </script>Child.vue 做展开
<template> <div> child comp <Goundson v-on="$listeners"></Goundson> </div> </template> <script> import Goundson from './goundson' export default { components: { Goundson, }, } </script>Goundson.vue 触发方法
<template> <div> goundson comp <button @click="$emit('some-event', 'some event message')">点击</button> </div> </template> <script> export default {} </script>
-
结语
以上就是全部内容,大部分的通讯方式多用于组件库开发中,欢迎评论指点,一起交流一起进步 🙏🙏🙏🙏。