123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- <template>
- <view class="waterfall">
- <view class="left" v-if="leftList[0]">
- <view v-for="(item, index) in leftList" :key="index" @click="emits('click',item)">
- <u-transition :show="true" mode="fade-left" :duration="transitionIndex">
- <view class="waterfall-item" :style="{backgroundColor: bgColor}">
- <view class="tags">{{item.city}}</view>
- <image :src="item.cover" mode="widthFix" lazy-load @load="onImageLoad">
- </image>
- <view class="mt20 column">
- <view class="align-center" v-if="item.user">
- <u-avatar :src="item.user.head_img" size="48rpx"></u-avatar>
- <text class="ellipsis ml10 fs28 bold">{{item.user.nickname}}</text>
- </view>
- <view class="column mt10">
- <text class="bold mb10 ellipsis">{{item.title}}</text>
- <text class="base-color-gray ellipsis lines-2">{{item.content}}</text>
- </view>
- <view class="align-center mt20" @click.stop.prevent>
- <view class="align-center" @click="emits('onLike',item)">
- <u-icon :name="item.is_collent==1?'heart-fill':'heart'"
- :color="item.is_collent==1?'#f44':''"></u-icon>
- <text class="ml10" :style="{color:item.is_collent==1?'#f44':''}">{{item.like_num}}</text>
- </view>
- <view class="align-center ml30">
- <u-icon name="eye"></u-icon>
- <text class="ml10">{{item.browse_num}}</text>
- </view>
- </view>
- </view>
- </view>
- </u-transition>
- </view>
- </view>
- <view class="right" v-if="rightList[0]">
- <view v-for="(item, index) in rightList" :key="index" @click="emits('click',item)">
- <u-transition :show="true" mode="fade-right" :duration="transitionIndex">
- <view class="waterfall-item" :style="{backgroundColor: bgColor}">
- <view class="tags">{{item.city}}</view>
- <image :src="item.cover" mode="widthFix" lazy-load @load="onImageLoad">
- </image>
- <view class="mt20 column">
- <view class="align-center" v-if="item.user">
- <u-avatar :src="item.user.head_img" size="48rpx"></u-avatar>
- <text class="ellipsis ml10 fs28 bold">{{item.user.nickname}}</text>
- </view>
- <view class="column mt10">
- <text class="bold mb10 ellipsis">{{item.title}}</text>
- <text class="base-color-gray ellipsis lines-2">{{item.content}}</text>
- </view>
- <view class="align-center mt20" @click.stop.prevent>
- <view class="align-center" @click="emits('onLike',item)">
- <u-icon :name="item.is_collent==1?'heart-fill':'heart'"
- :color="item.is_collent==1?'#f44':''"></u-icon>
- <text class="ml10" :style="{color:item.is_collent==1?'#f44':''}">{{item.like_num}}</text>
- </view>
- <view class="align-center ml30">
- <u-icon name="eye"></u-icon>
- <text class="ml10">{{item.browse_num}}</text>
- </view>
- </view>
- </view>
- </view>
- </u-transition>
- </view>
- </view>
- </view>
- </template>
- <script setup>
- import {
- watch
- } from 'vue';
- name: 'waterfall-card'
- import {
- onLoad,
- } from "@dcloudio/uni-app";
- import {
- ref
- } from "vue";
- const emits = defineEmits(['click', 'onLike'])
- const props = defineProps({
- list: {
- type: Array,
- default: () => []
- },
- bgColor: {
- type: String,
- default: '#fff'
- }
- })
- const transitionIndex = ref(100) //动画延时
- const leftList = ref([]) //左边列表
- const rightList = ref([]) //右边列表
- const itemIndex = ref(0)
- const leftHeight = ref(0)
- const rightHeight = ref(0)
- //第一张图片入栈
- leftList.value = [props.list[0]];
- watch(() => props.list, (n, o) => {
- // console.log('=====watch list=====', n, o);
- let ol = o.length;
- let nl = n.length;
- // console.log(ol);
- if (nl > ol) {
- if (leftHeight.value > rightHeight.value) {
- rightList.value.push(props.list[ol]);
- } else {
- leftList.value.push(props.list[ol]);
- }
- onImageLoad();
- }
- })
- const onImageLoad = (e) => {
- props.list.forEach((item, index) => {
- let i = index
- transitionIndex.value = (i + 1) * 30
- if (i > 10) i = 0
- })
- if (!e) {
- // console.log('无图片!!!!');
- return;
- }
- let imgH = (e.detail.height / e.detail.width) * 345 + 110 + 20; //图片显示高度加上下面的文字的高度110rpx,加上margin-bottom20rpx
- if (itemIndex.value === 0) {
- leftHeight.value += imgH; //第一张图片高度加到左边
- itemIndex.value++;
- rightList.value.push(props.list[itemIndex.value]); //第二张图片先入栈
- } else {
- itemIndex.value++;
- //再加高度
- if (leftHeight.value > rightHeight.value) {
- rightHeight.value += imgH;
- } else {
- leftHeight.value += imgH;
- }
- if (itemIndex.value < props.list.length) {
- //下一张图片入栈
- if (leftHeight.value > rightHeight.value) {
- rightList.value.push(props.list[itemIndex.value]);
- } else {
- leftList.value.push(props.list[itemIndex.value]);
- }
- }
- }
- }
- </script>
- <style lang="scss">
- .waterfall {
- width: 100%;
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-gap: 20rpx;
- .left,
- .right {
- .waterfall-item {
- width: 100%;
- margin-bottom: 20rpx;
- box-sizing: border-box;
- border-radius: 20rpx;
- overflow: hidden;
- font-size: 24rpx;
- background: #fff;
- padding: 30rpx 25rpx;
- position: relative;
- image {
- width: 100%;
- display: block;
- border-radius: 10rpx;
- }
- .tags {
- position: absolute;
- top: 36rpx;
- right: 37rpx;
- width: 86rpx;
- height: 33rpx;
- line-height: 33rpx;
- color: #fff;
- background: rgba(255, 255, 255, .45);
- z-index: 10;
- border-radius: 20rpx;
- text-align: center;
- font-size: 22rpx
- }
- }
- }
- }
- </style>
|