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

介绍

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

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

相关推荐
IT_陈寒9 分钟前
React 性能优化:5个实战技巧让首屏加载提升50%,开发者亲测有效!
前端·人工智能·后端
rising start26 分钟前
前端基础一、HTML5
前端·html·html5
Never_Satisfied34 分钟前
在JavaScript / HTML中,div容器在内容过多时不显示超出的部分
开发语言·javascript·html
鬼谷中妖35 分钟前
JavaScript 循环与对象:深入理解 for、for...in、for...of、不可枚举属性与可迭代对象
前端
大厂码农老A40 分钟前
你打的日志,正在拖垮你的系统:从P4小白到P7专家都是怎么打日志的?
java·前端·后端
im_AMBER41 分钟前
CSS 01【基础语法学习】
前端·css·笔记·学习
DokiDoki之父1 小时前
前端速通—CSS篇
前端·css
pixle01 小时前
Web大屏适配终极方案:vw/vh + flex + clamp() 完美组合
前端·大屏适配·vw/vh·clamp·终极方案·web大屏
ssf19871 小时前
前后端分离项目前端页面开发远程调试代理解决跨域问题方法
前端
@PHARAOH1 小时前
WHAT - 前端性能指标(加载性能指标)
前端