black

WELCOME

Vue -> 组件通信

组件通信

:v-bind (props) $emit
在父组件中定义一个数据 父->子
data(){
	return {
		message: 'hello world';
	}
}
template中
<child :message="message" />
通过prop属性的方式把message绑定到变量message里面 
在子组件里就可以接受这个prop
props:['message']然后进行使用
template:
{{message}}

在子组件中:  子->父
methods:{
	xxx(){
		this.$emit('aaa','bbb')   
		// bbb是携带的值 当事件触发时 就会把bbb带入到$event这个变量中 赋值给message
		// 所以当事件触发时最终会把message设置为bbb
	}
}
在父组件中就可以监听aaa事件
<child :message="message" @aaa="message = $event"  />
当事件触发最终会把message设置为bbb

回调函数(callback)

也是props + $emit

父组件中: 父->子
data(){
	return {
		message: '';
	}
},
methods:{
	changeMessage(){
		this.message = 'aaa'
	}
}
template:
<child :message="message" :changeMessageFn="changeMessage"  /> 把changeMessage作为另外一个prop传给child
所以此时child就接收message和changeMessageFn两个prop
在子组件中:
props:['message','changeMessageFn']然后进行使用
template:
<button @click="changeMessageFn">按钮</button>
在点击时就可以执行changeMessageFn
$root $parent $children
访问根组件
this.$root.foo 
// 获取根组件的数据/计算属性/方法
// 所有的子组件都可以将这个实例作为一个全局 store 来访问或使用。

在子组件中访问父组件
this.$parent.message

在父组件中访问子组件
this.$children[0].number   
// [0]是因为一个父组件可以有很多子组件
// 当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。

  1. 对于 demo 或非常小型的有少量组件的应用来说这是很方便的。
    不过这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下,我们强烈推荐使用 Vuex 来管理应用的状态。

​ - Vue官方文档

provide + inject 依赖注入

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

provide

选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 SymbolReflect.ownKeys 的环境下可工作。

inject

一个字符串数组 或

一个对象,对象的 key 是本地的绑定名,value 是:

  • 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
  • 一个对象,该对象的:
    • from property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)
    • default property 是降级情况下使用的 value

提示:provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

​ - Vue官方文档

// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}

// 利用 ES2015 Symbols、函数 provide 和对象 inject:
const s = Symbol()

const Provider = {
  provide () {
    return {
      [s]: 'foo'
    }
  }
}

const Child = {
  inject: { s },
  // ...
}

父组件中:
export default{
	provide:{
		message:'aaaa'
	}
}
子组件中:
export default{
	inject:['message']
}
template:
{{message}}

依赖注入还是有负面影响的。它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的 property 是非响应式的。这是出于设计的考虑,因为使用它们来创建一个中心化规模化的数据跟使用 $root做这件事都是不够好的。如果你想要共享的这个 property 是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex这样真正的状态管理方案了。

​ - Vue官方文档

$attrs + $listeners
三级组件: parent child grandchild
$attrs:

parent中:
定义message  并在child中:message="message"
child中:
给grandchild组件绑定
<grandchild v-bind="$attrs">   //$attrs属性包括了parent中传过来的message
grandchild中:
template:
{{$attrs.message}}

$listeners:

parent:
methods:{
	aaa(){
		this.message='aaa'
	}
}
在child标签上定义了一个事件监听器
<child @aaa="aaa">
在child中就可以通过:  
<button @click="$listeners.aaa">按钮</button> 访问到
此时就可以执行绑定的事件处理函数aaa 把name改为aaa  在点击按钮的时候就会修改
ref refs

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。

父组件中:
<child ref="childaaa">
methods:{
	aaa(){
		使用:
		this.$refs.childaaa可以获取到这个组件实例child 就可以访问属性 执行方法
		this.$refs.childaaa.xxx
		this.$refs.childaaa.xxx()
	}
}
// $refs 只会在组件渲染完成之后生效,并且它们不是响应式的。
// 应该避免在模板或计算属性中访问 $refs。

兄弟组件通信

需求:child1点击按钮可以修改数据传到child2中

props + $emit 经过父亲

child1:
使用$emit方式 在父组件中监听发射的事件 然后就可以修改数据值 
父组件中的值修改了 就会传递给child1和child2 所以child2就可以接收数据了 

EventBus = new Vue 不经过父亲 一:$emit 二:监听

main.js中:
export const eventBus = new Vue()  //eventBus实际上就是vue的实例 所以可以在main.js创建并导出
然后就可以在child1中使用eventBus
child1:
eventBus.$emit('aaa','bbb') //因为eventBus是vue实例 所以存在$emit方法 并携带bbb
child2:
created(){
	eventBus.$on('aaa',(name)=>{
		this.name=name   // name为携带的bbb
	})
}

具体的总线学习内容可参见 Vue-EventBus

posted @ 2021-02-20 15:34  微风若里  阅读(70)  评论(0编辑  收藏  举报