如果你平时老是需要编写各种列表,例如商品列表、图片列表,不妨自己写一个通用的列表组件,只需要传入几个参数,就能帮我们自动分列、自动调整间距。下面就是一个实现起来非常简单,但真的很好用的自定义列表组件。

定义

直接上完整的代码:

<script setup>
const props = defineProps({
    data: {
        type: Array,
        default: []
    },
    columnCount: {
        type: Number,
        default: 2
    },
    gap: {
        type: Number,
        default: 10
    }
});

const emit = defineEmits(['select']);
</script>

<template>
    <div class="list" :style="{ gap: `${gap}px` }">
        <template v-for="i in data">
            <div class="item" :style="{ 'flex-basis': `calc((100% - ${columnCount - 1} * ${gap}px) / ${columnCount})` }" @click="emit('select', i)">
                <slot :row="i"></slot>
            </div>
        </template>
    </div>
</template>

<style lang="scss" scoped>
.list {
    display: flex;
    flex-wrap: wrap;

    >.item {
        flex-shrink: 0;
        flex-grow: 0;
        cursor: pointer;
    }
}
</style>

在 script 部分,这个组件定义了 3 个属性,data是需要传入的数组形式的数据,就像 el-table 的 data 属性。columnCount是列数,可以是任意整数列,默认值为 2,这也是最常用的列数。gap是每一项与其他项的边距。如果你需要实现其他特定,可以非常容易地自己增加其他参数。

模板部分,列表使用了 flex 布局,根据参数自动计算每一列的宽度。还提供了一个默认插槽,用来自定义每一项里面的内容。

使用

使用起来非常简单,假设我们将上面的代码保存到一个叫 CommonMultiColumnList.vue 的文件中,首先引入这个组件:

import CommonMultiColumnList from 'CommonMultiColumnList.vue';

然后在模板中使用:

<CommonMultiColumnList :data="someData" :column-count="1" :gap="15">
    <template #default="{row}">
        <!-- 这里是自定义的每一项的结构 -->
    </template>
</CommonMultiColumnList>

现在只需要编写每一项的结构和样式,列表就会展示出来了。
如果你希望更加方便,也可以在组件中写好每一项的样式,而不是提供插槽,并多建立几个每一项样式不同的组件。


End

标签: vue3, element-plus, 自定义组件