Vue中组件间传值总结 ------ 2020-05-17
2020-05-17 本文已影响0人
自己写了自己看
父子组件间传递数据的方式
1、父组件向子组件传递数据
// 1、Vue是单向数据流
// 父组件向子组件传递数据
<son1 :value="mny"/>
// 子组件接收
props:{
value:{
type:Number,
default:1
}
}
2、子组件向父组件传递数据
// 子组件向父组件传递数据,父组件将自己的方法传递给子组件
// 传递原理:组件解析时会将@input="change"解析成 {input: chagne}
// 这种对象形式传递到子组件中,子组件再调用 this.$on()方法,将传
// 递过来的{input: change} 绑定到自己身上,是给子组件绑定方法,然后
// 再通过 this.$emit()触发
<son1 :value="mny" @update="change"/>
this.$emit('input', 200)
3、父子组件相互传递同一数据的两种语法糖
// 父子组件相互传递数据的第一种语法糖
<son1 :value.sync="mny" />
就等于
<son1 :value="mny" @update:value="change"/>
this.$emit('update:val', 200) // 必须用update: [传递过来的值] 触发
// :value.sync="mny" 这种语法在解析时,会解析成,传递了一个属性value[可以自定义]
// 又传递了一个方法,默认是 update:value
// 父子组件相互传递数据的第二种语法糖
<son1 v-model="mny" />
等同于
<son1 :value="mny" @input="mny => this.mny = mny"/>
this.$emit('input', 200);
// v-model="mny" 在解析的时候会解析成:向子组件传递了一个value的属性
// 和input方法
// 使用 .sync 和 v-model 的唯一区别在于,使用 .sync可以修改传递的属性
// 名称,v-model传递的属性必须就是value
4、多层数据传递
// 孙子级组件修改爷爷级组件数据
// 爷爷级组件向父级组件传递数据和给子组件绑定方法
<son1 v-model="mny" />
// 儿子组件触发$on()方法给自己绑定的方法
this.$emit('update:val', 200)
// 孙子组件触发儿子组件的方法,修改爷爷组件的数据
this.$parent.$emit('input', 1000)
// 基于多层数据传递封装的两个方法
Vue.prototype.$dispatch = function (eventName, value) {
let parent = this.$parent;
while(parent) {
parent.$emit(eventName, value);
parent = parent.$parent;
}
}
Vue.prototype.$broadcast = function (eventName, value) {
const broadcast = (children) => {
children.forEach(child => {
child.$emit(eventName, value);
if(child.$children) {
broadcast(child.$children);
}
})
}
broadcast(this.$children)
}
// 注意:$emit()触发的只能是通过组件绑定的事件,也就是$on()绑定的
// 通过methods绑定的是无法触发的
5、通过
listeners 获取父级传递过来的属性和方法\
1、$attrs
1、作用:$attrs 存储的是父级组件传递过来的所有属性,以键值对的形式
存在默认传递,而且这些传递过来的属性,会显示在当前组件的最外层DOM节
点上
<son2 name="jack" sex="meal" :mny="mny"/>
$attrs => { "name": "jack", "sex": "meal", "mny": 100 }
2、如果我们不想让传递的属性显示在DOM节点上,可以给当前组件添加属性:
inheritAttrs: false
3、我们通过$attrs获取属性时,不需要再通过props去注册接收,但是可以去
接收
3、如果我们想将当前组件的 $attrs 继续向下传递,我们可以使用一个语
法糖
<Grandson2 v-bind="$attrs"/>
或者
<Grandson2 v-bind="{name:$attrs.name, sex:$attrs.sex}"/>
或者
<Grandson2 v-bind="{name:1, sex:2}"/> // 传递其他属性
这样就可以将父级传递过来的属性原封不动的传递给自己的儿子,必须使用 v-bind
没有简写了;
2、$listeners
1、作用:$listeners存储的是父级传递过来的所有方法,也是以键值对的形式存在
$listeners => {son: ƒ}
<son2 name="jack" sex="meal" :mny="mny" @son="son"/>
$listeners.son() // 调用
2、继续向下传递:
<Grandson2 v-bind="$attrs" v-on="$listeners"/>
6、通过 provide 和 inject 提供和注入数据
1、provide
1、作用:provide可以将当前组件的数据暴露出去,供儿子级组件注入使用
provide() {
return {'xixi': this} // 键可以随意,this就是当前组件
},
2、inject
inject:[
'xixi' // 必须和父级组件provide的键名相同
],
// 儿子级组件注入父级组件数据后使用方式:
this.xixi.父级数据或者方法
7、通过 ref 获取子组件中的方法并调用
1、ref的用法:用在DOM上是获取DOM元素,用在组件上可以获取组件实例
<son2 name="jack" sex="meal" :mny="mny" @son="son" ref="son2"/>
this.$refs可以以获取到son2这个组件实例,自然就能够获取到son2中的
方法和属性;
8、eventBus
Vue.prototype.$bus = new Vue(); // Vue实例上有 $on 和 $emit 方法
// 在任意组件中通过$on() 绑定方法
this.$bus.$on('gs2', function () {
alert('eventBus')
})
// 任意组件中通过 $emit() 触发方法
this.$bus.$emit('gs2')