函数式编程
主要用到h函数,h接收三个参数
- type:元素的类型
- propsOrChildren:数据对象,主要表示props、attrs、dom props、class和style
- children:子节点
优点:跳过了模板的编译过程
缺点:很难看,学习成本高
模板的编译过程:
- parser函数将模板转成抽象语法树ast
- transform函数将ast转成js api
- generate函数通过js api生成render函数
render函数会返回一个形如这样的数据,就是h函数:
1 2 3
| return h("div",{},[ h("span",{},"1") ])
|
Vue3开发使用h函数较少,因为Vue3模板的编译性能也不差。
App.vue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <template> <table border> <tr> <th>name</th> <th>age</th> <th>address</th> <th>操作</th> </tr> <tr v-for="item in list" :key="item.id"> <td>{{ item.name }}</td> <td>{{ item.age }}</td> <td>{{ item.address }}</td> <td> <Btn type="success">编辑</Btn> <Btn type="error">删除</Btn> </td> </tr> </table> </template>
<script setup lang="ts"> import { h, reactive } from 'vue'
const list = reactive([ {id:20,name:"yajue",age:20,address:"xbz"}, {id:21,name:"yajue",age:21,address:"xbz"}, {id:22,name:"yajue",age:22,address:"xbz"}, {id:23,name:"yajue",age:23,address:"xbz"}, {id:24,name:"yajue",age:24,address:"xbz"}, ])
interface Props { type: "success" | "error" }
// 类似setup函数模式 // 可以用于封装一些小组件 const Btn = (props:Props,ctx:any,)=> { // 参数1:节点名 参数2:节点属性 参数3:节点内容 return h("button",{ class:"btn", style: { color: props.type==="success"?"green":"red" }, onClick:()=>{ if(props.type==="success") { console.log("编辑") } else { console.log("删除") } } },ctx.slots.default()) } </script>
|
源码
在Vue源码(/package/runtime-core/src/h.ts
)中可以看到h函数的源码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
export function h(type: any, propsOrChildren?: any, children?: any): VNode { const l = arguments.length if (l === 2) { if (isObject(propsOrChildren) && !isArray(propsOrChildren)) { if (isVNode(propsOrChildren)) { return createVNode(type, null, [propsOrChildren]) } return createVNode(type, propsOrChildren) } else { return createVNode(type, null, propsOrChildren) } } else { if (l > 3) { children = Array.prototype.slice.call(arguments, 2) } else if (l === 3 && isVNode(children)) { children = [children] } return createVNode(type, propsOrChildren, children) } }
|