有一个需求,需要我们渲染一个未知层级关系的cascader级联选择器。这样在template模版当中是无法写死v-for嵌套的,因为数据是活的,可能三个嵌套子集,也有可能有四个。下面是element-ui当中的例子:


 那么我们如何解决这个需求呢?

用递归组件。

html:

<cascader :source="source">联级选择框</cascader>

数据结构:

data: {
        source: [
            {
                name: '浙江',
                children: [
                    {
                        name: '杭州',
                        children: [
                            {name: 'shang'},
                            {name: 'xia'},
                            {name: 'jianggan'}
                        ]
                    },
                    {
                        name: '嘉兴',
                        children: [
                            {name: 'shang'},
                            {name: 'xia'},
                            {name: 'jianggan'}
                        ]
                    }
                ]
            },
            {
                name: '湖南',
                children: [
                    {
                        name: '长沙',
                        children: [
                            {name: 'shang'},
                            {name: 'xia'},
                            {name: 'jianggan'}
                        ]
                    },
                    {
                        name: '湘潭',
                        children: [
                            {name: 'shang'},
                            {name: 'xia'},
                            {name: 'jianggan'}
                        ]
                    }
                ]
            },
        ]
    },

 cascader组件内部:也就是将外部得到的全部数据统一传到cascader组件中处理。

<template>
    <div class="cascader-content">
        <div class="trigger">
            <slot></slot>
        </div>
        <div class="popover">
<!--        递归组件-->
            <cascader-item v-for="(item, index) in source" :key="index" :sourceItem="item"></cascader-item>
        </div>
    </div>
</template>

<script>
    import cascaderItem from './cascader-item'

    export default {
        name: 'cascader',
        components: {cascaderItem},
        props: {
            source: {
                type: Array
            }
        },
    }
</script>

cascader-item组件内部:这个组件进行递归调用。

<template>
    <div class="cascader-item-content">
        {{sourceItem.name}}
        <cascader-item
            v-if="sourceItem.children"
            v-for="item in sourceItem.children"
            :sourceItem="item">
        </cascader-item>
    </div>
</template>

<script>
    export default {
        name: 'cascaderItem',
        props: {
            sourceItem: {
                type: Object
            }
        },
    }
</script>

在vue只需要声明组件的name,即可在template模版中使用当前组件name作为组件标签进行自身调用,这样就能满足无需提前知道有几层嵌套,通过递归v-for都能遍历出来,这就是递归组件调用大致雏形,样式功能可以根据需求继续完善。递归组件特别适合用于cascader级联选择器、tree树等功能。

最后在页面中渲染出如下结果:

Logo

前往低代码交流专区

更多推荐