大家好,我是鱼樱!!!
关注公众号【鱼樱AI实验室】
持续每天分享更多前端和AI辅助前端编码新知识~~喜欢的就一起学反正开源至上,无所谓被诋毁被喷被质疑文章没有价值~~~坚持自己观点
一个城市淘汰的自由职业-农村前端程序员(虽然不靠代码挣钱,写文章就是为爱发电),兼职远程上班目前!!!热心坚持分享~~~
📜 目录
- [什么是 h 函数?](#什么是 h 函数? "#-%E4%BB%80%E4%B9%88%E6%98%AF-h-%E5%87%BD%E6%95%B0")
- 核心作用与原理
- [Vue2 vs Vue3 用法对比](#Vue2 vs Vue3 用法对比 "#-vue2-vs-vue3-%E7%94%A8%E6%B3%95%E5%AF%B9%E6%AF%94")
- 实战案例对比
- 底层原理与源码分析
- 最佳实践与注意事项
🌟 什么是 h 函数?
h 函数(Hyperscript) 是 Vue 中用于创建虚拟 DOM 节点的核心函数。它是模板编译的底层实现,能直接操作虚拟 DOM,适用于需要极致灵活性的场景。
核心特点:
- 声明式渲染:比直接操作 DOM 更高效
- 动态构建能力:可在 JavaScript 中直接构造复杂 UI 逻辑
- 模板的替代方案:当模板语法无法满足需求时的终极武器
🧠 核心作用与原理
核心作用
- 创建虚拟 DOM 节点(VNode)
- 实现模板的底层渲染逻辑
- 支持 JSX 和自定义渲染逻辑
实现原理
bash
模板/JSX → 编译 → h 函数调用 → 虚拟 DOM → 真实 DOM
虚拟 DOM 优化:
- Vue2:全量对比虚拟 DOM
- Vue3:静态标记 + 靶向更新(性能提升 200%)
⚔️ Vue2 vs Vue3 用法对比
参数结构对比
特性 | Vue2 | Vue3 |
---|---|---|
导入方式 | 自动注入 | 需要显式导入 |
参数结构 | h(tag, data, children) |
h(tag, props, children) |
事件监听 | on: { click: handler } |
onClick: handler |
Props 传递 | props: { ... } |
直接作为对象属性 |
默认插槽 | this.$slots.default |
通过 slots.default() 访问 |
💻 实战案例对比
案例 1:基础按钮组件
Vue2 实现
javascript
export default {
render(h) {
// dom
return h('button', {
// attr
class: 'btn',
// 事件
on: {
click: this.handleClick
}
// 获取默认插槽的内容
}, this.$slots.default)
},
methods: {
handleClick() {
console.log('Vue2 按钮点击!')
}
}
}
Vue3 实现
javascript
import { h } from 'vue'
export default {
setup() {
const handleClick = () => {
console.log('Vue3 按钮点击!')
}
return () => h('button', {
class: 'btn',
onClick: handleClick
}, slots.default?.())
}
}
案例 2:动态列表渲染
Vue2 实现
javascript
render(h) {
return h('ul',
this.items.map(item =>
h('li', { key: item.id }, item.text)
)
)
}
Vue3 实现
javascript
import { h } from 'vue'
setup() {
return () => h('ul',
items.value.map(item =>
h('li', { key: item.id }, item.text)
)
)
}
🔍 底层原理与源码分析
Vue2 实现原理
javascript
// 简化版 h 函数实现
function h(tag, data, children) {
return {
__v_isVNode: true,
tag,
data,
children,
// ...其他属性
}
}
Vue3 优化实现
javascript
// Vue3 的 createVNode 函数
function createVNode(type, props, children) {
const vnode = {
__v_isVNode: true,
type,
props,
children,
shapeFlag: getShapeFlag(type),
// ...新增 patchFlag 进行靶向更新
}
// 静态节点标记优化
if (isStaticVNode(vnode)) {
vnode.patchFlag = PatchFlags.STABLE
}
return vnode
}
🚀 最佳实践与注意事项
最佳实践
- 优先使用模板:90% 场景下模板更合适
- 合理使用 JSX:复杂逻辑时更直观
- 缓存静态节点:利用 Vue3 的静态提升特性
常见陷阱
markdown
- 🚫 Vue2 中忘记写 `this.$slots`
- 🚫 Vue3 中未正确导入 h 函数
- 🚫 错误处理事件绑定语法(`onClick` vs `on:click`)
- 🚫 忘记添加 `key` 属性导致渲染异常
📌 总结
维度 | Vue2 | Vue3 |
---|---|---|
性能 | 中等 | 优化后提升 200% |
语法简洁性 | 较传统 | 更现代化 |
类型支持 | 有限 | 完美 TS 支持 |
扩展能力 | 普通 | 支持自定义渲染器 |
掌握 h 函数的使用,你将获得:
- 🔧 更强大的动态组件构建能力
- 🚤 更精细的性能优化手段
- 🧩 更深入理解 Vue 的渲染机制