Vue3中的Provide / Inject

347 阅读1分钟

一般我们从父组件向子组件传递数据时,我们使用 props,但是如果有一些深度嵌套的组件中,孙子级组件需要获取最高级父辈组件的数据时,使用props可能会不太方便,这时候就可以使用Provide / Inject了,两者都只能在当前活动实例的 setup() 期间调用。

Provide:父组件使用;

Inject:子组件使用;

1、 在父组件setup中(setup可使用语法糖):

    let verse="不识庐山真面目,只缘身在此山中";
    provide('parentVerse',verse);
    let person={name:'李白',age:23};
    provide('parentPerson',person);
    let updateVerse=()=>{
      verse="安得广厦千万间,大庇天下寒士俱欢颜";
    }
    provide('updateVerse',updateVerse);

    let updatePerson=()=>{
      person={name:'王维子',age:25};
    }
    provide('updatePerson',updatePerson);

在子组件内:

    <h3>{{childrenVerse}}</h3>
    <h3>{{childrenPerson.name}}——{{childrenPerson.age}}</h3>
    <button @click="childrenUpdateVerse">点我换诗句</button>
    <button @click="childrenUpdatePerson">点我换人</button>
    
    let childrenVerse=inject('parentVerse');
    let childrenPerson=inject('parentPerson');
    let childrenUpdateVerse=inject('updateVerse'),childrenUpdatePerson=inject('updatePerson');
    return{
        childrenVerse,
        childrenPerson,
        childrenUpdateVerse,
        childrenUpdatePerson
    }

此时可以在页面上看到相应的内容输出,但是点击更新却没效果。下面把他们换成响应式的数据。

2、 在父组件setup中改为

    let verse=ref("不识庐山真面目,只缘身在此山中");
    provide('parentVerse',verse);
    let person=reactive({name:'李白子',age:23});
    provide('parentPerson',person);

    let updateVerse=()=>{
      verse.value="安得广厦千万间,大庇天下寒士俱欢颜";
    }
    provide('updateVerse',updateVerse);

    let updatePerson=()=>{
      person.name='王维子';
      person.age=25;
    }
    provide('updatePerson',updatePerson);

此时可以看到点击按钮数据更新了。

如果不想数据被更改,可添加readonly。 如:

let verse=ref("不识庐山真面目,只缘身在此山中"); provide('parentVerse',readonly(verse));

注释:事件行为写在父组件内最好。