詹华晨

V1

2022/06/05阅读:33主题:默认主题

在vue template模板中使用render函数的方法

在某些场景下,一个组件用template语法写比较简单,或者历史代码就是使用template写的,现在我们要扩展它的功能,要求它的某个props可以传入一个render函数,要求template可以将这个props正常渲染出来,怎么办?

代码示例:

子组件代码:

<template>
    <div class="form-item">
        <div class="label">{{item.label}}:</div>
        <div class="value" v-if="defaultRender">{{item.value}}</div>
        <value-node class="value" v-else :vnodes="vnodes"></value-node>
    </div>
</template>

<script>
export default {
    name"formItem",
    components: {
        "value-node": {
            functionaltrue,
            render(h, ctx) {
                return ctx.props.vnodes(h)
            }
        }
    },
    props: {
        item: {
            typeObject,
            default() => ({})
        }
    },
    computed: {
        defaultRender() {
            return !this.item.renderFn
        }
    },
    methods: {
        vnodes(h) {
            return this.item.renderFn && this.item.renderFn(h, this.item)
        }
    }
}
</script>

<style lang="css">
.form-item {
    display: flex;
}

</style>

父组件调用代码:

<template>
    <div id="app">
        <form-item v-for="(item) in formOptions" :key="item.key" :item="item"></form-item>
    </div>
</template>

<script>
import formItem from "./components/formItem.vue";
export default {
    name"App",
    components: { formItem },
    data() {
        return {
            formOptions: [
                {
                    key"user-name",
                    label"用户名",
                    value"张三",
                },
                {
                    key"user-sex",
                    label"性别",
                    value"1",
                    renderFn(h, item) {
                      // eslint-disable-next-line no-console
                      console.log(item)
                        return <span>{item.value == "1" ? "男" : "女"}</span>;
                    },
                },
            ],
        };
    },
};
</script>


渲染结果:

注意传进去的item的渲染函数名称不要叫做render,则会被当成vue组件。

分类:

前端

标签:

前端

作者介绍

詹华晨
V1