Vue3 jsx syntax uses v-slots slots and component dynamic components

Using v-slots slots and dynamic components in jsx syntax

1. In the original template syntax, slots are used to implement #title and #icon
2. Dynamic components are implemented through component

<template>
  <a-menu>
    <a-sub-menu key="sub1" @titleClick="titleClick">
      <template #icon>
         <component :is="QqOutlined "></component >
      </template>
      <template #title>Navigation One</template>
      <a-menu-item-group key="g1">
        <template #icon>
          <component :is="QqOutlined "></component >
        </template>
        <template #title>Item 1</template>
        <a-menu-item key="1">Option 1</a-menu-item>
        <a-menu-item key="2">Option 2</a-menu-item>
      </a-menu-item-group>
      <a-menu-item-group key="g2" title="Item 2">
        <a-menu-item key="3">Option 3</a-menu-item>
        <a-menu-item key="4">Option 4</a-menu-item>
      </a-menu-item-group>
    </a-sub-menu>
  </a-menu>
</template>

The use of jsx syntax slots and dynamic components
Note:
1. Use v-slots to receive the slot parameter default as the default slot title and icon as the scope slot of the ui component 2. The
dynamic implementation needs to use h and resolveComponent Composite API

    const slot = {
    
    
        title: () => <span> {
    
    menu.meta.title}</span>,
        icon: () => (
          <span>{
    
    menu.meta.icon ? h(resolveComponent(menu.meta.icon)) : ""} </span>
        ),
      };
      <a-menu
        mode="inline"
        theme="dark"
        forceSubMenuRender={
    
    true}
      >
      <a-sub-menu key={
    
    menu.name} v-slots={
    
    slot}>
         <a-menu-item key={
    
    menu.name}>
            菜单内容
        </a-menu-item>
        </a-sub-menu>
      </a-menu>

The complete code deom implements a menu that recursively traverses the rendered menu

<script>
import {
    
     useStore } from "vuex";
import {
    
     useRoute } from "vue-router";
import {
    
     computed, ref, watch, h, resolveComponent, defineComponent } from "vue";
export default defineComponent({
    
    
  setup() {
    
    
    const store = useStore();
    const route = useRoute();
    //当前选中项
    const selectedKeys = ref([route.name]);
    //当前展开项
    const openKeys = ref([route.meta.partentName || ""]);
    const menuTrees = computed(() => store.state.permission.addRouters);
    watch(route, (n, o) => {
    
    
      selectedKeys.value = [n.name];
    });

    // 生成 subMenu 菜单
    const renderSubMenu = (menu) => {
    
    
      const menuItem = [];
      menu.children.forEach((item) => menuItem.push(renderMenu(item)));
      const slot = {
    
    
        title: () => <span> {
    
    menu.meta.title}</span>,
        icon: () => (
          <span>{
    
    menu.meta.icon ? h(resolveComponent(menu.meta.icon)) : ""} </span>
        ),
      };
      return (
        <a-sub-menu key={
    
    menu.name} v-slots={
    
    slot}>
          {
    
    menuItem}
        </a-sub-menu>
      );
    };
    // 生成  menu-item 菜单
    const renderMenuItem = (menu) => {
    
    
      const slot = {
    
    
        icon: () => (
          <span>{
    
    menu.meta.icon ? h(resolveComponent(menu.meta.icon)) : ""} </span>
        ),
      };
      return (
        <a-menu-item key={
    
    menu.name} v-slots={
    
    slot}>
          <router-link to={
    
    menu.path}>{
    
    menu.meta.title}</router-link>
        </a-menu-item>
      );
    };

    const renderMenu = (menu) => {
    
    
      return menu.children ? renderSubMenu(menu) : renderMenuItem(menu);
    };

    const menuList = menuTrees.value.map((menu) => {
    
    
      return renderMenu(menu);
    });
    return () => (
      <a-menu
        mode="inline"
        theme="dark"
        forceSubMenuRender={
    
    true}
        v-model:selectedKeys={
    
    selectedKeys.value}
        v-model:openKeys={
    
    openKeys.value}
      >
        {
    
    menuList}
      </a-menu>
    );
  },
});
</script>

For the complete project code address, please refer to: https://gitee.com/ZHANG_6666/crm-template/blob/develop/src/components/Menu/Menu.vue
If the current scaffolding does not support jsx syntax compilation, you need to install jsx syntax support Bag

npm i @vitejs/plugin-vue-jsx -s

Guess you like

Origin blog.csdn.net/weixin_43835425/article/details/130673990