Vue插槽的父子通信

312 阅读2分钟

场景一 简单的父组件给所有插槽子组件传值

当我们父组件的属性想传递给插槽里面的所有属性的时候。如果我们使用props是实现不了的,因为无法将属性通过一个插槽挂载给所有子组件,

如以下场景,我们的父组件有属性col,我希望所有的子组件拿到这个属性,然后通过这个属性做出样式变更

 <RadioGroup v-model="value"  col>
                <Radio  value="10" label="第一个选项"></Radio>
                <Radio  value="11" label="第二个选项"></Radio>
                <Radio  value="12" label="第二个选项"></Radio>
                <Radio  value="13" label="第二个选项"></Radio>
</RadioGroup>

在radio组件内部是插槽的方式

  <slot ></slot>

于是我们会想到provide,inject;

provide(col,'col'//父组件注入
inject(col,"col")//子组件引入  
  

场景二 困难模式父组件调用插槽内子组件的方法

父组件希望调用所有子组件的某个方法,比如说form组件希望调用每一个formItem的规则校验,父组件如何拿到子组件的方法

如果是在正常场景不是插槽,我们会想到ref,但是不可能使用的时候每一个formItem都挂载一个ref,props只能拿到我们在子组件初始定义的属性,于是我们尝试用Vue响应式和provide、inject来解决这个问题

步骤一

父组件定义一个reactive对象。然后注入一个方法,这个方法当我子组件的proxy对象上有东西的时候就将子组件给响应式对象

const publicChildren = reactive([]);
const link = (child) => {
    if (child.proxy) {
        console.log(child.proxy, 'child.proxy');
        console.log(publicChildren, 'publicChildren1');
        publicChildren.push(child.proxy);
        console.log(publicChildren, 'publicChildren12');
    }
};
provide('demo', {
    link,
});
步骤二

子组件需要注入依赖,如果依赖有东西,调用父组件的parent.link(),然后将我们的方法挂载在proxy对象上,也不一定需要挂载在proxy对象,只要挂载让publicChildren可以push之后访问就行,

let parent = inject('demo', null);
console.log(parent);
let mylove = () => {
    console.log('mylove');
};
if (parent) {
    const instance = getCurrentInstance();
    console.log(instance, 'instance');
    parent.link(instance); // 这会将子组件实例链接到父组件
    if (instance) {
        instance.proxy.mylove = mylove; // 将方法挂载到 proxy 上
    }
}
步骤三

父组件获取子组件方法

publicChildren[0].mylove();  
小小知识点
let a = reactive({});
console.log(a, 'ssssssssss');//{name:"1111"}
a.name = '111';