Vue组件通讯详解

219 阅读2分钟

逐层传递

父子

属性绑定+props接受
// 父 template内
<子 :自定义属性="父数据"></..>

//子 script内
props:['自定义属性']   
props:{自定义属性:{type/default/required/...}}

//子 template内
<div>
  {{自定义属性}}
</div>

props是只读的,使用场景: 电商 (松耦合)

props命名

​ props: ['postTitle'] ​

$parent
 //子模板: 
$parent.父数据

//子js: 
this.$parent.父数据

使用场景: 通用组件(紧耦合)

子父

自定义事件
//父组件 template
<子 @自定义事件="父方法"></..>

//父组件 script
methods:{
	父方法(数据){梳理}
}

//子组件 template
<div @click="$emit('自定义事件',数据)"></div>
     
//子组件 script
this.$emit('自定义事件',子.数据名)
$children
// 父组件
this.$children[索引].数据|方法

使用场景: 通用组件(紧耦合)

$ref

引用元素(dom,组件<类,函数>)

//父 template
<子 ref="自定义子名称"></..>
<div ref="自定义子名称">
  
</div>

//父 script
 this.$refs.自定义子名称.数据名
 this.$refs.自定义子名称.方法()

refs只会在组件渲染完成之后生效,并且它们不是响应式的,避免在模板或计算属性中访问refs 只会在组件渲染完成之后生效,并且它们不是响应式的,避免在模板或计算属性中访问 refs

兄弟

兄弟A->自定义事件->中间人(父)->props->兄弟B

路由

params,query

越层传递

attrs/attrs/listeners

假设A>B>C三个组件关系,A传递给C,越过中间的B,A作为祖先一定要传递(属性绑定),C作为后代一定要接受(props),中间层所有的组件值负责做二传手的动作,如下

<中间层组件 v-bind="$attrs" v-on="$listeners"></..>

attrs里面包含了所有上层组件传递过来的属性attrs里面包含了所有上层组件传递过来的属性 listeners 里面包含了所有上层组件传递过来的事件

attrs如果中间层组件没有接受props,c的是所有propsattrs 如果中间层组件没有接受props,给c的是所有props listeners 所有中间层组件+后代组件都可触发

provide/inject

祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量

//祖先组件
export default {
  data(){
    return {数据}
  },
  provide: {
    name: '浪里行舟'
    name2: this.data数据
  }
}

//孙组件
export default {
  inject: ['name'],
  mounted () {
    console.log(this.name);  // 浪里行舟
  }
}

使用场景:为高阶插件/组件库提供用例

provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的

集中式管理

订阅发布模式

第三方库

如:pubsub,会在react时讲

公共总线

利用一个空vue实例的事件订阅和发布api实现

//src/main.js
const bus = new Vue()
export default bus;

//组件内部
import bus from '...';
bus.$emit('事件',数据) //发布
bus.$on('事件',(接){处理})	//订阅
bus.$off('事件')	//取消订阅

$root

子组件内部直接找到根实例,访问,操作根data数据

//src/main.js

new Vue({
  data:{key:value}
})

//组件内部
this.$root.key //获取
this.$root.key=value //修改