vue3和vue2 之 provide/inject 用法区别 ---vue3组件间通讯2

一、为什么用他们?

 provide/inject 主要用于父组件和子孙组件间通讯,不用在父传子,子传孙,孙传重孙等数据传递了(解决了Prop 逐级透传问题)。简单的父子组件间传值还是使用props、emits或是defineProps、defineEmits、defineExpose比较方便。

二、原理 与 区别

父组件中提供数据,并在其后代的组件树,无论层级有多深,都可以中注入这些数据,从而实现了组件之间的数据传递。。

1. 在vue2中,组件实例方法和属性的继承是通过原型链来实现。

  • 当一个组件通过 provide 提供数据,它会将这些数据添加到其原型链上,然后子组件通过 inject 可以在原型链上查找并访问这些数据。
  • vue 会遍历父组件链,通过匹配provide( key,value)和inject(key,default [可选])的 key 来确定所提供的值。如果父组件链上多个组件对同一个 key 提供了值,那么离得更近的组件将会“覆盖”链上更远的组件所提供的值。如果没有能通过 key 匹配到值,inject() 将返回 undefined,除非提供了一个默认值。

2. 在 Vue 3 中 组件不再依赖于原型链,而是 引入了 Composition API,直接导出给组件实例。

  • provide 是在父组件中使用的选项,它是一个函数,会在父组件实例上创建一个名为 _provided 的对象。_provided 对象存储了提供给子组件的数据,而且这些数据会在整个组件树中可用,子组件可以通过inject选项来访问这些数据。
  • 当子组件访问通过inject注入的数据时,Vue 3会在组件树中向上搜索父组件,一旦找到包含提供数据的组件,Vue 3会从该组件的_provided属性中获取相应的数据。
  • 如果提供的数据是响应式的,子组件将自动成为这些数据的依赖,当提供的数据发生变化时,子组件将被通知并进行更新。 

三、使用方式

1. vue2中的使用

父组件:

// 1. 对象形式
export default{
 
 provide:{
 
  info:"哈哈哈"
 
 }
 
}

//2. provide 需要使用 data 内的数据(访问组件实例 property)时,需要将 provide 转换为返回对象的函数。
export default{
    data() {
        return {
            msg: "哈哈哈"
        };
    },
    provide() {
        return {
            info: this.msg //提供祖先组件的实例
        };
    },
}

后代组件:

// 1. 
export default{
 
 inject:['info'],
 
 mounted(){
     console.log("接收数据:", this.info) // 接收数据:哈哈哈
 }
 
}

//2. 或者 对象形式
<template>
  <div>
    <P>姓名:{{info.msg}}</P>
  </div>
</template>

<script>
export default {
 inject: {
  info: {
      from: 'info', // 当声明注入的默认值时,必须使用对象形式,与原注入名同名时,这个属性可选 
      default: 'default value'
  }
 } 
};
</script>

2. vue3中的使用

父组件:

//1. 
<script>
import { provide } from "vue"

export default {
  setup(){
    provide('info',"哈哈哈");

    provide('changeSubmitLoading', (val) => {
      submitLoading.value = val
    })
  }
}
</script>


// 2. 添加响应性
<script setup>

import { provide, ref } from 'vue'

const location = ref('哈哈哈')

function updateLocation() {
  location.value = '吼吼吼'
}

provide('location', {
  location,
  updateLocation
})
</script>

后代组件:

// 1. 
<template> 
 {{info}}
</template>

<template #cell="{ record }">
 <a-button size="mini" type="text"  @click="handleDelete(record)">
 </a-button>
</template>

<script>
import { inject } from "vue"
 
export default {
  setup(){
    const info = inject('info')
    const changeSubmitLoading = inject('changeSubmitLoading')
    
    const handleDelete = (record) => {
       /* 方法内其他内容*/  
       changeSubmitLoading(true)
    }

    return{
      info
    }
  }
} 
</script>

//2. 添加响应性后

<template>
  <button @click="updateLocation">{{ location }}</button>
</template>

<script setup>
import { inject } from 'vue'

const { location, updateLocation } = inject('location')
</script>


相关推荐

  1. Vue2Vue3组件通信方式汇总(3)------$bus

    2024-04-09 02:48:02       48 阅读
  2. vue2vue3区别

    2024-04-09 02:48:02       34 阅读
  3. Vue3Vue2区别

    2024-04-09 02:48:02       32 阅读
  4. Vue2Vue3区别

    2024-04-09 02:48:02       36 阅读
  5. vue3vue2区别

    2024-04-09 02:48:02       29 阅读
  6. Vue2Vue3区别

    2024-04-09 02:48:02       29 阅读
  7. vue2vue3区别

    2024-04-09 02:48:02       25 阅读
  8. vue2vue3区别

    2024-04-09 02:48:02       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-09 02:48:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-09 02:48:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-09 02:48:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-09 02:48:02       20 阅读

热门阅读

  1. Transformer架构顶层应用的基础知识

    2024-04-09 02:48:02       15 阅读
  2. pyqtgraph 实时更新柱状图

    2024-04-09 02:48:02       15 阅读
  3. SSH常见运维总结

    2024-04-09 02:48:02       15 阅读
  4. 深入了解 STL:强大的编程工具

    2024-04-09 02:48:02       18 阅读
  5. Springboot注解知识-文字描述(学习笔记)

    2024-04-09 02:48:02       13 阅读
  6. D435i发布的话题学习

    2024-04-09 02:48:02       12 阅读