vue slot 复用

话不投机半句多,直接上代码

有3步html

  • 第一步:建立渲染slot的组件 重要
  • 第二步:为slot添加父组件数据(props) 重要
  • 第三步:使用

第一步:建立渲染slot的组件

首选建立一个单文件组价,因为咱们是使用的slot(父组件传进来的),因此,咱们只须要建立js文件便可,而不用建立.vue文件vue

// slot.js
export default {
    name: 'Slot', // slot的名字,调试使用
    functional: true, // 使组件无状态 (没有 data ) 和无实例 (没有 this 上下文)。他们用一个简单的 render 函数返回虚拟节点使他们更容易渲染。
    inject: ['Root'], // 父组件的映射 
    props: { // 此组件接受的props
        data: Object,
        options: Object
    },
    render: (h, ctx) => { // dom渲染函数
        return h('div', ctx.injections.Root.$scopedSlots['icon']({ // 获得名为icon的做用域插槽
            data: ctx.props.data, // 给slot的组件传递props
            options: ctx.props.options
        }));
    }
};

第二步:为slot添加父组件数据(props)

// 导入子组件
import IconSlot from 'slot.js';

// 切换到父组件
export default {
    name: 'IconTable',
    components: {IconSlot},
     provide () { // 该对象包含可注入其子孙的属性 在这里把父组件自身传递给子组件
        return {
            Root: this
        };
    },
    data() {
        return {
            list: [],
            options: {}
        };
    }
}

在模板中使用node

<template>
    <div v-for="(item, index) in list" :key="index">
        <icon-slot :data="item" :options="options"></icon-slot>
    </div>
</template>

第三步:使用

<icon-table>
    <template slot="icon" slot-scope="{ list, options }">
        <div v-if="list.length > 1"><Icon type="add"></Icon></div>
        <div v-else><Icon type="del"></Icon></div>
    </template>
</icon-table>

大功告成 总结

若是在父组件直接取this.$slotthis.$scopedSlots的话,
其实只能用一次
若是在模板中使用 slot 标签来接收的话,其实也只能只用一次dom

因此核心思路是;每次使用都必须从新建立VNode节点,那只能每次都使用createElement生成node,
那只有一个办法使用render渲染了,而后第一个参数建立dom后,dom附带的数据,均可以是一个对象,只要保证节点是惟一的便可,数据其实无所谓,怎么传均可以ide

相关文章
相关标签/搜索