You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1.8 KiB

在单一vue组件内实现模板复用非jsx版本

关联文章,使用jsx

注意事项

  • 定义的模版必须放置在使用之前,遵循代码执行顺序
  • 复杂版本将render渲染的slot存为了一个数组使用的时候必须传入数组类型的slotName这样在使用useTemplate函数时才知道该渲染哪个模版
  • 简单版本可以直接v-slot默认使用defalut

简单版本源代码

<template>
    <DefineTemplate v-slot="{ title, content, onFoo }">
        <!-- 方法可以直接使用script中的写法: @click="doClick" -->
        <div class="box" @click="onFoo()">
            <p>{{ title }}</p >
            <p>{{ content }}</p >
        </div>
    </DefineTemplate>
    <useTemplate title="标题一" content="内容一" @foo="doClick"></useTemplate>
    <useTemplate title="标题二" content="内容二" @foo="doClick"></useTemplate>
    <!-- <div class="box">
        <p>标题一</p >
        <p>内容一</p >
    </div>
    <div class="box">
        <p>标题二</p >
        <p>内容二</p >
    </div> -->
</template>

<script setup>
import { creatTemplateReuse } from "./index";
const [DefineTemplate, useTemplate] = creatTemplateReuse();

const doClick = () => {
    console.log("我是标题一点击");
};
</script>

<style scoped>
.box {
    width: 100px;
    height: 100px;
    background: #e1e1e1;
    margin-right: 50px;
}
</style>
export function creatTemplateReuse() {
    let render;

    const DefineTemplate = {
        setup(_, { slots }) {
            console.log(slots);
            render = slots.default;
            return () => {};
        },
    };

    const useTemplate = (props) => {
        return render(props);
    };

    return [DefineTemplate, useTemplate];
}

下面是复杂模版的效果代码请查看vue文件