Vue3 h函数

文章目录

Vue3 h函数

概述

Vue 推荐使用模版创建 HTML,在一些特殊场景,可以使用 JavaScript 创建 HTML。

  • VNode:在 template 中编写的 HTML 最终通过渲染函数生成对应的 VNode。
  • VDOM:VNode 组合在一起形成一棵树结构,也就是虚拟 DOM(VDOM)。
  • h():h 是 "hyperscript" 的缩写,表示为生成 HTML 结构的 JavaScript。h 函数是 createVNode 函数的别名,用于创建 VNode 的核心函数。

template工作流程

  1. 编译阶段:
    1. 将模板转换为抽象语法树(AST)
    2. 对 AST 进行优化
    3. 将优化后的 AST 转换为渲染函数代码(通常是h函数调用或render函数)
  2. 运行阶段:
    1. 执行渲染函数生成虚拟 DOM 节点(VNode)
    2. 通过 patch 函数将 VNode 转换为真实 DOM
  3. 响应式联动:当数据变化时,触发重新渲染,重复执行运行阶段

语法

复制代码
h(type, props, children)
  • type:节点类型,可以是字符串、组件、异步组件等。
  • props:属性对象,可选。
  • children:子节点,可选。

使用

选项式

vue 复制代码
<script>
import {h, ref} from "vue"
import HelloWorld from "./components/HelloWorld.vue";

export default {
  data() {
    return {
      counter: 100
    }
  },
  // 使用 render 函数
  render() {
    return h("div", {class: "counter"}, [
      h("h2", {class: "title"}, `counter: ${this.counter}`),
      h("button", {onclick: this.increment}, "+1"),
      h("button", {onclick: this.decrement}, "-1"),
      h(HelloWorld),
    ])
  },
  methods: {
    increment() {
      this.counter++
    },
    decrement() {
      this.counter--
    },
  }
}
</script>

<style scoped>
.counter {
  text-align: center;
  background-color: gray;
}

.title {
  color: red;
}
</style>

组合式

vue 复制代码
<script>
import {h, ref} from "vue"
import HelloWorld from "./components/HelloWorld.vue";

export default {
  setup() {
    const counter = ref(200)
    const increment = () => {
      counter.value++
    }
    const decrement = () => {
      counter.value--
    }
    // 返回渲染函数
    return () => h("div", {class: "counter"}, [
      h("h2", {class: "title"}, `counter: ${counter.value}`),
      h("button", {onclick: increment}, "+1"),
      h("button", {onclick: decrement}, "-1"),
      h(HelloWorld),
    ])
  }
}
</script>

<style scoped>
.counter {
  text-align: center;
  background-color: gray;
}

.title {
  color: red;
}
</style>

setup语法糖

vue 复制代码
<script setup>
import {h, ref, getCurrentInstance} from "vue"
import HelloWorld from "./components/HelloWorld.vue";

const instance = getCurrentInstance()
const scopeId = instance.type.__scopeId

const counter = ref(300)
const increment = () => {
  counter.value++
}
const decrement = () => {
  counter.value--
}

// 定义渲染函数
const render = () => h("div", {class: "counter", [scopeId]: ""}, [
  h("h2", {class: "title", [scopeId]: ""}, `counter: ${counter.value}`),
  h("button", {onclick: increment}, "+1"),
  h("button", {onclick: decrement}, "-1"),
  h(HelloWorld),
])
</script>

<template>
  <component :is="render"/>
</template>

<style scoped>
.counter {
  text-align: center;
  background-color: gray;
}

.title {
  color: red;
}
</style>
相关推荐
yyt36304584111 小时前
KLineChartQuant:GLSL 的精度问题及 RTC 解法
前端·vue.js·react.js·交互·图形渲染·webgl·数据可视化
变与不变80612 小时前
js函数与封装详细解答
前端·javascript·vue.js
计算机毕设定制辅导-无忧学长14 小时前
基于Spring Boot的玄幻小说个性化推荐平台设计与实现
java·vue.js·spring boot·后端·mysql·推荐算法
雪芽蓝域zzs14 小时前
第三十二节:部门组织管理(el‑tree 组织树
前端·javascript·vue.js
leoZ23115 小时前
第 7 篇:进阶——校验、联动、列表页
开发语言·前端·javascript·vue.js·人工智能·目标检测·ecmascript
全栈技术负责人16 小时前
大模型流式输出核心技术:智能 Markdown 渲染引擎方案
前端·javascript·vue.js
雪芽蓝域zzs16 小时前
第三十四节:用户新增编辑弹窗增加 el‑tree‑select 部门选择器
前端·javascript·vue.js
雪芽蓝域zzs18 小时前
第三十一节:角色管理页面 + 权限分配树形弹窗
前端·javascript·vue.js
雪芽蓝域zzs18 小时前
第三十五节:Axios 统一错误拦截、401 Token 过期处理
前端·javascript·vue.js
单线程_0119 小时前
从案例分析 Vue3 Tokenizer+Parser 源码四
前端·javascript·vue.js