Vue—slot 跨组件传递

2022/07/28 Vue 共 1767 字,约 6 分钟

父组件

Parent.vue

<template>
  <div class="parent">
    <Child>
      <span #slot1="{ item, index }"></span>

      <span #slot2="{ item, index }"></span>
    </Child>
  </div>
</template>

<script>
import Child from './Child.vue'
export default {
  name: "parent"
}
</script>

Parent.jsx

import Child from './Child.jsx'
const Parent = Vue.component('parent', {
  render() {
    return (
      <div className="parent">
        <Child
          scopedSlots={
            {
              slot1: props => {
                return <span>{ props.index }</span>
              },
              slot2: props => {
                return <span>{ props.index }</span>
              }
            }
          }
        ></Child>
      </div>
    )
  }
})

子组件

Child.vue

<template>
  <div class="child">
    <Sun>
      <template v-for="(index, name) in $scopedSlots" v-slot:[name]="data">
        <slot :name="name" v-bind="data"></slot>
      </template>
    </Sun>
  </div>
</template>

<script>
import Sun from './Sun.vue'
export default {
  name: "child"
}
</script>

Child.jsx

import Sun from 'Sun.jsx'
const Child = Vue.component('child', {
  methods: {
    scopedSlots() {
      let result = {}
      Object.keys(this.$scopedSlots).forEach((name) => {
        result[name] = (props) => this.$scopedSlots[name](props)
      })
      return result
    }
  },
  render() {
    return (
      <div className="child">
        <Sun
          scopedSlots=
        ></Sun>
      </div>
    )
  }
})

孙组件

Sun.vue

<template>
  <div class="sun">
    <template v-for="(name, index) in slots">
      <slot :name="name" :item="item" :index="index"></slot>
    </template>
  </div>
</template>

<script>
export default {
  name: "sun",
  data() {
    return {
      slots: ['slot1', 'slot2', 'slot3'],
      item: {}
    }
  }
}
</script>

Sun.jsx

const Sun = Vue.component('sun', {
  data() {
    return {
      slots: ['slot1', 'slot2', 'slot3'],
      item: {}
    }
  },
  render() {
    return (
      <div className="sun">
        {this.slots.map((name, index) => {
          this.$scopedSlots[name](this.item, index)
        })}
      </div>
    )
  }
})