vue 实战 tab标签页+el-card+流式布局+异步接口调用

html 复制代码
<template>
  <div>
    <!-- 布局按钮 -->
    <el-button @click="dialogVisible = true">布局配置查看</el-button>

    <!-- 布局配置对话框 -->
    <el-dialog :visible.sync="dialogVisible" title="布局配置查看" width="1200px">
      <!-- 表单 -->
      <el-form :inline="true" :model="filter" class="form-row">
        <!-- 玩家 uid 输入框 -->
        <el-form-item label="玩家 uid">
          <el-input v-model="filter.uid" placeholder="请输入玩家 uid" clearable size="small"></el-input>
        </el-form-item>
        <!-- 游戏类型 id 输入框 -->
        <el-form-item label="游戏类型 id">
          <el-input v-model="filter.gameId" placeholder="请输入游戏类型 id" clearable size="small"></el-input>
        </el-form-item>
        <!-- 时间点选择器 -->
        <el-form-item label="时间点">
          <el-date-picker v-model="filter.timePoint" type="datetime" placeholder="请选择时间点" clearable size="small"></el-date-picker>
        </el-form-item>
        <!-- 搜索和重置按钮 -->
        <el-form-item>
          <el-button type="primary" @click="search" icon="el-icon-search" size="mini">搜索</el-button>
          <el-button @click="reset" icon="el-icon-refresh" size="mini">重置</el-button>
        </el-form-item>
      </el-form>

      <el-tabs v-model="activeTab">
        <!-- 结束面板引流区页面 -->
        <el-tab-pane label="开始面板引流区" name="drainage">
          <el-card class="box-card-area">
            <div class="component-list">
              <el-button
                v-for="(component, index) in drainComponents"
                :key="component.comId"
                class="component-button"
                :style="getButtonStyle(index)"
              >
                <div>{{ component.name }}</div>
                <div class="comId">{{ component.comId }}</div>
              </el-button>
            </div>
          </el-card>
        </el-tab-pane>

        <!-- 结束面板数据区页面 -->
        <el-tab-pane label="开始面板数据区" name="data">
          <el-card class="box-card-area">
            <div class="component-list">
              <el-button
                v-for="(component, index) in dataComponents"
                :key="component.comId"
                class="component-button"
                :style="getButtonStyle(index)"
              >
                <div>{{ component.name }}</div>
                <div class="comId">{{ component.comId }}</div>
              </el-button>
            </div>
          </el-card>
        </el-tab-pane>

        <!-- 直播中默认区域页面 -->
        <el-tab-pane label="生活中默认区域" name="default">
          <el-card class="box-card-area">
            <div class="component-list">
              <el-button
                v-for="(component, index) in liveComponents"
                :key="component.comId"
                class="component-button"
                :style="getButtonStyle(index)"
              >
                <div>{{ component.name }}</div>
                <div class="comId">{{ component.comId }}</div>
              </el-button>
            </div>
          </el-card>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>
</template>

<script>
const generateSoftColor = () => {
  const hue = Math.floor(Math.random() * 360);
  const saturation = 60 + Math.random() * 20; // 饱和度在60%-80%之间
  const lightness = 70 + Math.random() * 20; // 亮度在70%-90%之间
  return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
};

// 通用转换函数
const convertDataList = (dataList) => {
  return dataList.map(item => ({
    comId: item.comId,
    name: item.name,
    weight: item.weight,
    color: generateSoftColor()
  }));
};

const sortedDataList = (dataList) => {
  return dataList.slice().sort((a, b) => b.weight - a.weight);
};

// 数据列表
const dataList1 = [
  { comId: '1000009', name: '对方如果', property: 0, type: 0, weight: 4 },
  { comId: '1000004', name: '辅导费人', property: 0, type: 0, weight: 1 },
  { comId: '1000010', name: '电电风扇', property: 0, type: 0, weight: 2 },
  { comId: '1000006', name: '小组件', property: 0, type: 0, weight: 3 },
  { comId: '1000007', name: '飒飒飒飒', property: 0, type: 0, weight: 5 },
  { comId: '1000011', name: '你说的分手', property: 0, type: 0, weight: 6 },
  { comId: '1000012', name: '大润发儿童', property: 0, type: 0, weight: 9 },
  { comId: '1000013', name: '大方的发过的', property: 0, type: 0, weight: 8 }
];

const dataList2 = [
  { comId: '1000001', name: '哈哈哈', property: 0, type: 1, weight: 2 },
  { comId: '1000005', name: '测试组件名称', property: 0, type: 1, weight: 2 },
  { comId: '1000002', name: '啦啦啦', property: 1, type: 0, weight: 0 }
];

const dataList3 = [
  { comId: '1000017', name: 'GV地方大幅度', property: 0, type: 0, weight: 3 },
  { comId: '1000016', name: '奋斗奋斗发的', property: 0, type: 0, weight: 2 },
  { comId: '1000008', name: '大幅度发', property: 0, type: 0, weight: 1 },
  { comId: '1000003', name: '似懂非懂发', property: 1, type: 1, weight: 0 },
  { comId: '1000014', name: '个人发一个发帖人', property: 0, type: 0, weight: 0 },
  { comId: '1000015', name: '会更好多说点', property: 0, type: 0, weight: 0 }
];

export default {
  data() {
    return {
      dialogVisible: false,
      activeTab: "drainage",
      filter: {
        uid: '',
        gameId: '',
        timePoint: ''
      },
      drainComponents: convertDataList(sortedDataList(dataList1)),
      dataComponents: convertDataList(sortedDataList(dataList2)),
      liveComponents: convertDataList(sortedDataList(dataList3))
    };
  },
  methods: {
    getButtonStyle(index) {
      return {
        backgroundColor: this.drainComponents[index]?.color,
        paddingLeft: '5px',
        paddingRight: '5px',
        marginLeft: (index === 0) ? '10px' : '',
      };
    },
    async search() {
      /* eslint-disable */
      const { uid, gameId, timePoint } = this.filter;
      // 使用搜索条件调用获取组件数据的方法
      this.drainComponents = await this.getComponents(uid, gameId, '');
      this.dataComponents = await this.getComponents(uid, gameId, '');
      this.liveComponents = await this.getComponents(uid, gameId, '');
    },
    reset() {
      this.filter = {
        uid: '',
        gameId: '',
        timePoint: ''
      };
      // 重置后的操作
    },
    async getComponents(uid, gameId, area) {
      let componentsData = [];
      try {
        const response = await getComConfListItems({
          'uid': uid,
          'clientType': 1,
          'clientVerNum': '',
          'templateType': 0,
          'gameId': gameId,
          'area': area
        });
        console.log('快捷布局配置 getComConfListItems response.data: ', response.data);
        componentsData = convertDataList(response.data);
      } catch (error) {
        console.error('Error fetching components:', error);
      }
      return componentsData;
    }
  },
};
</script>

<style scoped>
/* 表单行样式 */
.form-row {
  margin-bottom: 20px;
}

/* 流式布局样式 */
.component-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.component-button {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.comId {
  font-size: 12px;
  color: gray;
}

/* 设置 el-card__body 的 padding */
::v-deep .box-card-area .el-card__body {
  padding-top: 10px !important;
  padding-bottom: 10px !important;
  padding-right: 0px !important;
  padding-left: 0px !important;
}
</style>
相关推荐
十一吖i3 分钟前
前端将后端返回的文件下载到本地
vue.js·elementplus
光影少年4 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
Rattenking9 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
熊的猫1 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
mosen8682 小时前
Uniapp去除顶部导航栏-小程序、H5、APP适用
vue.js·微信小程序·小程序·uni-app·uniapp
别拿曾经看以后~3 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
川石课堂软件测试3 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
JerryXZR3 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
problc3 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
Gavin_9154 小时前
【JavaScript】模块化开发
前端·javascript·vue.js