组件通信-跨级通信Provide | Inject

使用 provide/inject ,只需要向后代注入组件本身(this),后代组件中可以无视层级任意访问祖先组件中的状态。

当然它也有缺点:因为 provide/inject 中变量的修改是无法控制的。换句话说,不知道是哪个组件修改了这个全局状态

Vue 的设计理念借鉴了 React 中的单向数据流原则(虽然有 sync 这种破坏单向数据流的家伙),而 provide/inject 明显破坏了单向数据流原则。试想,如果有多个后代组件同时依赖于一个祖先组件提供的状态,那么只要有一个组件修改了该状态,那么所有组件都会受到影响。这一方面增加了耦合度,另一方面,使得数据变化不可控。如果在多人协作开发中,这将成为一个噩梦。

下面我们来看看一个小案列:

我的四个组件 App.vue(祖组件) App.vue下面有一个Navbar.vue 和一个Tabbar.vue 而Tabbar.vue组件下有一个TabbarItem.vue的组件

现在要实现的的功能是在TabbarItem.vue组件中改变Navbar.vue组件中的值

App.vue

html 复制代码
<template>
  <div>
    <Navbar :nvartitle="nvaTitle"></Navbar>
    <Tabbar></Tabbar>
  </div>
</template>
<script>
import Navbar from "./components/Navbar.vue" //导入AChild组件模板
import Tabbar from "./components/Tabbar.vue";
export default {
  inheritAttrs: false,
  data() {
    return {
      nvaTitle:"首页"
    }
  },
  components: {
    Navbar,
    Tabbar
  },
  provide(){
    return{
      myNvarTitle:this.nvaTitle, //向外提供一个值(可以供其他组件可以直接获取到)
      app:this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
      appMythod:this.MyAppMethod  //向外提供一个方法。
    }

  },
  methods: {
    MyAppMethod(){
      console.log("我的根组件中的方法")
    }
  }
}
</script>
<style>
#app{
  width: 100%;
  max-width: 95%;
}
* {
  margin: 0px;
  padding: 0px
}

ul {
  list-style: none;
}
body{
  display:block
}
</style>

Navbar.vue

html 复制代码
<template>
    <div>
        <button>返回</button>
        <span>{{app.nvaTitle}}</span>
        <button>首页</button>
    </div>
</template>
<script>
export default {
    props:["nvartitle"],
    inject:["myNvarTitle","app"],//在App.vue根组件中通过provide向外提供了一个myNvarTitle,和app的值,我们可以通过注入的方式获取
    components: {
    }
}
</script>
<style scoped>
div {
    display: flex;
    width: 100%;
    justify-content: space-between;
    height: 50px;
    line-height: 50px;
    background: gray;

}
</style>

Tabbar.vue

html 复制代码
<template>
    <ul>
        <TabbarItem v-for="item in datalist" :key="item" :itemStr="item"></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

html 复制代码
<template>
    <li @click="handelClick">
        {{ itemStr }}
    </li>
</template>
<script >
export default {
    props: ["itemStr"],
    inject: ["app","appMythod"],//在App.vue根组件中通过provide向外提供了一个app的值和一个appMythod的方法,我们可以通过注入的方式获取
    methods: {
        handelClick() {
            this.app.nvaTitle = this.itemStr //这个app就是根组件,根组件中有一个nvaTitle的对象,我们可以重新给他赋值,它的值变化后就会自动流向需要这个值的子组件。
            this.appMythod(); //直接调用跟组件中的方法。
        }
    }
}
</script>
相关推荐
开开心心就好2 天前
卸载工具清理残留,检测垃圾颜色标识状态
linux·运维·服务器·python·安全·tornado·1024程序员节
子燕若水3 天前
Facebook reels 运营指南
1024程序员节
尘觉6 天前
创作 1024 天|把热爱写成长期主义
数据库·1024程序员节
写点什么呢7 天前
Word使用记录
word·1024程序员节
开开心心就好7 天前
内存清理工具点击清理,自动间隔自启
linux·运维·服务器·安全·硬件架构·材料工程·1024程序员节
开开心心就好8 天前
内存清理工具开源免费,自动优化清理项
linux·运维·服务器·python·django·pdf·1024程序员节
张萌杰11 天前
深度学习的基础知识(常见名词解释)
人工智能·深度学习·机器学习·1024程序员节
开开心心就好12 天前
免费无广告卸载工具,轻便安全适配全用户
linux·运维·服务器·网络·安全·启发式算法·1024程序员节
开开心心就好13 天前
图片格式转换工具,右键菜单一键转换简化
linux·运维·服务器·python·django·pdf·1024程序员节
徐子童15 天前
网络协议---TCP协议
网络·网络协议·tcp/ip·面试题·1024程序员节