Vue冷门技巧递归组件实践示例详解

 更新时间:2023年03月06日 10:23:00   作者:JetTsang  
这篇文章主要为大家介绍了Vue冷门技巧递归组件实践示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

痛点引出

在平时的开发当中,渲染侧边栏导航菜单有时会遇到过需要侧边栏有多层甚至无限层级的问题。此时更优雅的方式便是使用递归组件

<el-menu>
        <template slot="title">
          <i class="el-icon-location"></i>
          <span>菜单</span>
        </template>
        <el-submenu index="1-1">
          <template slot="title">子菜单</template>
          <el-menu-item index="1-1-1">子菜单选项1</el-menu-item>
          <el-submenu index="1-1-2">  
            <template slot="title">子菜单的子菜单</template>
            <el-menu-item index="1-1-2-1">子菜单的子菜单的选项1</el-menu-item>
          </el-submenu>
        </el-submenu>
      </el-submenu>
</el-menu>

可以看到这部分重复的代码可以完全抽离出来做单独的组件。

<el-submenu>
    <el-menu-item></el-menu-item>
    ...
</el-submenu>

那么问题来了,在一层当中又有重复的submenu怎么办?显然这个层级是需要动态生成的。比如:

<el-submenu>
    <el-menu-item></el-menu-item>
    ...
    <el-submenu>
        <el-menu-item></el-menu-item>
        ...
        <el-submenu>
            <el-menu-item></el-menu-item>
            ...
            //这里省略很多很多层
        </el-submenu>
    </el-submenu>
</el-submenu>

很明显,这里需要可以用递归(recursive) 的思想来解决, 那么在template模版当中有办法做这样的组件吗?答案当然是可以,template模版语法也是支持递归。

源码中的体现

先找找源码,我们在src/core/global-api.ts当中找到initExtend函数,这个函数是initGlobalAPI的一个执行步骤,每个组件创建的时候都会去调用。

可以看到如果命中name,则会给自己的components的配置项当中注册自己,使得可以在编译的时候可以识别到自己,从而在template模版语法当中去使用。

组件示例封装

首先定义数据结构能描述这样的菜单

[
    {
        id: '1',
        title: '父菜单',
        children:[
            {id:'1-1',title:'子选项',children:[]},
            {id:'1-1',title:'子菜单',children:[
                {id:...,title:...,children:...},
                ...
            ]},
            ...
        ]
    }
]
简单点描述就是
interface item:{
    id: string,
    title: string,
    children: item[] | []
}
item[]

然后开始封装组件

// RescursiveMenu.vue
<template>
    <el-submenu :index="menuItem.id" v-if="menuItem.children.length">
        <template slot="title">{{ menuItem.title }}</template>
            <template v-for="item in menuItem.children">
                <RecursiveMenu :menuItem="item"/>
            </template>
    </el-submenu>
    <el-menu-item v-else>{{ menuItem.title }}</el-menu-item>
</template>
<script>
export default {
    name:"RecursiveMenu",
    props: {
        menuItem: Object
    }
}
</script>

当然这只是简单示例demo,后续根据业务需求相信难不倒各位看官。

使用:

<el-submenu>
    <template v-for="item in menuList.children">
       <RecursiveMenu :menuItem="item" :key="item.id"/>
   </template>
</el-submenu>

小扩展

同样的,vue也支持jsx/tsx语法 ,使用jsx则需要抽象需要重复的过程,封装成渲染函数来实现递归,这里采用整个数组渲染过程抽象重复,来实现递归。

//MyMenu.jsx
export default {
    name:"RecursiveMenu",
    props: {
        menuList: Array,
        dafault:()=>([])
    },
    render(){
        const recursiveRender = (menuList)=>{
                return menuList.map((menuItem)=>{
                        return menuItem.children.length > 0 ? (
                            <elSubmenu index="{menuItem.id}">
                            <div slot="title">{menuItem.title}</div>
                            {recursiveRender(menuItem.children)}
                            </elSubmenu>
                            ):(
                            <elMenuItem key="{menuItem.id}">{ menuItem.title }</elMenuItem>
                        )
                    }
                )
            }
            return (<elMenu>
                {recursiveRender(this.menuList)}
                </elMenu>
            )
    }
}

当然,如果想用jsx复刻上诉template当中抽象的逻辑,可以写成这样:

// RecursiveMenu.jsx
export default {
    name:"RecursiveMenu",
    props: {
        menuItem: Object,
        dafault:()=>({})
    },
    render(){
        const recursiveRender = (menuItem)=>{
            return menuItem.children.length > 0 ? (
                <elSubmenu index="{menuItem.id}">
                    <div slot="title">{menuItem.title}</div>
                    {menuItem.children.map(children=>recursiveRender(children))}
                </elSubmenu>
            ):(
                <elMenuItem key="{menuItem.id}">{ menuItem.title }</elMenuItem>
            )
        }
        return recursiveRender(this.menuItem)
    }
}

总结

Vue当中实现递归渲染,可以使用模版语法和jsx语法。而实现本质上是抽象出重复的逻辑,以及找到递归退出点。

以上就是Vue冷门技巧递归组件实践示例详解的详细内容,更多关于Vue 递归组件的资料请关注脚本之家其它相关文章!

相关文章

  • vue组件生命周期详解

    vue组件生命周期详解

    这篇文章主要为大家详细介绍了vue组件生命周期,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • postcss-pxtorem设置不转换UI框架的CSS单位问题

    postcss-pxtorem设置不转换UI框架的CSS单位问题

    这篇文章主要介绍了postcss-pxtorem设置不转换UI框架的CSS单位问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Element-UI el-table对循环产生的空白列赋默认值方式

    Element-UI el-table对循环产生的空白列赋默认值方式

    这篇文章主要介绍了Element-UI el-table对循环产生的空白列赋默认值方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 在Vue中实现二维码生成与扫描功能的方法

    在Vue中实现二维码生成与扫描功能的方法

    二维码是一种广泛应用于各种场合的编码方式,它可以将信息编码成一张二维图案,方便快捷地传递信息,在Vue.js中,我们可以使用一些库和组件来实现二维码的生成和扫描,本文将介绍如何在Vue中实现二维码的生成和扫描的方法
    2023-06-06
  • vue parseHTML源码解析hars end comment钩子函数

    vue parseHTML源码解析hars end comment钩子函数

    这篇文章主要为大家介绍了vue parseHTML源码解析hars end comment钩子函数示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • vue如何点击多个tab标签打开关闭多个页面

    vue如何点击多个tab标签打开关闭多个页面

    这篇文章主要介绍了vue如何点击多个tab标签打开关闭多个页面,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • 浅谈Vue.js组件(二)

    浅谈Vue.js组件(二)

    这篇文章主要介绍了Vue.js组件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Vue添加请求拦截器及vue-resource 拦截器使用

    Vue添加请求拦截器及vue-resource 拦截器使用

    这篇文章主要介绍了Vue添加请求拦截器及vue-resource 拦截器使用,需要的朋友可以参考下
    2017-11-11
  • Vue项目打包部署总结篇

    Vue项目打包部署总结篇

    这篇文章主要介绍了Vue项目打包部署总结篇,关于Vue项目发布的相关问题就先总结这么多,几乎在每一步都踩过坑才有所体会,有问题欢迎各位同学一起探讨,需要的朋友可以参考下
    2024-08-08
  • 详解Vue中一种简易路由传参办法

    详解Vue中一种简易路由传参办法

    本篇文章主要介绍了详解Vue中一种简易路由传参办法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09

最新评论