递归组件组合拳,无惧页面嵌套

介绍

递归组件在组件内嵌套组件时比较常用,我在这里举几个例子:

1、后台管理系统的menu菜单

2、教育系统的题目列表

在遍历生成基础题时,遇到了综合题,综合题包含了所有基础题,此时就不用再写一遍基础题,直接调用自身组件即可,这样不论基础题内部嵌套多少层综合题,都可以生成题目列表。


如何实现递归组件?

父页面:正常引入组件

javascript 复制代码
// 父页面
<template>
    <div>
        <Circulation :dataInfo="dataInfo"/>
    </div>
</template>
 
<script>
import Circulation from '@/views/circulation.vue'
export default {
    components: { Circulation },
    data() {
        return {
          dataInfo: [
            // ......
          ]
        }
    },
}
</script>

子组件

javascript 复制代码
// circulation页面
<template>
    <div>
       <div v-for="item in dataInfo"></div>
        // 其它逻辑......

        // 假如遇到children -> 复用自身 
        <Circulation :dataInfo="item.children"/>
    </div>
</template>
 
<script>
export default {
    name: 'Circulation', // 一定要设置name,于组件名相同
    props: {
        dataInfo: {
            type: Array,
            default: () => {
                return []
            }
        },
    },
}
</script>

上面的代码就实现了递归组件,在子组件中不需要引入自身,只需要设置name,然后通过name复用组件即可 下面是你在教育类型项目中会遇到的场景:


注意点

1、事件冒泡

注意:递归组件的事件一定要用.stop阻止冒泡,否则会报错 例如:@click.stop="onClose(item)"

2、prop值更新

在递归组件中通过事件更改prop的值时,会报错,提示请避免在子组件中对prop进行直接更改 Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "questionList" 避免直接更改 prop,因为每当父组件重新渲染时,该值都会被覆盖。相反,请使用基于道具值的数据或计算属性。被变异的道具:"questionList" 递归组件尽量避免直接对prop进行修改,哪怕你使用了计算属性,也会报错提示。

3、递归组件深层事件

由于是递归组件,层级的嵌套可能会很深,但是页面只有当前这一个,如果只处理当前层级的逻辑可以直接@click.stop="xxx"触发 如果需要将事件向父级回传,则需要使用emit,并且自身页面的递归组件上也需要设置事件,例如:

javascript 复制代码
// 父页面
<template>
    <div>
        <Circulation :dataInfo="dataInfo" @onChange="onChange"/>
    </div>
</template>
<script>
import Circulation from '@/views/circulation.vue'
export default {
    components: { Circulation },
    data() {
        return {
          dataInfo: [
            // ......
          ]
        }
    },
    methods: {
      // 触发事件 
      onChange() {},
    }
}
</script>

子页面

javascript 复制代码
// circulation页面
<template>
    <div>
       <div v-for="item in dataInfo"></div>
        // 其它逻辑......

        // 假如遇到children -> 复用自身 
        <Circulation :dataInfo="item.children"  @onChange="onChange"/>
    </div>
</template>
 
<script>
export default {
    name: 'Circulation', // 一定要设置name,于组件名相同
    props: {
        dataInfo: {
            type: Array,
            default: () => {
                return []
            }
        },
    },
    methods: {
      // 触发回传
      onChange() {
        this.$emit('onChange')
      },
    }
}
</script>

这样做它的回传事件会层层递归,直到返回最上层。 在渲染层面,它是层层递。 在事件回传层面,它是层层归。


如果觉得该组件不错,欢迎点赞👍、收藏💖、转发✨哦~

阅读其它:

微信小程序用户隐私API(👈点击直达)

前端换肤,聊一聊主题切换那些事(👈点击直达)

Shapes布局-文字环绕动画(👈点击直达)

css绘制一个Pinia小菠萝(👈点击直达)

深入理解Promise(👈点击直达)

相关推荐
Miketutu18 分钟前
Flutter学习 - 组件通信与网络请求Dio
开发语言·前端·javascript
摘星编程22 分钟前
React Native for OpenHarmony 实战:Swiper 滑动组件详解
javascript·react native·react.js
鸣弦artha40 分钟前
Flutter框架跨平台鸿蒙开发——Build流程深度解析
开发语言·javascript·flutter
QQ4022054962 小时前
python基于vue的大学生课堂考勤系统设计与实现django flask pycharm
vue.js·python·django
光影少年2 小时前
前端如何调用gpu渲染,提升gpu渲染
前端·aigc·web·ai编程
Surplusx2 小时前
运用VS Code前端开发工具完成网页头部导航栏
前端·html
小宇的天下3 小时前
Calibre 3Dstack --每日一个命令day13【enclosure】(3-13)
服务器·前端·数据库
LongJ_Sir3 小时前
Cesium--可拖拽气泡弹窗(Vue3版)
javascript
跟着珅聪学java3 小时前
JavaScript 中定义全局变量的教程
javascript
一只小bit4 小时前
Qt 文件:QFile 文件读写与管理教程
前端·c++·qt·gui