vue provide/inject

188 阅读2分钟

provideinject 是 Vue.js 中用于父组件向子组件传递数据的一种高级技术。它们提供了一种依赖注入的方式,允许父组件在其整个组件树中传递数据给后代组件,而不需要显式地通过 props 逐层传递。

下面是关于 provideinject 的详细介绍、具体代码示例、注意点和如何使其变成响应式的解释:

  1. provideinject 的作用:

    • provide:在父组件中使用 provide 选项,可以注册一个数据或方法,供其子孙组件访问。
    • inject:在子组件中使用 inject 选项,可以接收父组件提供的数据或方法。
  2. 代码示例: 下面是一个简单的示例,展示了如何使用 provideinject 传递数据:

    htmlCopy code
    <template>
      <div>
        <child-component></child-component>
      </div>
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      components: {
        ChildComponent
      },
      provide() {
        return {
          message: 'Hello from parent'
        };
      }
    };
    </script>
    

    子组件 ChildComponent 中使用 inject 接收父组件提供的数据:

    <template>
      <div>
        <p>{{ injectedMessage }}</p>
      </div>
    </template>
    
    <script>
    export default {
      inject['message']
    };
    </script>
    

    在上述示例中,父组件使用 provide 选项提供了一个名为 message 的数据,其值为 'Hello from parent'。子组件 ChildComponent 使用 inject 选项接收了父组件提供的 message 数据,并将其显示在模板中。

  3. 注意点:

    • provideinject 并不是响应式的,即父组件数据的更新不会自动触发子组件的更新。因此,不建议在 provide 中提供可变的响应式数据对象。
    • provideinject 的使用应谨慎,因为它们引入了隐式的依赖关系,使得组件之间的关系不够明确。建议在合适的情况下使用,例如在跨层级的组件通信或共享数据时。
    • provideinject 的键名是字符串或符号类型,且必须一致。请注意避免与 Vue 内置的属性或方法名称冲突。
  4. 如何使其变成响应式:

    vue2中解决方法 provide 属性值 message 变成 一个函数

    // 父组件
    provide() { 
        return {
            message: ()=> this.message;
        }; 
    }
    
    // 子组件
    export default {
        inject['message'],
        computed: {
            messageObj(){
                return this.message();
            }
        }
    }
    

    vue3中解决方法

    • 如果需要在 provide 中提供一个响应式的数据对象,可以使用 vuereactiveref 函数将其包裹。
    • 在父组件中,使用 provide 提供一个包含响应式数据的对象。
    • 在子组件中使用 inject 接收父组件提供的对象,并使用响应式数据。
    htmlCopy code
    <template>
      <div>
        <child-component></child-component>
      </div>
    </template>
    
    <script>
    import { provide, reactive } from 'vue';
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      components: {
        ChildComponent
      },
      setup() {
        const state = reactive({
          message: 'Hello from parent'
        });
    
        provide('state', state);
    
        // 可以通过修改 state 中的属性来触发响应式更新
        setTimeout(() => {
          state.message = 'Updated message from parent';
        }, 2000);
      }
    };
    </script>
    

    子组件 ChildComponent 中接收父组件提供的响应式数据:

    htmlCopy code
    <template>
      <div>
        <p>{{ injectedState.message }}</p>
      </div>
    </template>
    
    <script>
    import { inject } from 'vue';
    
    export default {
      setup() {
        const injectedState = inject('state');
        return {
          injectedState
        };
      }
    };
    </script>
    

在上述示例中,父组件使用 reactive 函数将包含响应式数据的 state 对象创建为响应式的。然后,使用 provide 提供了一个名为 'state' 的键,并将 state 对象作为值传递给子组件。子组件 ChildComponent 使用 inject 接收了父组件提供的 state 对象,并在模板中显示了 state.message 的值。当父组件中的 state.message 改变时,子组件会响应式地更新。