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>
相关推荐
学Linux的语莫10 小时前
Vue 3 入门教程
前端·javascript·vue.js
qq43569470113 小时前
Vue04
前端·vue.js
万物更新_16 小时前
vue框架
前端·javascript·vue.js·笔记
英勇无比的消炎药19 小时前
一文吃透TinyRobot Bubble:从基础组件搭建完整AI消息渲染体系
vue.js
英勇无比的消炎药20 小时前
深挖底层:TinyRobot Bubble消息气泡组件核心技术原理
vue.js
英勇无比的消炎药20 小时前
架构剖析:TinyRobot Bubble渲染器状态管理与工具调用机制
vue.js
英勇无比的消炎药20 小时前
多模态消息渲染实战:TinyRobot Bubble内容解析与contentResolver用法
vue.js
gg1593572846020 小时前
Uni-app跨平台开发全解课程:从零基础到企业级多端落地实战
vue.js·uni-app
阿猫的故乡20 小时前
Vue + Axios 从入门到封装:拦截器、错误处理、请求取消、接口管理全搞定
前端·javascript·vue.js
秃头网友小李21 小时前
前端难点:Vue3 响应式遇上 Three.js / ECharts —— 为什么要用 shallowRef?
前端·vue.js