vue3组件跨层级数据共享provide 和 inject

发布于:2024-12-06 ⋅ 阅读:(34) ⋅ 点赞:(0)

在 Vue 3 中,provideinject 是一对组合式 API,用于在组件树中进行跨层级的数据共享,而无需通过 propsemit 逐层传递。

使用场景

  • 当祖先组件需要向后代组件共享数据,而中间层组件不需要参与时。
  • 当数据需要在多个不直接相关的组件之间共享时。

provideinject 的基本用法

1. 在祖先组件中使用 provide

provide 用于定义要共享的数据。

import { provide } from 'vue';

export default {
  setup() {
    const sharedData = 'Hello from parent';
    provide('sharedKey', sharedData); // 提供数据

    return {};
  }
};
  • provide 接收一个键值对,'sharedKey' 是键,sharedData 是值。
  • 这个数据会被共享到组件树中的后代组件。
2. 在后代组件中使用 inject

inject 用于接收祖先组件提供的数据。

import { inject } from 'vue';

export default {
  setup() {
    const sharedData = inject('sharedKey'); // 接收数据
    console.log(sharedData); // 输出 "Hello from parent"

    return { sharedData };
  }
};
  • 如果提供的键不存在,inject 会返回 undefined,你可以提供默认值:
    const sharedData = inject('sharedKey', 'Default Value');
    

响应式支持

  1. 非响应式数据
    默认情况下,通过 provideinject 共享的数据是非响应式的。如果需要响应式,应该显式使用 Vue 的响应式 API。

    import { provide, reactive } from 'vue';
    
    export default {
      setup() {
        const sharedData = reactive({ message: 'Hello from parent' });
        provide('sharedKey', sharedData); // 提供响应式数据
    
        return {};
      }
    };
    

    后代组件:

    import { inject } from 'vue';
    
    export default {
      setup() {
        const sharedData = inject('sharedKey');
        console.log(sharedData.message); // 响应式:改变父组件的 message 会同步
    
        return { sharedData };
      }
    };
    
  2. 仅需要响应式引用
    如果只想共享响应式引用而非整个对象,可以使用 ref

    import { provide, ref } from 'vue';
    
    export default {
      setup() {
        const count = ref(0);
        provide('countKey', count);
    
        return {};
      }
    };
    

注意事项

  1. 作用域

    • 数据只能在 provideinject 所在的组件树内使用。
    • 如果后代组件超出了提供组件的作用域,则无法访问该数据。
  2. 非响应式问题

    • 共享的是普通变量时,更新变量不会自动触发视图更新。
    • 如果需要响应式,确保使用 reactiveref
  3. 多层嵌套组件

    • inject 会自动查找最近的 provide

高级用法

  1. 多个数据提供
    你可以在 provide 中提供多个值:

    provide('key1', value1);
    provide('key2', value2);
    
  2. 函数作为值
    你可以通过函数来动态计算数据:

    provide('getMessage', () => 'Dynamic Message');
    

    后代组件:

    const getMessage = inject('getMessage');
    console.log(getMessage()); // 调用函数获取值
    

总结

  • provideinject 提供了一种简单的方式在 Vue 组件树中实现跨层级数据共享。
  • 它们避免了 props 和事件的逐层传递,适合管理全局状态或共享逻辑。
  • 对于复杂的场景,Vue 提供的 PiniaVuex 可能是更好的选择。

网站公告

今日签到

点亮在社区的每一天
去签到