我要做的是一个菜单成果,是用的jsx语法,开发应用的是Vue3.0+ts开发的

间接用模板编写

<a-menu v-model:selectedKeys="selectedKeys" mode="inline" theme="light">    <a-menu-item key="1">        <pie-chart-outlined/>            <span>工作台</span>    </a-menu-item>    <a-sub-menu key="sub3">        <template #title>        <span>        <desktop-outlined/>            <span>系统配置</span>        </span>        </template>        <a-sub-menu key="sub4" title="权限治理">            <a-menu-item key="7">                菜单列表            </a-menu-item>        </a-sub-menu>    </a-sub-menu>    <a-sub-menu key="sub2">        <template #title>            <span>                <user-outlined/>                <span>User</span>            </span>        </template>        <a-menu-item key="4">Bill</a-menu-item>    </a-sub-menu></a-menu>

应用tsx编写

数据结构

const defaultMenu = [    {        name: '首页',        router: '/home',        icon: 'HomeFilled',        isShow: 1,        id: 1    },    {        name: '组件库',        router: '',        isShow: 1,        id: 2,        children: [            {                name: 'Markdown编辑器',                router: '/markdown',                icon: 'HomeFilled',                isShow: 1,                id: 3,            },            {                name: '文件上传',                router: '/fileUpload',                icon: 'UploadOutlined',                isShow: 1,                id: 4,        children:[                    {                        name: '图片上传',                        router: '/fileUploadImg',                        icon: 'UploadOutlined',                        isShow: 1,                        id: 6,                    }                ]            },        ]    },    {        name: '对于',        router: '/about',        icon: 'UserOutlined',        isShow: 1,        id: 5,    },]
import {computed, defineComponent, h, ref} from 'vue'import {useStore} from 'vuex'export default defineComponent({    name: 'yxs-menu-slider',    setup() {        const store = useStore();        const selectedKeys = ref<string[]>(['1']); // 设置默认选中        const menuList = computed(() => store.getters.menuList); // 等于上述的 defaultMenu 构造,我只不过放在了store        return {            selectedKeys,            menuList        }    },    render(ctx: any) {        const deepMenu = function (list: Array<any>) {            let html = null;            return list.filter((item: any) => item.isShow).map((item: any) => {                if (item.children && item.children.length) {                    html = h(                        <a-sub-menu key={item.id}></a-sub-menu>,                        {},                        {                            title: () => { // 插槽地位 title                                return <span>{item.name}</span>                            },                            default: () => { // 默认内容                                let children = item.children.map((todo: any) => {                                    return <a-menu-item key={todo.id}>{todo.name}</a-menu-item>                                })                                return children && deepMenu(item.children) // 递归                            }                        }                    )                } else {                    html = h(                        <a-menu-item key={item.id}></a-menu-item>,                        {},                        {                            default: () => {                                return <span>{item.name}</span>                            }                        }                    )                }                return html;            })        }        const children = deepMenu(ctx.menuList);        return (            <div class="yxs-menu-slider">                <a-menu                    v-model:selectedKeys={ctx.selectedKeys}                    mode="inline"                    theme="light">                    {children}                </a-menu>            </div>        )    }})

应用

注册调用即可
<template>    <YxsMenuSlider/></template><script lang="ts">    import YxsMenuSlider from './components/menu/index.tsx'    export default defineComponent({        name: 'Slider',        components: {            YxsMenuSlider        }    })</script>

成果如下

下面半截是模板,上面tsx模板

扩大

你的组件可能有更多的插槽,写上插槽名字即可
h(Comp, null, {    default: () => 'default',    foo: () => 'foo',    bar: () => 'bar'})

留神这么写的时候,即使没有props,第二个参数也是必须的,因为h函数发现第二个参数如果是对象,那么默认其就是props,

更多写法请往下看,源码曾经帮我做好了很多兼容

解说

h语法

在讲之前先看h函数源码
// type 元素的类型// propsOrChildren 数据对象, 这里次要示意(props, attrs, dom props, class 和 style)// children 子节点也是一个any类型export function h(type: any, propsOrChildren?: any, children?: any): VNode {  if (arguments.length === 2) {    if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {      // single vnode without props      if (isVNode(propsOrChildren)) {        return createVNode(type, null, [propsOrChildren])      }      // props without children      return createVNode(type, propsOrChildren)    } else {      // omit props      return createVNode(type, null, propsOrChildren)    }  } else {    if (isVNode(children)) {      children = [children]    }    return createVNode(type, propsOrChildren, children)  }}

通过上述咱们就晓得,如何应用h函数,以及为什么能这么传参

h('div')// type + propsh('div', {})// type + omit props + children// Omit props does NOT support named slotsh('div', []) // arrayh('div', 'foo') // texth('div', h('br')) // vnodeh(Component, () => {}) // default slot// type + props + childrenh('div', {}, []) // arrayh('div', {}, 'foo') // texth('div', {}, h('br')) // vnodeh(Component, {}, () => {}) // default sloth(Component, {}, {}) // named slots// named slots without props requires explicit `null` to avoid ambiguityh(Component, null, {})

官网也说的有列子

更多对于你学习的常识

https://vue3js.cn/global/h.html
对于 vue3 中的 render 办法,你可能不晓得这些