组件通信-跨级通信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 天前
第二十六周机器学习笔记:PINN求正反解求PDE文献阅读——正问题
人工智能·笔记·深度学习·机器学习·1024程序员节
希忘auto5 天前
详解Redis的常用命令
redis·1024程序员节
yaosheng_VALVE5 天前
探究全金属硬密封蝶阀的奥秘-耀圣控制
运维·eclipse·自动化·pyqt·1024程序员节
dami_king5 天前
SSH特性|组成|SSH是什么?
运维·ssh·1024程序员节
一个通信老学姐10 天前
专业125+总分400+南京理工大学818考研经验南理工电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节
sheng12345678rui10 天前
mfc140.dll文件缺失的修复方法分享,全面分析mfc140.dll的几种解决方法
游戏·电脑·dll文件·dll修复工具·1024程序员节
huipeng92611 天前
第十章 类和对象(二)
java·开发语言·学习·1024程序员节
earthzhang202112 天前
《深入浅出HTTPS》读书笔记(19):密钥
开发语言·网络协议·算法·https·1024程序员节
爱吃生蚝的于勒12 天前
计算机基础 原码反码补码问题
经验分享·笔记·计算机网络·其他·1024程序员节
earthzhang202112 天前
《深入浅出HTTPS》读书笔记(20):口令和PEB算法
开发语言·网络协议·算法·https·1024程序员节