• 基于Vue element-ui实现支持多级纵向动态表头的仿表格布局


    [本文出自天外归云的博客园]

    需求图示如下,多级纵向动态表头表格:

    我的思路是用element-ui的layout实现,做出一个仿造表格,能够支持动态的、多级的、纵向的表头:

    <template>
      <div>
        <!--按设备系统统计-->
        <div style="text-align:left">
          <h1>{{tableName}}</h1>
        </div>
        <!--纵向表格设计-->
        <el-row>
          <!--纵向表头设计-->
          <el-col :span="6">
            <el-row>
              <div :style="projectDivStyle">
                <p>项目名</p>
              </div>
            </el-row>
            <el-row v-if="ifAndroid">
              <el-col :span="12">
                <div :style="wordOfMouthAndroidDivStyle">
                  <p>Android口碑指数</p>
                </div>
              </el-col>
              <el-col :span="12">
                <el-row v-for="(chl, i) in tableData.ratingChls"
                        :key="i">
                  <div :style="ratingSubDivStyle">
                    <p>{{chl}}</p>
                  </div>
                </el-row>
              </el-col>
            </el-row>
            <el-row v-else>
              <div :style="wordOfMouthIOSDivStyle">
                <p>AppStore口碑指数</p>
              </div>
            </el-row>
            <el-row>
              <el-col :span="12">
                <div :style="ratingDivStyle">
                  <p>评分</p>
                </div>
              </el-col>
              <el-col :span="12">
                <el-row v-for="(chl, i) in tableData.ratingChls"
                        :key="i">
                  <div :style="ratingSubDivStyle">
                    <p>{{chl}}</p>
                  </div>
                </el-row>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <div :style="rankDivStyle">
                  <p>排名</p>
                </div>
              </el-col>
              <el-col :span="12">
                <el-row v-for="(chl,i) in tableData.rankChls"
                        :key="i">
                  <div :style="rankSubDivStyle">
                    <p>{{chl}}</p>
                  </div>
                </el-row>
              </el-col>
            </el-row>
            <el-row>
              <div :style="topModuleDivStyle">
                <p>TOP3好评关键词</p>
              </div>
            </el-row>
            <el-row>
              <div :style="topModuleDivStyle">
                <p>TOP3差评关键词</p>
              </div>
            </el-row>
          </el-col>
          <!--纵列数据遍历-->
          <el-col :span="colSpan"
                  v-for="(col,i) in tableData.cols"
                  :key="i">
            <!--项目名数据-->
            <el-row>
              <div :style="projectDivStyle">
                <p>{{col.name}}</p>
              </div>
            </el-row>
            <!--口碑数据 区分Android和iOS视图显示逻辑-->
            <el-row v-if="ifAndroid">
              <el-col :span="24">
                <el-row v-for="(each, i) in col.wordOfMouth"
                        :key="i">
                  <div :style="ratingSubDivStyle">
                    <p>
                      {{each}}
                    </p>
                  </div>
                </el-row>
              </el-col>
            </el-row>
            <el-row v-else>
              <div :style="wordOfMouthIOSDivStyle">
                <p>{{col.wordOfMouth[0]}}</p>
              </div>
            </el-row>
            <!--评分数据-->
            <el-row>
              <el-col :span="24">
                <el-row v-for="(each, i) in col.ratingInfo"
                        :key="i">
                  <div :style="ratingSubDivStyle">
                    <p>
                      {{each.info}}
                    </p>
                    <el-rate :value='Number(each.rating)'
                             disabled
                             show-score
                             text-color="#ff9900"
                             score-template="{value}">
                    </el-rate>
                  </div>
                </el-row>
              </el-col>
            </el-row>
            <!--排名数据-->
            <el-row>
              <el-col :span="24">
                <el-row v-for="(each,i) in col.rankInfo"
                        :key="i">
                  <div :style="rankSubDivStyle">
                    <p>{{each.rank}} {{each.info}}</p>
                  </div>
                </el-row>
              </el-col>
            </el-row>
            <el-row>
              <div :style="topModuleDivStyle">
                <p v-for="(_module,i) in modules(col.topGoodModule)"
                   :key="i">
                  {{_module}}
                </p>
              </div>
            </el-row>
            <el-row>
              <div :style="topModuleDivStyle">
                <p v-for="(_module,i) in modules(col.topBadModule)"
                   :key="i">
                  {{_module}}
                </p>
              </div>
            </el-row>
          </el-col>
        </el-row>
      </div>
    </template>
    <style scoped>
    /*
    通过布局el-row来完成表格边界样式替代式设计
    */
    .el-row {
      margin-bottom: 0px; /*去除el-row之间的间距*/
      border: 1px solid #e6e6e6;
      margin: -1px -1px -1px -1px; /*解决相邻边框重叠问题就靠这行代码*/
      &:last-child {
        margin-bottom: 0px;
      }
    }
    .bg-purple {
    }
    .bg-purple-light {
      background: #121927;
    }
    .grid-content {
      border: 0px solid rgb(0, 0, 0);
      min-height: 50px;
    }
    .grid-content-sub {
      border: 0px solid rgb(0, 0, 0);
      padding: 20px;
    }
    .grid-content-large {
      border: 0px solid rgb(0, 0, 0);
      padding: 70px;
      height: 60px;
    }
    .grid-content-large-sub {
      border: 0px solid rgb(0, 0, 0);
      padding: 20px;
      height: 57.5px;
    }
    </style>
    <script>
    import { getFeedbackCompetitorData } from '@/api/feedbacks'
    import { EventBus } from '@/bus.js'
    export default {
      data () {
        return {
          myProjectId: this.$route.query.feedbackProject,
          largeDivHeight: 120,
          smallDivHeight: 80,
          miniDivHeight: 50,
          ratingSubDivHeight: 80,
          rankSubDivHeight: 80,
          tableName: '',
          tableData: [],
          shadowCss: 'border-radius: 15px;box-shadow: 5px 5px 2px #888888',
          borderStyle: ''
        }
      },
      methods: {
        getFbCompetitorData () {
          getFeedbackCompetitorData(this.myProjectId).then(fbCpInfo => {
            this.tableName = fbCpInfo.competitorTable.tableName
            this.tableData = fbCpInfo.competitorTable.tableData
          })
        },
        modules (someArray) {
          var newArray = []
          for (var i = 0; i < someArray.length; i++) {
            var count = someArray[i]['cou']
            var word = someArray[i]['word']
            newArray.push(word + ':' + count)
          }
          return newArray
        }
      },
      computed: {
        ifAndroid: function () {
          if (this.tableData.wordOfMouthChls[0] === 'AppStore') {
            return false
          } else {
            return true
          }
        },
        colSpan: function () {
          var count = this.tableData.cols.length
          if (count > 5) {
            return 18 / count
          } else if (count < 4) {
            return 6
          }
        },
        commonDivStyle: function () {
          var height = this.smallDivHeight
          return `padding: 20px;height: ${height}px`
        },
        projectDivStyle: function () {
          var height = this.miniDivHeight
          return `background: #E8F8F5;padding: 20px;height: ${height}px`
        },
        wordOfMouthAndroidDivStyle: function () {
          var height = this.miniDivHeight
          return `margin-top:50%;padding: 20px;height: ${height}px`
        },
        wordOfMouthIOSDivStyle: function () {
          var height = this.miniDivHeight
          return `padding: 20px;height: ${height}px`
        },
        topModuleDivStyle: function () {
          var height = this.largeDivHeight
          return `padding: 20px;height: ${height}px`
        },
        ratingDivStyle: function () {
          var height = this.ratingSubDivHeight
          // 区分Android和iOS样式
          if (this.ifAndroid) {
            var margin = 'margin-top:50%'
          }
          return `${margin};padding: 20px;height: ${height}px`
        },
        ratingSubDivStyle: function () {
          var height = this.ratingSubDivHeight
          return `padding: 20px;height: ${height}px`
        },
        rankDivStyle: function () {
          var height = this.rankSubDivHeight
          return `margin-top:30%;padding: 20px;height: ${height}px`
        },
        rankSubDivStyle: function () {
          var height = this.rankSubDivHeight
          return `padding: 20px;height: ${height}px`
        }
      },
      created () {
        let _this = this
        EventBus.$on('projectId', projectId => {
          _this.myProjectId = projectId
        })
      },
      mounted () {
        this.getFbCompetitorData()
      },
      watch: {
        myProjectId: {
          immediate: false,
          handler: function (val) {
            this.getFbCompetitorData()
          }
        }
      }
    }
    </script>

    实现图如下:

  • 相关阅读:
    Blender文档翻译-Blender库数据的通用属性
    Blender文档翻译-什么是Ghash?
    PythonQt
    QT与Python混合编程经验记录
    WebStorm开发ReactNative过程中导入插件设置智能提示
    原生iOS项目导入ReactNative,各种问题
    关于网易七鱼iOS 端集成
    iOS "_OBJC_CLASS_$_JPUSHService", referenced from: 解决办法
    同时安装使用 两个Xcode切换的一些问题。
    实现一个iOS项目中添加多个target,并制作马甲包。
  • 原文地址:https://www.cnblogs.com/LanTianYou/p/10622710.html
Copyright © 2020-2023  润新知