Vue3使用h函数创建子组件(涉及到$emit,props的传递以及多个具名插槽的使用)

h 函数是什么
h 函数本质就是 createElement() 的简写,作用是根据配置创建对应的虚拟节点,在vue 中占有极其重要的地位!!!

h 函数的配置
参数
接收三个参数:type,props 和 children

type
类型:String | Object | Function
详细:HTML 标签名、组件、异步组件或函数式组件 (注意:Vue3 不支持组件名用字符串表示了,必须直接使用组件名)

例如:
import MySon from './son.vue'

h('div', {}, [
  h(MySon, {props: {name: 'hhh'}}) // MySon 不可写成 'MySon'
])


props

复制代码
类型:Object
{
// 和`v-bind:class`一样的 API
'class': {
foo: true,
bar: false
},
// 和`v-bind:style`一样的 API
style: {
color: 'red',
fontSize: '14px'
},
// 正常的 HTML 特性
attrs: {
  id: 'foo'
},
// 组件 props
props: {
  myProp: 'bar'
},
// DOM 属性
domProps: {
  innerHTML: 'baz'
},
// 事件监听器基于 `on`
// 所以不再支持如 `v-on:keyup.enter` 修饰器
// 需要手动匹配 keyCode。
on: {
  click: this.clickHandler
},
// 仅对于组件,用于监听原生事件,而不是组件内部使用
// `vm.$emit` 触发的事件。
nativeOn: {
  click: this.nativeClickHandler
},
// 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
// 赋值,因为 Vue 已经自动为你进行了同步。
directives: [
{
  name: 'my-custom-directive',
  value: '2',
  expression: '1 + 1',
  arg: 'foo',
  modifiers: {
    bar: true
  }
}
],
// Scoped slots in the form of
// { name: props => VNode | Array<VNode> }
scopedSlots: {
  default: props => createElement('span', props.text)
},
// 如果组件是其他组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其他特殊顶层属性
key: 'myKey',
ref: 'myRef'
}
复制代码


children
类型:String | Object | Array

String

h('div', {}, 'Some text comes first.')


生成的虚拟节点:

<div>Some text comes first.</div>

 

Array

复制代码
h('div', {}, [
  'Some text comes first.',
  h('h1', 'A headline'),
  h(MyComponent, {
   props: {
    name: 'hhh'
   }
  })
])
复制代码

 

生成的虚拟节点:

<div>
    Some text comes first.
    <h1>A headline</h1>
    <MyComponent name="hhh" />
</div>


Object
这个挺实用的,特别是需要传入多个具名插槽的时候!!!

复制代码
子组件:
<template>
    <div>
        你好,我是子组件,下面是两个具名插槽
        <template #content />
        <template #contentTips />
    </div>
</template>



父组件:
const props = {
    name: 'aaa',
    age: 18
}
const slots = {}
['content', 'contentTips'].forEach(name => slots[name] = h('div', {key: name}, name));
h(MySon, {...props}, slots);
复制代码


关于 Vue3 中 h 函数如何接收子组件$emit发送的事件

这个问题困扰了我很久。

以前 vue2 的写法:

复制代码
子组件 MySon :
<template>
    <div>
        <button @click.stop="$emit('start', 'gogogo!!!')"/>
    </div>
</template>



父组件的 h 函数:
import MySon from './son.vue'

h(MySon, {
    //子组件 $emit 传递函数
    start(data) {
        console.log(data);
    },
})
复制代码

 

如今 vue3 的写法(绑定的事件名需要加多一个on前缀):

复制代码
子组件:
<template>
    <div>
        <button @click.stop="$emit('start', 'gogogo!!!')"/>
    </div>
</template>



父组件的 h 函数:
h(TableActionButtons, {
    //子组件 $emit 传递函数!!!!
    onStart(data) {
        console.log(data);
    },
})
复制代码

 

posted @   wingring  阅读(5776)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示