<template> <div class="sr-list"> <div class="sr-col" v-for="(col, index) in colsList" :key="index" :style="`width:${100/cols}%`"> <template v-if="col.length"> <ArticleItem v-for="(item, index) in col" :key="item.articleId" class="sr-item" :data="item" :index="index" @click="onClick" :tab="tab"></ArticleItem> </template> <ArticleItem class="sr-temp" :temporary="true" :index="0" :tab="tab"></ArticleItem> </div> </div> </template> <script> import ArticleItem from './author-article-item'; import {assign, get, forEach} from 'lodash'; import {getArticleImageSize} from 'utils/image-handler'; import YAS from 'utils/yas-constants'; export default { data() { return { colsList: [], loadedIndex: 0, colsHeight: [] }; }, props: { list: { type: Array, default: [] }, cols: { type: Number, default: 2 }, params: Object, tab: Number }, created() { this.reset(); }, mounted() { this.$cols = this.$el.getElementsByClassName('sr-col'); this.getCoverImgWidth(); }, watch: { list(newList, oldList) { if (oldList.length > newList.length || get(oldList, '[0]._type') !== get(newList, '[0]._type')) { this.reset(); } this.$nextTick(() => { this.calcListLayout(); }); } }, methods: { getCoverImgWidth() { let imgWidth = this.$el.offsetWidth / this.cols; let $item = this.$el.getElementsByClassName('sr-temp'); if ($item && $item.length) { let _w = $item[0].offsetWidth; let $img = $item[0].children; (_w > 0) && (imgWidth = _w); if ($img && $img.length) { _w = $img[0].offsetWidth; (_w > 0) && (imgWidth = _w); } } this.imgBlockWidth = imgWidth; }, calcListLayout(single) { this.loadedIndex = this.loadedIndex || 0; let num = this.list.length - this.loadedIndex; if (num <= 0) { return; } forEach(this.$cols, (col, index) => { this.colsHeight[index] = col.offsetHeight; }); let minHeight = Math.min.apply(null, this.colsHeight); let minIndex = this.colsHeight.indexOf(minHeight); let end = 1; if (!single) { end = Math.max.apply(null, [1, num - Math.floor(this.cols * 2)]); } for (let i = 0; i < end; i++) { let item = this.list[this.loadedIndex + i]; if (item) { let index = (minIndex + i) % this.cols; this.colsList[index] = this.colsList[index] || []; this.colsList[index].push(this.clacCoverSize(item)); } } this.colsList = [...this.colsList]; this.loadedIndex += end; this.$nextTick(() => { this.calcListLayout(true); }); }, clacCoverSize(item) { let {width, height} = getArticleImageSize({ width: item.imageWidth, height: item.imageHeight }); return assign(item, { imageWidth: width, imageHeight: height, scale: height / width, blockWidth: this.imgBlockWidth }); }, reset() { this.loadedIndex = 0; let list = []; for (let i = 0; i < this.cols; i++) { list[i] = []; } this.colsList = list; }, onClick({data, type}) { if (type === 'author') { this.toAuthor(data); } else { this.toArticle(data); } }, toAuthor({authorUid, authorType}) { if (get(this.params, 'params.authorUid') === authorUid) { return; } this.$router.push({ name: 'author', params: { id: authorUid, type: authorType } }); }, toArticle({articleId, sort}) { this.$router.push({ name: 'article', params: { id: articleId }, query: { report_yas: YAS.eventName.detailShow, report_param: { ART_ID: articleId, ATR_TYPE: sort === 2 ? 1 : 2 } } }); } }, components: { ArticleItem } }; </script> <style lang="css"> .sr-list { padding: 5px; display: flex; align-items: flex-start; .sr-col { flex-grow: 1; position: relative; } } </style>