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>
相关推荐
我的div丢了肿么办2 小时前
element-plus表格使用:filter-method过滤导致出现无数据
前端·javascript·vue.js
贾公子2 小时前
AI 内容检测 API 接入实战——异步任务、幂等键与轮询的正确写法
vue.js
星光不问赶路人2 小时前
Vue 项目类型检查:深入理解 vue-tsc --build
前端·vue.js
WeiXin_DZbishe3 小时前
基于springboot装修风格选择系统的设计与开发-计算机毕设【课程设计】77964
java·vue.js·spring boot·后端·python·php·课程设计
雪碧聊技术3 小时前
Vue 一个页面中使用多个同类组件出现“串数据“现象?一个 key 就能解决
vue.js·v-show·一个页面使用多个相同组件·解决数据错乱·v-if、key
Java小卷6 小时前
Vue3 动态表单支持弹框组件
前端·vue.js·低代码
溪语流沙6 小时前
【Web全栈进阶】前端对接新契约:信封解包 + 统一错误处理
前端·vue.js·python·状态模式·fastapi
Q26433650236 小时前
【有源码】基于SpringBoot+Vue的居民健康体检与慢病干预管理系统-面向智慧医疗的体检预约与健康知识服务平台
java·vue.js·spring boot·mysql·毕业设计·javaweb·课程设计
雪芽蓝域zzs7 小时前
Vue导入方法三种方式对比
前端·javascript·vue.js
雪芽蓝域zzs8 小时前
从零搭建【pnpm+Vue3+TS+Setup+VueRouter4+Pinia+Axios+ElementPlus (unplugin 按需)】仿若依后台
前端·vue.js