渲染函数[h()]
h()
是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。一个更准确的名称应该是 createVnode()
# 题目
<script setup lang="ts">
// 编写MyButton组件
import MyButton from "./MyButton.ts";
const onClick = () => {
console.log("onClick");
};
</script>
<template>
<MyButton :disabled="false" @custom-click="onClick"> my button </MyButton>
</template>
# 题目分析
需使用h()
实现一个单独的组件,并将其渲染到页面上。
MyButton
- 组件名:
MyButton
- 组件属性:
disabled
- 组件事件:
custom-click
- 组件内容:
my button
,该地方可以看出来是一个默认插槽
综上我们需要用h()
实现一个可接受传参
,事件
,插槽
的组件。
# 实现
方法一
import { h } from "vue"; // 引入h函数
export default {
name: "MyButton", // 组件名称
props: ["disabled"], // 使用props接收参数
setup(_, { slots, emit }) {
// _为props,{ slots, emit }为上下文,还包括attrs
return () =>
h(
"button", // 定义标签类型
// object
{
disabled: _.disabled,
onclick: () => {
emit("custom-click");
},
},
slots.default?.() // children,可为插槽、字符串、虚拟 DOM 节点等等
);
},
};
注意
请确保返回的是一个函数而不是一个值!setup() 函数在每个组件中只会被调用一次,而返回的渲染函数将会被调用多次。
方法二
// 你的答案
import { defineComponent, h } from "vue";
export default defineComponent({
name: "MyButton",
props: {
disabled: Boolean,
},
render({ $emit, $slots, $props }) {
return h(
"button",
{
disabled: $props.disabled,
onclick: (e) => $emit("custom-click", e),
},
$slots.default?.()
);
},
});
该地方的实现方式有多种写法,但是核心还是用
h()
函数创建一个vnode
,并返回该vnode
。
# 解析
MyButton
组件- 组件名:
MyButton
- 组件属性:
disabled
- 组件事件:
custom-click
- 默认插槽:
my button
- 组件名:
此处是一个 js
文件,由于要导出一个组件,所以需要export default
导出。写法与 <script setup>
的形式有区别。