vue3+uni-app 瀑布流

哈喽大家好,能和大家见面啦,我依旧是那个可爱的秃头小兄弟。
今天又周二了啊,划水人的一天,开心。
话不多说哈,直接搂代码

一般用于图片多列展示。列宽固定,图片根据自身高度自适应交错排列

(通过计算图片的高度累加去实现瀑布流的效果)

  1. 声明需要的数据

    //声明需要的数据
    const data = reactive({
      leftList: [], // 左边列图片
      rightList: [], // 右边列图片
      leftHeight: 0, // 左边列高度
      rightHeight: 0, // 右边列高度
      columnWidth: 0, // 列宽度
    })
    
    
  2. 在这里进行左右两个列表的分开循环渲染

    //在这里进行左右两个列表的分开循环渲染
     <view class="a1">
          <view class="a1-l">
            <view
              v-for="(item, i) in data?.leftList"
              :key="i"
              class="leftList"
              @click="go(item)"
            >
              //在这里我将图片加载写成组件 加上loading效果
              <shu-img-loading
                class="image"
                :src="item.images[0].url"
                :custom-style="{
                  height: `${item.height}px`,
                  width: '100%',
                }"
                :mode="item.mode"
              />
              <view class="title-info">
                <view class="item-title">
                  {{ item?.title }}
                </view>
                <view class="item-desc">
                  #{{ item?.talkName }}
                </view>
                <view class="item-name">
                  {{ item?.name }}
                </view>
              </view>
            </view>
          </view>
          <view class="a1-r">
            <view
              v-for="(item, i) in data?.rightList"
              :key="i"
              class="rightList"
              @click="go(item)"
            >
             //在这里我将图片加载写成组件 加上loading效果
              <shu-img-loading
                class="image"
                :src="item.images[0].url"
                :custom-style="{
                  height: `${item.height}px`,
                  width: '100%',
                }"
                :mode="item.mode"
              />
              <view class="title-info">
                <view class="item-title">
                  {{ item?.title }}
                </view>
                <view class="item-desc">
                  #{{ item?.talkName }}
                </view>
                <view class="item-name">
                  {{ item?.name }}
                </view>
              </view>
            </view>
          </view>
        </view>
    
  3.  width这里给的是174 这个值也是需要去计算的 但是我这里给的有固定值 就不需要计算
    在这里用的watch是因父组件传过来的需要进行监听,正好在这里进行的数据的处理,将处理后的高度挂在列表里形成一个标识

    
    
    watch(
      () => props.datalist,
      (nv) => {
        if (nv?.length) {
          realData.value = props.datalist.map((item) => {
            return {
              ...item,
              ...getElemHeight(item.images[0].height, item.images[0].width, 174),
            }
          })
          setWaterFallLayout()
        }
        nextTick(() => {})
      },
      { immediate: true, deep: true },
    )
    
    // 每个照片的真实高度   的到处理后的高度 (这里面的参数需要在循环的事件上传过来)
    function getElemHeight(height, width, testW) {
      const mode = 'aspectFill'
      let realH = Math.floor(testW / (width / height))
    //在这计算的单位是px. 在进行渲染的时候要换算成rpx. 
    //240  就是给图片最高度一个限制 最高240 超过240 就给他240  
    //98  就是给图片最低度一个限制 最低98 低于98 就给他98 
      if (realH > 240) {
        realH = '240'
      }
    
      if (realH < 98) {
        realH = '98'
      }
    
      return {
        height: `${realH}`,
        mode,
        ratio: realH / testW,
      }
    }
    
    
    //拿到每条数据进行循环 进行判断左右两边的高度差从而进行push到左右两边的数组中 并且高度进行添加
     realData.value.forEach((item) => {
    //Number (140)这个参数就是图片下边的文本域高度具体高度视情况而定
        const h = Number(item.height) + Number(140) // 图片渲染后的高度
    
        if (data.leftHeight <= data.rightHeight) {
          data.leftList.push(item)
          data.leftHeight += h * 1
        }
        else {
          data.rightList.push(item)
          data.rightHeight += h * 1
        }
      })
  4. css样式
    .a1 {
      padding-bottom: 80rpx!important;
      justify-content: space-around;
      display: flex;
      background: #f5f3f4;
    
      // margin: 0 auto;
    
      .a1-l,
      .a1-r {
        // background-color: #fff;
        width: 48%;
        // border-radius: 8rpx;
        .leftList,
        .rightList {
          margin-top: 14rpx;
          background-color: #fff;
          border-radius: 20rpx;
          overflow: hidden;
          .image {
            border-radius: 20rpx 20rpx 0 0;
          }
          .title-info {
            padding: 0rpx 20rpx 20rpx;
    
            .item-title {
              height: 44rpx;
              color: #000;
              font-size: 30rpx;
              font-style: normal;
              font-weight: 500;
              line-height: normal;
              letter-spacing: -0.373px;
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
            }
    
            .item-desc {
              margin: 6rpx 0;
              color: #656565;
              font-size: 24rpx;
              font-style: normal;
              font-weight: 500;
              line-height: normal;
              letter-spacing: -0.373px;
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
            }
            .item-name {
              color: #656565;
              font-size: 22rpx;
              font-style: normal;
              font-weight: 400;
              line-height: 150%; /* 16.5px */
              letter-spacing: -0.373px;
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
            }
          }
        }
      }
    }

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
首先,你需要在后端创建一个定时任务,用于监测订单是否超时,并将超时的订单状态设置为“取消”。 在前端,可以使用Vue3和Vant4来实现订单超时取消功能。具体步骤如下: 1. 创建一个定时器,用于监测订单是否超时。可以使用Vue3中的watch()函数监测订单状态是否为“待支付”,如果是,则设置一个定时器,定时器时间为订单超时时间减去当前时间,当定时器时间到达后,触发取消订单的操作。 2. 在取消订单的操作中,向后端发送取消订单的请求,并更新订单状态为“取消”。 3. 在前端界面中,可以使用Vant4中的弹窗组件来提示用户订单已经超时取消。可以在取消订单的操作中,弹出一个提示框,提示用户订单已经超时取消。 下面是一个简单的示例代码: ``` <template> <div> <van-button @click="payOrder">支付订单</van-button> </div> </template> <script> import { ref, watch } from 'vue'; import { Dialog, Toast } from 'vant'; export default { setup() { const orderStatus = ref('待支付'); const orderTimeout = ref(60); // 订单超时时间为60秒 // 监测订单状态是否为“待支付”,如果是,则设置定时器 watch(orderStatus, (newVal) => { if (newVal === '待支付') { const timer = setInterval(() => { orderTimeout.value -= 1; if (orderTimeout.value <= 0) { clearInterval(timer); cancelOrder(); } }, 1000); } }); // 取消订单操作 const cancelOrder = () => { // 向后端发送取消订单的请求,并更新订单状态为“取消” // ... // 弹出提示框,提示用户订单已经超时取消 Dialog.alert({ title: '订单已取消', message: '订单已超时取消,请重新下单', }); }; // 支付订单操作 const payOrder = () => { // 向后端发送支付订单的请求 // ... // 更新订单状态为“已支付” orderStatus.value = '已支付'; // 弹出提示框,提示用户支付成功 Toast.success('支付成功'); }; return { orderStatus, orderTimeout, cancelOrder, payOrder, }; }, }; </script> ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值