关于前端:vue3中h函数的常见用法

个别状况下每个vue组件都用”\<template\>”写html, 但理论还能够在js代码中通过render函数生成dom. 最次要常见组件库也须要配合”h”应用.

render

render是组件的一个选项, 他的返回值会被作为组件的DOM构造.

<script>
import { defineComponent} from "vue";
export default defineComponent({
  render(){
    return '123456789'
  }
});
</script>

试试插入html:

<script>
import { defineComponent } from "vue";
export default defineComponent({
  render(){
    return '<h2>123456789</h2>'
  }
});
</script>

能够看到html标签被当做字符串渲染了, 并没有生成h2标签. 如何正确插入h2标签呢?

VNode

如果想插入DOM就要用到”VNode”, VNode是vue对页面DOM节点的形容, 其是一个Object类型.

h

构造这么简单的”VNode”必定不是本人拼写的, 官网提供了”h”函数, 能够帮忙咱们生成”VNode”

<script>
import { defineComponent, h } from "vue";
export default defineComponent({
  render() {
    const props = { style: { color: "red" } };
    return h("h2", props, "123456789");
  },
});
</script>

这次生成了真正”h2″:

“h”函数的第1个参数是”标签名“, 第2个是”属性“, 在这个例子里能够了解为html的所有属性, 第3个是”内容“. “内容”不仅仅能够是字符串, 还能够是”VNode”或2者混合:

<script>
import { defineComponent, h } from "vue";
export default defineComponent({
  render() {
    const props = { style: { color: "red" } };
    const small = h("small", "副标题");
    return h("h2", props, ["123456789", small]);
  },
});
</script>

如果理论只传入2个参数, 那么第二2参数就会作为内容, 比方这里的”small”.

渲染组件

“h”还能够渲染”组件”, 这一下灵便度就上来了, 假如咱们有一个”switch”组件, 其反对<switch v-model:checked="checked"/>.

<script>
import { defineComponent, h } from "vue";
import ASwitch from "../components/ASwitch.vue";
export default defineComponent({
  components: { ASwitch },

  data() {
    return { checked: false };
  },

  render() {
    return h(ASwitch)
  }
});
</script>

这里留神第1个参数还反对传入组件对象.
成果如下:

然而你能够发现了, “switch”尽管显示了, 然而点击后按钮并不能切换.

h函数中应用”v-model”

下面不能切换是因为没有像在模板中那样应用”v-model”.

 <a-switch v-model:checked="checked"></a-switch>

回顾下后面讲过的”自定义双向数据绑定”课中讲的如何实现”v-model”, 比照下能够发现下面”h”中,没有定义”props”和”v-on事件监听”, 怎么写呢?
先说一个重要的知识点: 组件上的事件监听其实也可通过”props”传入:

<a-switch @update:checked="onChange"></a-switch>
<!-- 等价写法: -->
<a-switch :onUpdate:checked="onChange"></a-switch>

所有的自定义事件, 都能够通过”:on”前缀通过props传入. 所以在”h”中能够通过第2个参数传入”checked“属性和”onUpdate:checked“事件实现”v-model“的等同操作.

<script>
import { defineComponent, h } from "vue";
import ASwitch from "../components/ASwitch.vue";
export default defineComponent({
  components: { ASwitch },

  data() {
    return { checked: false };
  },

  render() {
    return h(ASwitch, {
      checked: this.checked,
      ["onUpdate:checked"]: (checked) => {
        this.checked = checked;
      },
    });
  },
});
</script>

应用场景

理论开发中很多第三方组件都设计了能够接管”VNode”的”属性”, 比方”ant-design-vue”的”Table”组件的”columns”属性中的”customRender”属性, 能够通过传入”VNode”实现款式自定义:

{
    title: '状态',
    customRender({ record }: any) {
    if (1 === record.state) {
      return h(Tag, { color: 'success' }, () => `开启`);
    } else {
      return h(Tag, { color: 'error' }, () => `敞开`);
    }
  },
},

代码中通过”h”渲染了”Tag”组件,成果如下:

总结

这节课讲了3个概念, 帮大家整顿下他们3者的关系: “render”函数的返回值须要是”VNode”格局, “h”函数能够结构”VNode”格局数据.

🍕学习互动

感激大家的浏览, 如有疑难能够加我微信, 我拉你进入微信群

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理