美文网首页
[翻译] VUE:如何把slot从父组件传到子组件

[翻译] VUE:如何把slot从父组件传到子组件

作者: 海之方 | 来源:发表于2020-01-16 22:23 被阅读0次

    原文地址: Vue: Pass Slots through from Parent to Child Components

    场景

    有A、B、C三个component,分别包含不同的slot:

    const A = {
      template: `<div><slot name="a">Default A Content</slot></div>`
    }
    
    const B = {
      template: `<div><slot name="b">Default B Content</slot></div>`
    }
    
    const C = {
      template: `<div><slot name="c">Default C Content</slot></div>`
    }
    

    还有一个wrapper component W,代码如下:

    Vue.component('W', {
      props: ['child'],
      template: `<component :is="child" />`
    })
    

    A, B, C会传入W,但问题是W并不知道A, B, C会用哪个slot。

    问题

    如果你尝试着这样写,

    <W :child="A">
      <div slot="a">Special A Content</div>
    </W>
    

    输出的结果确是Default A Content, 原因是slot a被当成了W的slot,而不是A的slot。

    方案

    所以我们需要想办法,将传给W的slot,接着传下去,让子的component能够接收到。

    代码如下:

    Vue.component('W', {
      props: ['child'],
      template: `<component :is="child">
      <slot v-for="(_, name) in $slots" :name="name" :slot="name" />
    </component>`
    })
    

    但上述代码还有一个小问题,就是不能识别scope slot中定义的变量,比如

    const D = {
      template: `<div><slot name="d" emoji="🎉">Default D Content</slot></div>`
    }
    

    其中的emoji就不能被slot中的代码识别。

    解决的方法也是会者不难。

    <template v-for="(_, name) in $scopedSlots" :slot="name" slot-scope="slotData"><slot :name="name" v-bind="slotData" /></template>
    

    于是,最终完整版的代码如下:

    Vue.component('W', {
      props: ['child'],
      template: `
      <component :is="child">
          <slot v-for="(_, name) in $slots" :name="name" :slot="name" />
          <template v-for="(_, name) in $scopedSlots" :slot="name" slot-scope="slotData">
            <slot :name="name" v-bind="slotData" />
          </template>
      </component>`
    })
    

    补充:如何传入指定的slot,并重命名

    原文中提供的上述写法,通用是通用。

    但有的时候,父组件提供的slot名,和子组件要用的slot名不一致的时候,这种写法就不行了。(不要问我为什么会出现这种情况-_-!!

    如果有重命名的规则还好办,如果没有,就只能hard code了。要传入指定的slot,并重命名。

    代码如下:

        <slot name="append-outer" slot="append"/>
    

    append-outer是在父组件指定的slot名,append是子组件里指定的slot名。

    后记

    新工作入职后,暂时没有前端程序员,只能自己琢磨着写起来,还好两年前自己的前端底子还在,vue上手也是快。

    用vue写了快了两周的prototype后,真心觉得vue+vuex比react+redux好上手多了。虽然一开始还是没有从angular双向绑定的思路转变过来,很不习惯,但上手了以后发现,有了vuex这都不是事,真心好用!

    借着眼下边摸索边做项目机会,也想顺手整理一下自己学到知识和技巧。于是,就从翻译这篇文章开始。

    一些常用的code snippet会陆续整理到vue code snippet

    相关文章

      网友评论

          本文标题:[翻译] VUE:如何把slot从父组件传到子组件

          本文链接:https://www.haomeiwen.com/subject/rspqzctx.html