精华内容
下载资源
问答
  • vue组件递归
    2022-01-04 15:53:31

    前言

    最近看项目发现了在菜单展示上面用到了组件的递归,跟函数递归类似,就是组件内部调用自己。

    实现

    用途
    组件递归一般会用到像菜单这样的树形结构,不确定层级时可以通过组件递归实现。

    实例

    使用页面

    <template>
        <div>
            <my-tree :menu-data="menuData"></my-tree>
        </div>
    </template>
    
    <script>
    import myTree from './recursion.vue';
    export default {
        components: {
            myTree
        },
        data() {
            return {
                menuData: [
                    {
                        text: '1',
                        children: [
                            {
                                text: '1-2',
                                children: []
                            }
                        ]
    
                    },
                    {
                        text: '2',
                        children: []
                    }
                ]
            };
        },
        methods: {
    
        }
    };
    </script>
    
    <style scoped lang="scss">
    
    </style>
    

    组件

    <template>
        <ul>
            <li v-for="(item,index) in menuData" :key="index">
                <div>{{ item.text }}</div>
                <my-tree v-if="item.children.length>0" :menu-data="item.children"></my-tree>
            </li>
        </ul>
    </template>
    
    <script>
    export default {
        name: 'myTree',
        props: {
            menuData: {
                type: Array,
                default: () => []
            }
        },
        data() {
            return {
            };
        },
        methods: {
    
        }
    };
    </script>
    

    效果
    在这里插入图片描述

    注意点

    • 组件内部要给组件加上name这个属性,否则无法自己调用自己
    • 循环层级时要循环props属性,v-for="(item,index) in menuData" :key="index"
    更多相关内容
  • vue 组件递归调用

    2018-07-03 11:53:30
    vue组件递归调用,展示树状结构,
  • vue组件递归

    千次阅读 2022-02-14 19:10:02
    这时我们可以使用组件递归的思想来实现: 如下demo: 1、定义菜单组件 <template> <ul> <li v-for="(item, index) in list" :key="index"> <p>{{ item.name }}</p> <tree...

    项目中出现多级菜单时,需要多层for循环时,但是当菜单增加层级时,需要在页面结构中增加一层for循环。

    这时我们可以使用组件递归的思想来实现:

    如下demo:

    1、定义菜单组件

    <template>
      <ul>
        <li v-for="(item, index) in list" :key="index">
          <p>{{ item.name }}</p>
          <treeMenu :list="item.children"></treeMenu>
        </li>
      </ul>
    </template>
    
    <script>
    export default {
      name: "treeMenu",
      props: ["list"],
      data() {
        return {};
      },
    };
    </script>
    
    <style scoped>
    ul {
      padding-left: 20px;
    }
    </style>
    

    2、组件调用

    3、效果图:

     

     

    展开全文
  • 不知道大家有没遇到过这样的场景:渲染列表数据的时候,列表的子项还是列表。如果层级少尚且可以用几个for循环搞定,但是层级多或者层级不确定就有点无从下手了。 其实这就是树形结构数据,...答案就是——组件递归

    前言

    不知道大家有没遇到过这样的场景:渲染列表数据的时候,列表的子项还是列表。如果层级少尚且可以用几个for循环搞定,但是层级多或者层级不确定就有点无从下手了。

    其实这就是树形结构数据,像常见的组织架构图,文件夹目录,导航菜单等都属于这种结构。很多组件库都带有树形组件,但往往样式不是我们想要的,改起来也非常的费劲。那么,如何自己渲染这些数据呢?答案就是——组件递归!
    在这里插入图片描述

    使用组件递归,并加入简单交互的展示效果。点击节点会在控制台输出节点对应的数据,如果有子节点,则会展开或收起子节点。接下来我们就看看如何实现以上效果吧!

    渲染完整数据

    渲染数据这一步非常简单,首先是把树形结构封装成一个列表组件,其次判断每一项有没有子节点,如果有子节点,再使用自身组件去渲染就可以了。

    src/components/myTree.vue

    <template>
      <div class="tree-item">
        <div v-for="item in treeData" :key="item.id">
          <div class="item-title">{{ item.name }}</div>
          <div v-if="item.children && item.children.length" class="item-childen">
            <my-tree :treeData="item.children"></my-tree>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'myTree',
      props: {
        treeData: {
          type: Array,
          default: () => []
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .tree-item {
      .item-title {
        padding: 4px 8px;
      }
      .item-childen {
        padding-left: 20px;
      }
    }
    </style>
    

    src/App.vue

    <template>
      <my-tree :tree-data="treeData"></my-tree>
    </template>
    
    <script>
    const treeData = [
      { id: 1, name: '一级1' },
      {
        id: 2,
        name: '一级2',
        children: [
          { id: 3, name: '二级2-1' },
          { id: 4, name: '二级2-2' }
        ]
      },
      {
        id: 5,
        name: '一级3',
        children: [
          {
            id: 6,
            name: '二级3-1',
            children: [
              { id: 7, name: '三级3-1-1' },
              { id: 8, name: '三级3-1-2' }
            ]
          },
          { id: 9, name: '二级3-2' },
          { id: 10, name: '二级3-3' }
        ]
      }
    ]
    import myTree from '@/components/myTree.vue'
    export default {
      components: {
        myTree
      },
      data() {
        return {
          treeData: treeData
        }
      }
    }
    </script>
    

    获取节点数据

    接下来我们要做的是,点击节点时在控制台输出对应的数据。首先我们使用 $emit,将一级节点的 item 传递出去,也就是子传父的方法,相信大家都会。

    其次是将内层节点的数据传递出去,同样使用子传父的方法,只是我们需要给组件里面的 my-tree 绑定@node-click=“$emit(‘node-click’, $event)”,这样每次子级每次都可以调用父级的 node-click 方法,父级又调用它的父级 node-click 方法,最终调的都是最外层的 node-click 方法,我们只需要在这个过程中,把数据传递过去就可以了。这块有点绕,相信大家多看几遍应该可以看懂。修改如下:

    src/components/myTree.vue

    <div class="item-title" @click="itemNodeClick(item)">{{ item.name }}</div>
    <div v-if="item.children && item.children.length" class="item-childen">
      <my-tree
        :treeData="item.children"
        @node-click="$emit('node-click', $event)"
      ></my-tree>
    </div>
    ...
    itemNodeClick(item) {
      this.$emit("node-click", item)
    }
    

    src/App.vue

    <my-tree :tree-data="treeData" @node-click="nodeClick"></my-tree>
    ...
    nodeClick(val) {
      console.log(val)
    }
    

    动态展开收起

    这一步的思路是给组件设置一个数组,数组中存放的是当前列表中需要展开的节点的id,当点击节点的时候添加或删除节点id,然后判断每个节点的id在不在这个数组,在则显示子节点,不在则隐藏子节点。

    src/components/myTree.vue

    <div class="item-title" @click="nodeClick(item)">
      <span>{{ item.name }}</span>
      <span v-if="item.children && item.children.length">
        [{{ isOpen(item.id) ? '-' : '+' }}]
      </span>
    </div>
    <div
      v-if="item.children && item.children.length"
      v-show="isOpen(item.id)"
      class="item-childen"
    >
      <my-tree
        :treeData="item.children"
        @node-click="$emit('node-click', $event)"
      ></my-tree>
    </div>
    ...
    data() {
      return {
        expandedKeys: [] // 当前列表需要展开的节点id组成的数组
      }
    },
    methods: {
      nodeClick(item) {
        this.$emit('node-click', item)
        if (item.children && item.children.length) {
          let index = this.expandedKeys.indexOf(item.id)
          if (index > -1) {
            // 如果当前节点id存在数组中,则删除
            this.expandedKeys.splice(index, 1)
          } else {
            // 如果当前节点id不存在数组中,则添加
            this.expandedKeys.push(item.id)
          }
        }
      },
      isOpen(id) {
        // 判断节点id在不在数组中,在则显示,不在则隐藏
        return this.expandedKeys.includes(id)
      }
    }
    

    完整代码

    src/components/myTree.vue

    <template>
      <div class="tree-item">
        <div v-for="item in treeData" :key="item.id">
          <div class="item-title" @click="nodeClick(item)">
            <span>{{ item.name }}</span>
            <span v-if="item.children && item.children.length">
              [{{ isOpen(item.id) ? '-' : '+' }}]
            </span>
          </div>
          <div
            v-if="item.children && item.children.length"
            v-show="isOpen(item.id)"
            class="item-childen"
          >
            <my-tree
              :treeData="item.children"
              @node-click="$emit('node-click', $event)"
            ></my-tree>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'myTree',
      props: {
        treeData: {
          type: Array,
          default: () => []
        }
      },
      data() {
        return {
          expandedKeys: [] // 当前展开的节点id组成的数组
        }
      },
      methods: {
        nodeClick(item) {
          this.$emit('node-click', item)
          if (item.children && item.children.length) {
            let index = this.expandedKeys.indexOf(item.id)
            if (index > -1) {
              // 如果当前节点id存在数组中,则删除
              this.expandedKeys.splice(index, 1)
            } else {
              // 如果当前节点id不存在数组中,则添加
              this.expandedKeys.push(item.id)
            }
          }
        },
        isOpen(id) {
          // 判断节点id在不在数组中,在则显示,不在则隐藏
          return this.expandedKeys.includes(id)
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .tree-item {
      cursor: pointer;
      .item-title {
        padding: 4px 8px;
        &:hover {
          background: #eee;
        }
      }
      .item-childen {
        padding-left: 20px;
      }
    }
    </style>
    

    src/App.vue

    <template>
      <my-tree :tree-data="treeData" @node-click="nodeClick"></my-tree>
    </template>
    
    <script>
    const treeData = [
      { id: 1, name: '一级1' },
      {
        id: 2,
        name: '一级2',
        children: [
          { id: 3, name: '二级2-1' },
          { id: 4, name: '二级2-2' }
        ]
      },
      {
        id: 5,
        name: '一级3',
        children: [
          {
            id: 6,
            name: '二级3-1',
            children: [
              { id: 7, name: '三级3-1-1' },
              { id: 8, name: '三级3-1-2' }
            ]
          },
          { id: 9, name: '二级3-2' },
          { id: 10, name: '二级3-3' }
        ]
      }
    ]
    import myTree from '@/components/myTree.vue'
    export default {
      components: {
        myTree
      },
      data() {
        return {
          treeData: treeData
        }
      },
      methods: {
        nodeClick(val) {
          console.log(val)
        }
      }
    }
    </script>
    
    展开全文
  • vue组件递归调用

    2020-10-16 17:07:46
    利用自身组件递归,达到无限极菜单效果 文件VMenu.vue源代码如下 <template> <ul> <li v-for="(item,index) in listdata"> <span @click="handle(item)">{{item.title}}</span> &...

    一、子组件VMenu

    利用自身组件递归,达到无限极菜单效果
    文件VMenu.vue源代码如下

    <template>
      <ul>
        <li v-for="(item,index) in listdata">
          <span @click="handle(item)">{{item.title}}</span>
          <v-menu :listdata='item.children' v-if="item.children" v-show="item.flag">
          </v-menu>
        </li>
      </ul>
    </template>
    <script>
      import VMenu from './VMenu'
      export default {
        name: 'VMenu',
        components: {
          VMenu
        },
        props: ['listdata'],
        methods: {
          handle: function(item) {
            item.flag = !item.flag;
          }
        }
      }
    </script>
    <style>
      ul {
        text-align: left;
      }
    
      li {
        cursor: pointer;
      }
    </style>
    
    

    二、父组件调用子组件

    <template>
      <div id="app">
        <v-menu :listdata="listdata">
        </v-menu>
      </div>
    </template>
    <script>
      import VMenu from '@/components/VMenu.vue';
      export default {
        components: {
          VMenu
        },
        data() {
          return {
            listdata: [{
              title: '一级菜单',
              flag: true,
              children: [{
                title: '二级菜单',
                flag: true,
                children: [{
                  title: '三级菜单'
                }, ]
              }, {
                title: '二级菜单'
              }, {
                title: '二级菜单'
              }, {
                title: '二级菜单'
              }, ]
            }, {
              title: '一级菜单',
              flag: true,
            }, {
              title: '一级菜单',
              flag: true,
              children: [{
                title: '二级菜单'
              }, ]
            }, {
              title: '一级菜单',
              flag: true,
            }, ]
          }
        },
      }
    </script>
    <style>
    </style>
    
    

    三、最终效果

    无限极菜单展示,可收缩折叠
    在这里插入图片描述

    展开全文
  • Vue组件递归渲染

    2021-12-29 16:05:43
    '三级标题', } ] }, {title: '二级标题'}, {title: '二级标题'}, ] } ] 子组件递归(直接使用name) <template> <div> (item,index) in asideChildren" v...
  • 问题描述组件A里面引用组件B,组件B同时又引用组件A,就这么简单,但是总是报如下错误:[Vue warn]: Failed to mount component: template or render function not defined最小复现代码index.vue:.test-node {...
  • 如果菜单嵌套层数是已知的可以通过 v-for 循环出要渲染的菜单,但是...将我们的菜单封装到组件中,通过递归组件实现菜单渲染 先贴一个 demo 图 demo地址:https://download.csdn.net/download/qq_25992675/1285387.
  • vue实现组件递归 调用效果及代码 <!-- * @Date: 2020-12-09 17:52:54 * @Author: surewinT 840325271@qq.com * @LastEditTime: 2022-05-10 14:14:15 * @LastEditors: surewinT 840325271@qq.com * @Desc
  • vue 组件递归

    2021-06-26 04:13:47
    组件递归常用到的栗子就比如树形结构的创建,需要自调用进行递归渲染下面是递归组件渲染tree的效果图:效果.jpeg完整的代码仓库地址:https://github.com/HuangPingP/vue-tree1、创建一个treeMenu.vue的组件文件,...
  • vue 组件递归嵌套

    2021-05-19 11:18:16
    this.$options.components.ComponentName = require('@/components/ComponentName.vue').default; }, components: { ComponentName: () => import('@/components/ComponentName.vue') }, componentName: '...
  • 出问题的地方在组件递归调用自己时,代码如下: 在Menus组件内递归调用Menus,其他项目通过 npm i vue-contextmenus安装调用。 待页面展示二级目录时报错 后经测试,发现一个临时解决方案,暂时没找到合理的...
  • Vue组件递归 及 循环依赖 解决办法

    千次阅读 2022-03-20 23:33:06
    组件递归(引入自己) 在写一个menu组件时,需要用到递归生成组件树的方法。 但是 “怎么在这个组件内部引入自己????” 解决办法 添加name option,无需注册组件,直接在内部使用<MenuItem></...
  • vue 组件递归(组件自己调用自己)

    千次阅读 2021-11-04 11:04:35
    vue 组件递归 项目中,用到 el-menu, 侧边栏导航动态加载时,需要用到组件递归,不然js写逻辑,有点繁琐。 干货多,屁话少,上代码 给组件name值 export default { name: "submenu", // 必须给name值 } 直接在...
  • vue组件递归遍历

    2022-08-11 14:30:56
    参考vue文件地址:递归组件 实现遍历效果 递归组件 实现思路: 遍历数组元素,并判断子元素的子集数量是否大于0。 如果子集的集合数量大于0,则需要需要再一次调用该组件。 如果子集的集合数量等于0,则直接显示内容...
  • 3、使用时传入参数的方式和组件在其他组件中使用相同,注意递归终止条件 <xx :props="props"> 倘若组件需要传参数 代码示例: 数据: list: [{ name: "经济", children: [{ name: "如家" }, { name: "7天...
  • uniapp/vue 组件递归

    2021-03-12 09:36:38
    因为没有思路所以在网上查询组件递归的方法。最终结合搜索到了一种组件递归调用方法。 记录时间 20210312 效果如下图: html代码块: 1、在执行这一块的时候 因为需要点击触发emit事件,所以执行了selectClassify...
  • vue组件递归调用时使用按需加载避免name重复问题
  • " :list='list'></sb-tree> <sb-tree :list='list1' :keys='k1'></sb-tree> </div> <script> Vue.component('sb-tree', { template: ` {{item.label}} `, props: { list: { type: Array, require: true, }, keys: { ...
  • vue 组件递归后$emit传值失效的问题(这里提供三个解决思路,建议使用最后一个) 分析原因 1.首先造成传值失效的问题是组件递归后事件传递不到上层。所以造成的问题是在递归组件的第二层里面,监听不到当前事件。 ...
  • Vue实现递归组件

    千次阅读 2022-04-05 21:58:31
    Vue实现递归组件 文章目录Vue实现递归组件前言一、递归组件是什么?二、Vue实现递归的核心思路三、代码示例1.父级2.子级3、实现效果四、总结 前言 在我们开发过程中,为了提高开发效率,降低开发难度,我们会直接...
  • 在我们平常的开发中组件递归很常见,一般情况下递归有两种类型,一种是自递归如:A->A->A,另一种是相互递归如:A->B->A。对于A->A单个组件自递归的情况,vue推荐使用name来解决,用法非常简单。 //...
  • vue组件递归(组件内引入自己) 今天看到大佬在vue项目中有个写法,在组件引用自身,一时觉得神奇,从未用到过,今天记录下。 1、现在组件内export default {}中设置好name值。 2、组件内引用是直接使用同名标签 ...
  • vue 组件如何递归调用自己

    千次阅读 2022-02-10 16:42:19
    第一点:要用好name属性,递归调用 第二点:要用好v-if,限制递归的条件,不能无限制递归下去,只能满足某一条件才能渲染。
  • vue 递归组件

    2022-08-05 15:29:01
    递归组件就是在模板中引用自身的组件 我们有时希望在一个组件内部渲染该组件本身,例如渲染树形结构时,需要在树根渲染子树,而子树与树根的结构是一样的,因此存在递归
  • 主要给大家介绍了关于Vue动态组件和异步组件原理的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,917
精华内容 5,966
关键字:

vue组件递归

友情链接: logopass.zip