【vue】组件之间通过provide/inject共享数据
组件之间共享数据的方式常用的有:1, props 属性传递数据2, emit 事件 a:全局的eventHub机制 b: 父组件调用子组件使用v-on:eventName="handleFunc",子组件在需要的时候调用this.$emit(eventName, params)即可。3, vuex4, ref 父组件给子组件添加一个ref引用,<child-compo...
组件之间共享数据的方式常用的有:
1, props 属性传递数据
2, emit 事件
a: 全局的eventHub机制
b: 父组件调用子组件使用v-on:eventName="handleFunc"
,子组件在需要的时候调用this.$emit(eventName, params)
即可。
3, vuex
4, ref 父组件给子组件添加一个ref引用,<child-component ref=”child“ />
直接通过this.$refs.child
获取到子组件实例对象。 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素。
5, $parent / $children 当前组件的父组件 和子组件
6, 通过provide 和 inject 来实现共享数据
provide 和 inject 类似于react的 Context共享数据, 父组件 与【子孙】组件而不只是子组件共享,有跨层级。
假定我们有3个组件。 Parent -> Child -> GrandSon 分别为父组件,子组件,孙子组件。
其实基础的用法都知道,在父组件Parent里面这样写:
import Child from './Child'
export default {
name: 'Parent',
provide: {
nameFromParent: 'Kevin'
}
components: {
Child
}
}
在GrandSon组件里面这样写[Child组件的调用忽略]:
export default {
inject: ['nameFromParent'],
mounted () {
console.log(this.nameFromParent, 'nameFromParent')
}
}
这样在加载GrandSon组件的时候会发现this.nameFromParent的值为Kevin,和父组件里面的定义的一致。
但是实际需求肯定没有这么简单,往往我们需要的是共享父组件里面的动态数据,这些数据可能来自于data 或者 store。 就是说父组件里面的数据发生变化之后,需要同步到子孙组件里面。这时候该怎么做呢?
我想的是将一个函数赋值给provide的一个值,这个函数返回父组件的动态数据,然后在子孙组件里面调用这个函数。
实际上这个函数存储了父组件实例的引用,所以每次子组件都能获取到最新的数据。代码长下面的样子:
Parent组件:
<template>
<div class="parent-container">
Parent组件
<br/>
<button type="button" @click="changeName">改变name</button>
<br/>
Parent组件中 name的值: {{name}}
<Child v-bind="{name: 'k3vvvv'}" />
</div>
</template>
<style scoped>
.parent-container {
padding: 30px;
border: 1px solid burlywood;
}
</style>
<script>
import Child from './Child'
export default {
name: 'Parent',
data () {
return {
name: 'Kevin'
}
},
methods: {
changeName (val) {
this.name = 'Kev'
}
},
provide: function () {
return {
nameFromParent: this.name,
getReaciveNameFromParent: () => this.name
}
},
// provide: {
// nameFromParent: this.name,
// getReaciveNameFromParent: () => this.name
// },
components: {
Child
}
}
</script>
Child组件
<template>
<div class="child-container">
Child组件
<br/>
<GrandSon />
</div>
</template>
<style scoped>
.child-container {
padding: 30px;
border: 1px solid burlywood;
}
</style>
<script>
import GrandSon from './GrandSon'
export default {
components: {
GrandSon
}
}
</script>
GrandSon组件:
<template>
<div class="grandson-container">
Grandson组件
<br/>
{{nameFromParent}}
<br/>
{{reactiveNameFromParent}}
</div>
</template>
<style scoped>
.grandson-container {
padding: 30px;
border: 1px solid burlywood;
}
</style>
<script>
export default {
inject: ['nameFromParent', 'getReaciveNameFromParent'],
computed: {
reactiveNameFromParent () {
return this.getReaciveNameFromParent()
}
},
watch: {
'reactiveNameFromParent': function (val) {
console.log('来自Parent组件的name值发生了变化', val)
}
},
mounted () {
console.log(this.nameFromParent, 'nameFromParent')
}
}
</script>
点击 改变name 按钮,查看效果如下:
第一个kevin 是来自于非响应式的 provide变量 nameFromParent
第二个来自于reactiveNameFromParent
,随着祖先组件变化而变化了
更多推荐
所有评论(0)