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

介绍

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

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(👈点击直达)

相关推荐
米米商聊36 分钟前
同名附件为什么被 Map 覆盖?重复键与一对多索引
前端·javascript
echome8882 小时前
Python 异常处理:try、else、finally 的正确搭配
开发语言·前端·python·异常处理·编程技巧
时间的情敌2 小时前
OpenLayers 实战|Vue3 + OpenLayers 完整工程案例(加载天地图、要素、弹窗、绘制、WFS)
前端·openlayers
陈随易2 小时前
下载神器!Motrix 停更三年后重写回归
前端·后端·程序员
前端的日常2 小时前
一个人+AI做情侣食谱小程序,0 费用的服务器
前端·后端
计算机魔术师3 小时前
谷歌搜索广告踩刹车,AI广告成为救命稻草
前端
总要学点什么3 小时前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
IT_陈寒3 小时前
Vue的v-for里用了个临时变量,页面直接挂了
前端·人工智能·后端
hunter_0763 小时前
一次 iOS 真机签名 409 的完整排查:证书、设备、描述文件为什么总是"对不上"
前端
枣把儿3 小时前
开源!公众号排版+一键发布工具懒人版
前端