Vue多层级组件传递动态具名插槽

发布时间 2023-09-18 19:26:33作者: szq233

这里以一个table组件的二次包装为案例,父组件中使用子组件(table组件)再次包装:

Vue2:

子组件,inTable

<template>
  <table>
    <thead>
      <tr>
        <th
          v-for="(item, index) of columns"
          :key="index">
          {{ item.title }}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) of dataSource" :key="index">
        <td
          v-for="(k, i) in columns"
          :key="i">
          <slot v-if="k.slot" :name="k.slot" :record="item" :value="item[k.key]">
            {{ !item[k.key] && item[k.key] !== 0 ? '-' : item[k.key] }}
          </slot>
          <template v-else>
            {{ !item[k.key] && item[k.key] !== 0 ? '-' : item[k.key] }}
          </template>
        </td>
      </tr>
    </tbody>
  </table>
</template>
<script>
export default {
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    dataSource: {
      type: Array,
      default: () => []
    }
  }
}
</script>

父组件,myTable

<template>
  <div>
    <in-table
      :columns="columns"
      :data-source="dataSource">
      <template
        v-for="t in columns.filter(k => k.slot)"
        #[t.slot]="{value, record}">
        <slot
          :name="t.slot"
          :record="record"
          :value="value"></slot>
      </template>
    </in-table>
  </div>
</template>
<script>
import InTable from './inTable.vue'
export default {
  components: {
    InTable
  },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    dataSource: {
      type: Array,
      default: () => []
    }
  }
}
</script>

使用示例组件:

<template>
  <div>
    <my-table columns="columns">
      <template #test3="{ value, record }">这里是替换“内容3”的内容</template>
    </my-table>
  </div>
</template>
<script>
import MyTable from './myTable.vue'
export default {
  components: {
    MyTable
  },
  data () {
    return {
      columns: [
        { title: '测试1', key: 'key1' },
        { title: '测试2', key: 'key2' },
        { title: '测试3', key: 'key3', slot: 'test3' }
      ],
      dataSource: [
        { key1: '内容1', key2: '内容2', key3: '内容3' }
      ]
    }
  }
}
</script>