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实现购物小球抛物线的方法实例
Nov 22 Vue.js
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
Dec 02 Vue.js
vue $router和$route的区别详解
Dec 02 Vue.js
vue实现两个区域滚动条同步滚动
Dec 13 Vue.js
基于vue+echarts数据可视化大屏展示的实现
Dec 25 Vue.js
vue中封装axios并实现api接口的统一管理
Dec 25 Vue.js
Vue项目打包部署到apache服务器的方法步骤
Feb 01 Vue.js
vue常用高阶函数及综合实例
Feb 25 Vue.js
Vue3.0 手写放大镜效果
Jul 25 Vue.js
详解Vue的列表渲染
Nov 20 Vue.js
教你部署vue项目到docker
Apr 05 Vue.js
vue.js 使用原生js实现轮播图
Apr 26 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
phpmyadmin中配置文件现在需要绝密的短语密码的解决方法
2007/02/11 PHP
php 动态多文件上传
2009/01/18 PHP
在Nginx上部署ThinkPHP项目教程
2015/02/02 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
详解Yii2 之 生成 URL 的方法
2017/06/16 PHP
初识javascript 文档碎片
2010/07/13 Javascript
js对象的复制继承实例
2015/01/10 Javascript
JS实现图片延迟加载并淡入淡出效果的简单方法
2016/08/25 Javascript
vue.js将unix时间戳转换为自定义时间格式
2017/01/03 Javascript
Web开发中客户端的跳转与服务器端的跳转的区别
2017/03/05 Javascript
validationEngine 表单验证插件使用实例代码
2017/06/15 Javascript
webpack开发跨域问题解决办法
2017/08/03 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
2018/01/25 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
Vue ElementUi同时校验多个表单(巧用new promise)
2018/06/06 Javascript
bootstrap里bootstrap动态加载下拉框的实例讲解
2018/08/10 Javascript
总结javascript三元运算符知识点
2018/09/28 Javascript
Vue 框架之键盘事件、健值修饰符、双向数据绑定
2018/11/14 Javascript
解决微信浏览器缓存站点入口文件(IIS部署Vue项目)
2019/06/17 Javascript
vue-cli3配置与跨域处理方法
2019/08/17 Javascript
[51:27]LGD vs Liquid 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
Python中关键字global和nonlocal的区别详解
2018/09/03 Python
pandas数据集的端到端处理
2019/02/18 Python
PyQt编程之如何在屏幕中央显示窗体的实例
2019/06/18 Python
pandas 对group进行聚合的例子
2019/12/27 Python
基于HTML5 Canvas:字符串,路径,背景,图片的详解
2013/05/09 HTML / CSS
美国高端医师级美容产品电商:BeautifiedYou.com
2017/04/17 全球购物
彼得罗夫美国官网:Peter Thomas Roth美国(青瓜面膜)
2017/11/05 全球购物
FC-Moto瑞典:欧洲最大的摩托车服装和头盔商店之一
2018/11/27 全球购物
大学军训自我鉴定
2013/12/15 职场文书
先进德育工作者事迹材料
2014/01/24 职场文书
销售求职信范文
2014/05/26 职场文书
车间安全生产管理制度
2015/08/06 职场文书
python引入其他文件夹下的py文件具体方法
2021/05/23 Python
如何用PHP实现分布算法之一致性哈希算法
2021/05/26 PHP