flex布局,一行显示4个,多出来的自动换行

css 复制代码
.m-carousel-wrap :deep(.el-carousel__indicator.is-active .el-carousel__button){background-color: #3081F2;}
.m-carousel-wrap :deep(.el-carousel__indicator .el-carousel__button){background-color: #666;}
.m-box-wrap{display: flex;  flex-wrap: wrap;padding: 5px 10px;}
.m-box-item{ flex: 0 0 25%;}
.m-box-item-inner{position: relative; display: flex;flex-direction: column;align-items: center;  margin: 5px;background: #f1f9ff;;border-radius: 8px;padding: 14px 10px;cursor: pointer;}
.m-box-number{position: absolute;top: 10px; right: 0;background-color: #fcd678;text-align: right;min-width: 15px;padding: 0 5px;}
.m-img-report{width: 48px;height: 48px;background: url(../../../../../../assets/images/common/m-oil.png);background-size: 100% 100%;}
.m-img-menu{height: 48px;}

.m-box-name{margin: 7px 0 0 0; font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 12px;color: #333;}
.m-search-input{margin: 0 0 0 5px;width: 200px;}
javascript 复制代码
<template>
  <div>
    <div class="m-box-title">
      <div class="m-box-title-divide"></div>
      <div class="m-box-title-info">常用功能
        <el-input v-model="searchValue" class="m-search-input" placeholder="请输入" :suffix-icon="Search" />
      </div>
      <div class="m-box-title-tabs-wrap">
        <el-tabs v-model="activeIndex" @tab-change="handleActiveIndexChange">
          <el-tab-pane label="常用报表" name="1"></el-tab-pane>
          <el-tab-pane label="常用菜单" name="2"></el-tab-pane>
          <el-tab-pane label="常用系统" name="3"></el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <div class="m-carousel-wrap">
      <div v-show="activeIndex === '1'">
        <el-carousel height="360px" :autoplay="false">
          <el-carousel-item v-for="listItem in list" :key="listItem.id">
            <div class="m-box-wrap">
              <div v-for="item in listItem.children" :key="item.id" class="m-box-item">
                <div class="m-box-item-inner">
                  <div class="m-img-report"></div>
                  <div class="m-box-name">{{ item.name }}</div>
                </div>
              </div>
            </div>
          </el-carousel-item>
        </el-carousel>
      </div>
      <div v-show="activeIndex === '2'">
        <el-carousel height="360px" :autoplay="false">
          <el-carousel-item v-for="listItem in list" :key="listItem.id">
            <div class="m-box-wrap">
              <div v-for="item in listItem.children" :key="item.id" class="m-box-item"
                @click="() => handleMenuClick(item)">
                <div class="m-box-item-inner">
                  <div class="m-img-menu">
                    <el-icon :size="30">
                      <SetUp />
                    </el-icon>
                  </div>
                  <div class="m-box-name">{{ item.menuName }}</div>
                </div>
              </div>
            </div>
          </el-carousel-item>
        </el-carousel>
      </div>
      <div v-show="activeIndex === '3'">
        <el-carousel height="360px" :autoplay="false">
          <el-carousel-item v-for="listItem in list" :key="listItem.id">
            <div class="m-box-wrap">
              <div v-for="item in listItem.children" :key="item.id" class="m-box-item">
                <div class="m-box-item-inner">
                  <div class="m-img-menu">
                    <el-icon :size="30">
                      <Tickets />
                    </el-icon>
                  </div>
                  <div class="m-box-name">{{ item.name }}</div>
                </div>
              </div>
            </div>
          </el-carousel-item>
        </el-carousel>
      </div>
    </div>

  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { isDev, handleSendMsg } from '@/utils/tools'
import { handleGetList } from './config'
import { Search } from '@element-plus/icons-vue'
import { userFavoritesQueryByUser } from '@/api/modules/complex'

//#region 配置
const router = useRouter();
const list: any = ref([])
const activeIndex: any = ref("1");
const searchValue = ref("");

//#endregion

//#region 事件
function chunkArray(arr: any, chunkSize: any) {
  let chunks: any = [];
  for (let i = 0; i < arr.length; i += chunkSize) {
    chunks.push({ id: i, children: arr.slice(i, i + chunkSize) });
  }
  return chunks;
}
const handleActiveIndexChange = async () => {
  console.log("activeIndex", activeIndex.value);
  if (activeIndex.value === '1') {
    list.value = handleGetList(activeIndex.value)
  } else if (activeIndex.value === '2') {
    let res = await userFavoritesQueryByUser({})
    let result = res.data
    result = chunkArray(result, 12);

    list.value = result
  } else if (activeIndex.value === '3') {
    list.value = handleGetList(activeIndex.value)
  }
};

const handleMenuClick = (item: any) => {
  console.log(item.url)

  let urlArr = item.url.split('/')
  urlArr = urlArr.slice(2)
  let url = '/' + urlArr.join('/')
  console.log(urlArr, url)
  if (isDev() && false) {
    router.push(url);
  } else {
    handleSendMsg("router", {
      path: url
    });
  }
};


//#endregion

//#region 生命周期
const handleInit = async () => {
  list.value = handleGetList('1')

}
onMounted(() => {
  handleInit()
})
//#endregion
</script>

<style scoped lang="scss">
@import "../../index.scss";
@import "./index.scss";
</style>