table

95 阅读1分钟

Cateegory.vue

<template>
  <div class="category">
    <s-filter @itemClick="itemClick" :filterData="resultData"></s-filter>
    <s-table :tableData="tableData"></s-table>
    <s-waterfall></s-waterfall>
  </div>
</template>
<script>
import SFilter from './filter.vue';
import STable from './table.vue';
import SWaterfall from './waterfall.vue';
export default {
  data() {
    return {
      tableData: [],
      resultData: {
        '上海': {
          2017: {
            '不限': [
              {
                a: '本科',
                admission: "综合",
                lowScore: 548,
                majorGroupName: "专业组"
              }
            ]
          }
        },
        '北京': {
          2021: {
            '文综': [
              {
                a: '本科',
                admission: "综合111",
                lowScore: 5222,
                majorGroupName: "专业组"
              }
            ]
          }
        }
      },
      OneData: []
    }
  },
  mounted() {
    // this.tableData = this.OneData
    console.log(Object.keys(this.resultData), '111');
    console.log(Object.values(this.resultData)[0], '22');
    this.tableData = Object.values(Object.values(Object.values(this.resultData)[0])[0])[0]
  console.log(this.tableData)
  },
  components: {
    SFilter,
    STable,
    SWaterfall
  },
  methods: {
    itemClick(name, year, subject) {
      console.log(name, year, subject)
      this.tableData = this.resultData[name][year][subject];
    }
  }
}
</script>

filter.vue

<template>
  <div>
    <ul class="filter-wrapper">
      <li @click="nameClick">{{ name }}</li>
      <li @click="yearClick">{{ year }}</li>
      <li @click="subjectClick">{{ subject }}</li>
    </ul>
<!--    <s-van-popup v-model="showDialog" :objArr="filterData"></s-van-popup>-->
    <div v-show="isShow" style="width: 200px; height: 200px; border: 1px solid red;">
      <ul>
        <li @click="itemClick(index)" v-for="(item, index) in filterData">{{index}}</li>
      </ul>
    </div>
  </div>
</template>
<script>
import SVanPopup from './vanPopup.vue';
export default {
  data() {
    return {
      name: '',
      year: '',
      subject: '',
      showDialog: false,
      showDialog1: false,
      isShow: false,
      tag: 0
    }
  },
  props: ["filterData"],
  components: {
    SVanPopup
  },
  mounted() {

  },
  methods: {
    nameClick() {
      this.isShow = true;
      this.tag = 0;
    },
    yearClick() {
      this.isShow = true;
      this.tag = 1;
    },
    subjectClick() {
      this.isShow = true;
      this.tag = 2;
    },
    itemClick(i) {
      switch(this.tag){
        case 0:
          this.name = i;
          this.year = Object.keys(this.filterData[i])[0]
          this.subject = Object.keys(this.filterData[i][this.year])[0]
          break;
        case 1:
          this.year = i;
          this.subject = Object.keys(this.filterData[this.name][this.year])[0]
          break;
        case 2:
          this.subject = i;
          break
      }
      this.$emit("itemClick", this.name, this.year, this.subject)
    }
  }
}
</script>
<style scoped>
.filter-wrapper li {
  display: inline-block;
  width: 100px;
  height: 40px;
  border: 1px solid red;
}
</style>

table.vue

<template>
  <div class="table_wrap" ref="trRef">
    <div ref="shadowRef" class="shadow" :style="{height: shadowHeight}" v-if="isShadowShow"></div>
    <table ref="tableRef">
      <thead>
      <tr>
        <th>序号</th>
        <th>栏目1</th>
        <th>栏目2</th>
        <th>栏目3</th>
        <th>栏目4</th>
        <th>栏目2</th>
        <th>栏目3</th>
        <th>栏目4</th>
      </tr>
      </thead>
      <tbody>
         <tr v-for="(item, index) in tableData">
           <td v-for="(ite, ind) in keyIndex">{{item[ite]}}</td>
         </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
export default {
  data() {
    return {
      keyIndex: ["a", "lowScore", "admission", "majorGroupName"],
      isShadowShow: false,
      shadowHeight: 0
    }
  },
  props: ["tableData"],
  mounted() {
    this.shadowHeight = this.$refs.tableRef.offsetHeight + 'px';
    console.log(this.shadowHeight, 'this.shadowHeight~~')
    this.$refs.trRef.addEventListener("scroll", ev => {
      console.log(ev.target.scrollLeft)
      if (ev.target.scrollLeft > 0) {
        this.isShadowShow = true;
      } else {
        this.isShadowShow = false;
      }
    })
  }
}
</script>
<style scoped>
.table_wrap {
  margin: 30px;
  width: 100%;
  height: 100px;
  overflow: auto;
  border-bottom:1px solid #61dafb;
}
.shadow {
  position: absolute;
  left: 127px;
  width: 10px;
  background: linear-gradient(to left,#d3959b,#bfe6ba);
  z-index: 200;
}

table {
  table-layout: fixed;
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid #DDDDDD;
}

/* 表格th/td样式 */
td,th {
  width: 150px;
  box-sizing: border-box;
  border-right: 1px solid #DDDDDD;
  border-bottom: 1px solid #DDDDDD;
  /*单元格 超出长度 显示...*/
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  height: 30px;

}

/* 表头固定 */
thead tr th {
  position: sticky;
  top: 0;
  background: #F4F4F5;
  height: 30px;
}

/* 首列固定/最后一列固定*/
th:first-child,
td:first-child {
  position: sticky;
  left: 0;
  background: #F4F4F5;
  text-align: center;
  right: 0px;
  border-left: 1px solid #DDDDDD ;
  width: 100px;
}

/* 表头首列和最后一列强制最顶层 */
th:first-child {
  z-index: 3;
  /*左上角单元格z-index,切记要设置,不然表格纵向横向滚动时会被该单元格右方或者下方的单元格遮挡*/
  background: #F4F4F5;
}
</style>

vanPop.vue

<template>
  <div>
    111
    <van-popup
      @input="val => this.$emit('input', val)"
      position="bottom" :style="{ height: '30%' }" >
      <div class="title" v-for="(item, index) in objArr">{{ index }}</div>
    </van-popup>
  </div>
</template>
<script>
export default {
  data() {
    return {
      show: false,
    }
  },
  props: ["title", "objArr", 'value'],
  mounted() {
    console.log(this.objArr, 'objArr~~~');
  }
}
</script>

<style scoped></style>


waterfall.vue

<template>
  <div class="waterfall">
    <h2>瀑布流布局</h2>
    <div class="v-waterfall-content" id="v-waterfall">
      <div
        v-for="(img, index) in waterfallList"
        :key="index"
        class="v-waterfall-item"
        :style="{
          top: img.top + 'px',
          left: img.left + 'px',
          width: waterfallImgWidth + 'px',
          height: img.height,
        }"
      >
        <img :src="img.src" alt="" />
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
/* eslint-disable */
export default {
  name: "v-waterfall",
  data () {
    return {
      waterfallList: [],
      imgArr: [
        require('./assets/img/err.jpg'),
        require('./assets/img/1.jpg'),
        require('./assets/img/2.jpg'),
        require('./assets/img/3.jpg'),
        require('./assets/img/4.jpg'),
        require('./assets/img/5.jpg'),
        require('./assets/img/6.jpg'),
        require('./assets/img/7.jpg'),
        require('./assets/img/8.jpg'),
        require('./assets/img/9.jpg'),
        require('./assets/img/10.jpg'),
        require('./assets/img/11.jpg'),
        require('./assets/img/12.jpg')
      ],
      // waterfallImgWidth: 100,
      waterfallImgWidth: 180,// 每个盒子的宽度
      waterfallImgCol: 2,// 瀑布流的列数
      // waterfallImgCol: 3,// 瀑布流的列数
      waterfallImgRight: 10,// 每个盒子的右padding
      waterfallImgBottom: 10,// 每个盒子的下padding
      waterfallDeviationHeight: [],
      imgList: []
    }
  },
  created () {
    axios.get('/data.json', {

    })
      .then(function (res) {
        this.imgArr = res
      })
      .catch(function (error) {
      })
    // 触发入口
    for (let i = 0; i < this.imgArr.length; i++) {
      // this.imgList.push(this.imgArr[Math.round(Math.random() * 8)]);// 图片随机显示
      this.imgList.push(this.imgArr[i]);
    }
  },
  mounted () {
    this.calculationWidth();
  },
  methods: {
    //计算每个图片的宽度或者是列数
    calculationWidth () {
      let domWidth = document.getElementById("v-waterfall").offsetWidth;
      if (!this.waterfallImgWidth && this.waterfallImgCol) {
        this.waterfallImgWidth = (domWidth - this.waterfallImgRight * this.waterfallImgCol) / this.waterfallImgCol;
      } else if (this.waterfallImgWidth && !this.waterfallImgCol) {
        this.waterfallImgCol = Math.floor(domWidth / (this.waterfallImgWidth + this.waterfallImgRight))
      }
      //初始化偏移高度数组
      this.waterfallDeviationHeight = new Array(this.waterfallImgCol);
      for (let i = 0; i < this.waterfallDeviationHeight.length; i++) {
        this.waterfallDeviationHeight[i] = 0;
      }
      this.imgPreloading()
    },
    //图片预加载
    imgPreloading () {
      for (let i = 0; i < this.imgList.length; i++) {
        let aImg = new Image();
        aImg.src = this.imgList[i];
        aImg.onload = aImg.onerror = (e) => {
          let imgData = {};
          imgData.height = this.waterfallImgWidth / aImg.width * aImg.height;
          imgData.src = this.imgList[i];
          // imgData.title = '标题';// 说明文字(也可以自己写数组,或者封装json数据,都可以,但是前提是你会相关操作,这里不赘述)
          // imgData.info = '详情说明:啦啦啦啦啦';// 说明文字
          this.waterfallList.push(imgData);
          this.rankImg(imgData);
        }
      }

    },
    //瀑布流布局
    rankImg (imgData) {
      let {
        waterfallImgWidth,
        waterfallImgRight,
        waterfallImgBottom,
        waterfallDeviationHeight,
        waterfallImgCol
      } = this;
      let minIndex = this.filterMin();
      imgData.top = waterfallDeviationHeight[minIndex];
      imgData.left = minIndex * (waterfallImgRight + waterfallImgWidth);
      // waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;// 不加文字的盒子高度
      waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;// 加了文字的盒子高度,留出文字的地方(这里设置56px)
      console.log(this.waterfallList);
    },
    /**
     * 找到最短的列并返回下标
     * @returns {number} 下标
     */
    filterMin () {
      const min = Math.min.apply(null, this.waterfallDeviationHeight);
      return this.waterfallDeviationHeight.indexOf(min);
    }
  }
}
</script>

<style scoped>
.waterfall {
  width: 100%;
  padding: 0 10px;
  margin: 0 auto;
  background: #000;
}
.v-waterfall-content {
  /* 主要 */
  width: 100%;
  /* height: 100vh; */
  position: relative;
  /* 次要:设置滚动条,要求固定高度 */
}

.v-waterfall-item {
  /* 主要 */
  float: left;
  position: absolute;
}

.v-waterfall-item img {
  /* 主要 */
  /* width: auto;height: auto; */
  width: 100%;
  height: auto;
  /* 次要 */
  border-radius: 6px;
}
</style>