vue 递归组件的简单使用示例


Posted in Vue.js onJanuary 14, 2021

前言

递归 相信很多同学已经不陌生了,算法中我们经常用递归来解决问题。比如经典的:从一个全为数字的数组中找出其中相加能等于目标数的组合。思路也不难,循环数组取值,不断递归相加,直到满足目标数条件。递归虽然能解决大部分,但弊处在于,很容易写出死循环的代码,导致爆栈。下面以我实际业务场景讲讲递归在vue组件中的应用。

在vue中使用

完成一个完整的递归,我个人认为最重要的有两点:

  1. 确定好进入递归的条件;
  2. 确定好跳出递归的条件;

其中最重要的就是确定 什么时候跳出递归。递归组件实际上非常简单,就是 A组件 里再调用 A组件,就形成了一个递归。以下面我遇到的业务来说,某天接到一个需求,需要在一堆用户中根据不同标签条件组合筛选出目标用户,因此就有如下设计图:

vue 递归组件的简单使用示例

咋一看,可能会被懵住,但其实只要经过仔细分析,发现并不是很难,看图不少同学会感觉,有点像我们常说的 套娃, 一层套一层。对于这种图,我们首要分析其中 最小单元 是哪一个,上图中很容易看出最小的是这一块。图中的大结构基本都是由这一小块组合而成,只要先实现了这块,其他无非就是通过 递归 来一层一层数据渲染。

vue 递归组件的简单使用示例

后面的无非就是判断数据结构,如果没有子树的话,就直接简单渲染该项目。如果某项含有子树的话,就得要重新渲染这块组件,将子数据传递进去。所以思路其实非常简单,假设我们的数据结构是这样的:

{
 type: 'or',
 valueList: [
  {	
   condition: '最近7天登录次数',
   login: '!=',
   value: 45
  },
  {	
   condition: '最近7天登录次数',
   login: '!=',
   value: 45
  },
  {
   type: 'and'
   valueList: [
   	{
     condition: '最近7天登录次数',
     login: '!=',
     value: 45
    }
   ]
  }
 ]
}

上面数据结构很清晰,可以看到当数组里面的子项目包含有 valueList 时表明需要重新渲染上图所说的一小块组件。因此我们可以简单编码如下(下面代码还有可优化的地方):

<template>
 <div class="label-list">
  <el-tag type="primary" size="mini" class="logic">{{ typeDict[treedata.type] }}</el-tag>
  <template v-for="(item, index) in treedata.valueList">
   <ul v-if="!item.hasOwnProperty('valueList')" :key="'rule_' + index">
    <li>{{ item.condition }} {{ item.logic }} {{ item.value }}</li>
   </ul>
  </template>
  <template v-for="(item, index) in treedata.valueList">
   <!-- 此处判断有 valuelist 因此再次调用渲染本组件 进行子项的渲染 -->
   <label-shows-view v-if="item.hasOwnProperty('valueList')" :key="'tree_' + index" :treedata="item"></label-shows-view>
  </template>
 </div>
</template>
<script>
const _TYPE = {
 'and': '且',
 'or': '或'
}
export default {
 name: 'LabelShowsView',
 props: {
  treedata: {
   type: Object,
   required: true
  }
 },
 data() {
  return {
   typeDict: _TYPE
  }
 }
}
</script>

不难看出,主要是要分析找出数据结构中重复的部分,一层一层渲染下去。其实,对于上面例子是纯展示来说比较容易理解,如果加上有数据交互的话,就需要额外注意了。递归层级很深的话,事件传递、数据变更等都需要小心处理,就比如笔者在完成上述可视化配置筛选客群时就遇到了如下图的:

vue 递归组件的简单使用示例

可以添加、删除子项,并且还可以拖拽每组进行位置的调整。这时就可以利用类似 冒泡 的方法,子组件即触发事件也接受事件。比如删除某一组条件时,需要通知父组件要删除的是子数据的哪一项,如下:

<!-- labelRulesView.vue -->
<!-- 这个自定义组件就是本组件 即递归的组件 -->
<label-rules-view v-if="item.hasOwnProperty('valueList')" :label-list="labelList" :treedata="item" :current-index="index" @delGroup="funDelGroup"></label-rules-view>
<!-- 本组件监听 delGroup 事件 -->
 
<el-button size="mini" type="danger" icon="el-icon-delete" class="operate-btn" @click="handleDelNewGroup(currentIndex)"></el-button>

// 删除某个组
handleDelNewGroup(index) {
 this.$emit('delGroup', index) // 向上层组件触发事件
},
funDelGroup(index) {
 this.treedata.valueList.splice(index, 1)
},

在递归组件中,很多时候这个组件即扮演着子组件,也扮演着父组件。因此要控制好数据之间的交互,否则很容易出现数据错乱的情况

小结

本文是笔者在实际业务场景中遇到并顺手记录,利用递归组件,我们甚至可以完成一些比较复杂的图形展示。希望能帮到大家拓宽下思路,帮到你的话还是顺手点个小心心(拒绝下次一定[doge])

以上就是vue 递归组件的简单使用示例的详细内容,更多关于vue 递归组件的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue+element_ui上传文件,并传递额外参数操作
Dec 05 Vue.js
在vue中动态修改css其中一个属性值操作
Dec 07 Vue.js
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 Vue.js
vue中实现点击空白区域关闭弹窗的两种方法
Dec 30 Vue.js
vue组件是如何解析及渲染的?
Jan 13 Vue.js
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 Vue.js
Vue单页面应用中实现Markdown渲染
Feb 14 Vue.js
vue实现简单数据双向绑定
Apr 28 Vue.js
vue-cropper组件实现图片切割上传
May 27 Vue.js
SSM VUE Axios详解
Oct 05 Vue.js
分享一个vue实现的记事本功能案例
Apr 11 Vue.js
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
vue element和nuxt的使用技巧分享
Jan 14 #Vue.js
vue动态设置路由权限的主要思路
Jan 13 #Vue.js
vue组件是如何解析及渲染的?
Jan 13 #Vue.js
vue实现一个获取按键展示快捷键效果的Input组件
Jan 13 #Vue.js
vue使用vue-quill-editor富文本编辑器且将图片上传到服务器的功能
Jan 13 #Vue.js
基于VUE实现简单的学生信息管理系统
Jan 13 #Vue.js
详解为什么Vue中的v-if和v-for不建议一起用
Jan 13 #Vue.js
You might like
php去掉文件前几行的方法
2015/07/29 PHP
PHP动态生成指定大小随机图片的方法
2016/03/25 PHP
PHP中静态变量的使用方法实例分析
2016/12/01 PHP
PHP实现图片批量打包下载功能
2017/03/01 PHP
PHP封装的page分页类定义与用法完整示例
2018/12/24 PHP
用正则表达式 动态创建/增加css style script 兼容IE firefox
2009/03/10 Javascript
动态的改变IFrame的高度实现IFrame自动伸展适应高度
2012/12/28 Javascript
jquery移动节点实例
2015/01/14 Javascript
JS实现鼠标滑过折叠与展开菜单效果代码
2015/09/06 Javascript
jQuery实现分章节锚点“回到顶部”动画特效代码
2015/10/23 Javascript
JS实现图片高亮展示效果实例
2015/11/24 Javascript
jquery mobile 移动web(5)
2015/12/20 Javascript
怎样判断jQuery当前元素是隐藏还是显示
2016/11/23 Javascript
js实现自动图片轮播代码
2017/03/22 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
详解vue如何使用rules对表单字段进行校验
2018/10/17 Javascript
Vue.js实现大转盘抽奖总结及实现思路
2019/10/09 Javascript
layui实现显示数据表格、搜索和修改功能示例
2020/06/03 Javascript
原生js+canvas实现下雪效果
2020/08/02 Javascript
把大数据数字口语化(python与js)两种实现
2013/02/21 Python
python中xrange用法分析
2015/04/15 Python
Python实现判断字符串中包含某个字符的判断函数示例
2018/01/08 Python
Python cookbook(数据结构与算法)通过公共键对字典列表排序算法示例
2018/03/15 Python
python3 遍历删除特定后缀名文件的方法
2018/04/23 Python
Python实现抓取HTML网页并以PDF文件形式保存的方法
2018/05/08 Python
对pandas中Series的map函数详解
2018/07/25 Python
关于Python3 类方法、静态方法新解
2019/08/30 Python
如何在python开发工具PyCharm中搭建QtPy环境(教程详解)
2020/02/04 Python
谈谈Python:为什么类中的私有属性可以在外部赋值并访问
2020/03/05 Python
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
男方父母婚礼答谢词
2014/01/25 职场文书
学位证书委托书
2014/09/30 职场文书
大学生英文求职信范文
2015/03/19 职场文书
2015年校医个人工作总结
2015/07/24 职场文书
浅谈如何提高PHP代码质量之端到端集成测试
2021/05/28 PHP
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技