「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战」
组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,
- A-B父子关系
- A-C爷孙关系
- B-C父子关系
- C-D兄弟关系
1.通行方式一 props
props父组件A通过props的方式向子组件B传递,$emit是子组件向上传递方法的方式,而props传递下来的单属性,在子组件中是不允许直接修改父组件的属性值的,所以需要借助.sync去和子组件打通通信通道
// parent
<template>
//子组件无法修改父组件传递的属性值
<child :content="content">
//需要修改父组件属性值的时候
<child :content.sync="content">
</template>
// child 承接父组件的属性
props: { content: String }
//调用父组件的方法,实现父子通信,
this.$emit("father",data)
//子组件修改props的值
this.$emit('update:content', data)
2.通行方式二 $emit/$on
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。
$emit相当于抛出组件当中的方法到全局
$on相当于其他组件中可以被调用执行的方法
vm.$emit('JS', '每日一题')
// 触发当前实例上的事件
vm.$on('JS', function say(val) {
// 执行事件并接收回传的参数 console.log('JS, ' + 每日一题) })
3.通行方式三 $attrs/$listeners
attrs和listeners 属性像两个收纳箱,一个负责收纳属性,一个负责收纳事件(不包含props声明过,以及内置特性绑定属性,如class,style等...)
爷孙组件之间通过这种方式实现属性和方法的传递和使用
//一级
<div class="details">
<h1>父组件---{{msg}}</h1>
<myComponent :a="a" :b="b" @name="getname" @age="getage" @gender="getgender" ></myComponent>
</div>
methods: {
getname(e){
window.console.log("name",e) // name 小编
},
getage(){
window.console.log("age")
},
getgender(){
window.console.log("gender")
}
//二级
<div class="child" v-bind="$attrs">
<Son v-on="$listeners"/>
</div>
created () {
window.console.log(this.$listeners) // {name: ƒ, age: ƒ, gender: ƒ}
} ,
//三级
<div class="son" v-bind="$attrs">
<h3 v-on="$listeners"></h3>
<button @click="toname">点击</button>
</div>
data() {
return {
name: "小编"
};
},
created() {
window.console.log(this.$listeners);
},
methods: {
toname() {
this.$listeners.name(this.name);
}
}
4.通行方式四 provide/ inject
provide,inject主要为高阶组件及组件库所用,理解为允许一个祖先组件为其所有子孙组件注入依赖
// parent
<template>
<child />
</template>
provide: {
name: 'JS',
value:'每日一题',
},
// child
inject: {
name: String,
value: String
}
console.log(this.name, this.value) // JS,每日一题