如何在<script setup> Vue3中使用render函数

use*_*922 30 javascript vue.js vuejs3 vue-composition-api vue-script-setup

我使用Vue 3.1.1

我在实验阶段使用脚本设置和单个文件组件。使用脚本设置,我了解defineProps、defineEmit和useContext,但我不了解如何使用渲染函数。

<script lang="ts" setup>
import { defineProps } from 'vue'

const props = defineProps<{
    text: string
}>()

const handleClick = () => {
    console.log('click!!')
}

// Render function...

/* The template I want to create.
    <button
        class="btn btn-primary"
        type="button"
        @click="handleClick"
    >
        {{ props.text }}
    </button>
*/
</script>
Run Code Online (Sandbox Code Playgroud)

小智 29

尝试一下。

<script lang="tsx" setup>
  import { h } from 'vue';

  const render = () => {
    return h('div', []);
  };

  const jsxNode = () => {
    return <div> text </div>;
  };
</script>
<template>
  <render />
  <jsxNode />
</template>

Run Code Online (Sandbox Code Playgroud)


Bou*_*him 8

尝试使用该h函数创建元素,然后将其呈现在模板部分中,如下所示:

<script setup lang="ts">
import { ref,h } from 'vue'

const props = defineProps<{
    text: string
}>()

const handleClick = () => {
    console.log('click!!')
}

const root=h('button',
             {type:'button',onClick:handleClick,class:'btn btn-primary'},props.text)

</script>

<template>
  <root/>             
</template>
Run Code Online (Sandbox Code Playgroud)

演示版


And*_* L. 7

您可以通过以下方式将渲染函数直接分配给您的组件实例getCurrentInstance

定制挂钩

// useRender.ts

import type { VNode } from 'vue';
import { getCurrentInstance } from 'vue';

export function useRender(render: () => Arrayable<VNode | null>): void {
    const vm = getCurrentInstance();

    if (!vm) {
        throw new Error('[useRender] must be called from inside a setup function');
    }

    /**
     * In development mode, assignment render property works fine
     * but in production SFC overwrites it with an empty function
     * because no <template> section defined.
     *
     * Filthy hack to avoid this in production.
     * https://github.com/vuejs/core/issues/4980
     */
    if (import.meta.env.DEV) {
        (vm as any).render = render;
    } else {
        Object.defineProperty(vm, 'render', {
            get: () => render,
            set: () => {},
        });
    }
}

Run Code Online (Sandbox Code Playgroud)

用法

<script setup>
import { h } from 'vue';

import { useRender } from './useRender';

useRender(() => h('span', 'Hello from script setup'));
</script>
Run Code Online (Sandbox Code Playgroud)