在前几篇学习笔记里,接触到了props $eimt $parent $root 等方式实现父子组件间的数据传递方式,但是如果遇到层级很多的情况如何处理呢?
provide 和 inject 可以帮助我们解决这一问题。 一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
为组件后代提供数据,使用 provide() 函数。
使用 inject() 函数,注入上层组件提供的数据。
注意:数据相应是由Root到底层组件的,所以inject到子组件的数据如果要响应到provide需要用computed与相应方法组合使用。
演示代码
App.vue
<template>
<Navbar></Navbar>
<Tabbar />
</template>
<script>
import { computed } from 'vue';
import Navbar from './Navbar.vue';
import Tabbar from './Tabbar.vue'
export default {
data() {
return { navTitle: '首页' }
},
components: {
Navbar, Tabbar
},
methods: {
changeTitle(title) {
this.navTitle = title
console.log(this.navTitle)
}
},
provide() {
return {
changeTitle: this.changeTitle,
navTitle: computed(()=>this.navTitle)
}
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
Navbar.vue
<template>
<div>
<button>返回</button>
<span>{{ navTitle }}</span>
<button>首页</button>
</div>
</template>
<script>
export default {
inject:['navTitle']
}
</script>
<style scoped>
div {
display: flex;
width: 100%;
justify-content: space-between;
height: 50px;
line-height: 50px;
background: orange;
}
</style>
Tabbar.vue
<template>
<ul>
<TabbarItem v-for="data in datalist" :key="data" :item="data">{{ data }}</TabbarItem>
</ul>
</template>
<script>
import TabbarItem from './TabbarItem.vue';
export default{
data(){
return{
datalist:["首页","列表","我的"]
}
},
components:{
TabbarItem
}
}
</script>
<style scoped>
ul{
display: flex;
position: fixed;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
}
li{
flex:1;
text-align: center;
}
</style>
TabbarItem.vue
<template>
<li @click="handleClick">{{ item }}</li>
</template>
<script>
import App from './App.vue';
export default {
props: ["item"],
inject: ["changeTitle"],
methods: {
handleClick() {
this.changeTitle(this.item)
}
}
}
</script>