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>
相关推荐
我叫黑大帅5 小时前
Vue3和Uniapp的爱恨情仇:小白也能懂的跨端秘籍
前端·javascript·vue.js
洋洋技术笔记6 小时前
Vue实例与数据绑定
前端·vue.js
牛奶17 小时前
Vue 基础理论 & API 使用
前端·vue.js·面试
牛奶17 小时前
Vue 底层原理 & 新特性
前端·vue.js·面试
pe7er17 小时前
状态提升:前端开发中的状态管理的设计思想
前端·vue.js·react.js
_AaronWong1 天前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
wuhen_n1 天前
双端 Diff 算法详解
前端·javascript·vue.js
爱勇宝1 天前
别再混用了!import.meta.env 与 process.env 的本质差异一次讲透
前端·javascript·vue.js
从文处安2 天前
「九九八十一难」组合式函数到底有什么用?
前端·vue.js
用户11489669441052 天前
VUE3响应式原理——从零解析
vue.js