原生微信小程序里面模仿发送朋友圈以九宫格形式并可以拖拽换图片位置的好用组件

图例:

1.先创建组件取名:van-dragImgList

2.组件代码:

wxml:

<view class="drag-container" id="drag-container" style="height: {{imgItemHeight}}px;">
  <view
    wx:for="{{dragImgList}}" 
    wx:key="index"
    style="transform: translate({{index === currentIndex ? tranX : item.tranX}}px, {{index === currentIndex ? tranY : item.tranY}}px); z-index: {{index === currentIndex ? 10 : 1}};height: {{ITEM_SIZE}}px;"
    class="darg-item item-transition"
    mark:index="{{index}}"
    mark:key="{{item.key}}"
    catch:longpress="longPress"
    catch:touchmove="touchMove"
    catch:touchend="touchEnd"
  >
    <image class="darg-item-img" mode="aspectFill" src="{{item.src}}" data-index="{{index}}" bindtap="previewImage"/>
    <view catch:tap="deleteImg" mark:key="{{item.key}}" class="drag-item-delete"><van-icon name="cross" /></view>
  </view>
  <view
    bindtap="uploadImage"
    class="darg-item drag-item-upload"
    hidden="{{dragImgList.length >= 18}}"
    style="transform: translate({{uploadPosition.tranX}}px, {{uploadPosition.tranY}}px); height: {{ITEM_SIZE}}px;"
  >
    <van-icon wx:if="{{ITEM_SIZE}}" class="iconfont icon-mn_shangchuantupian_fill" class-prefix="icon" name="icon-mn_shangchuantupian_fill" size="80rpx"></van-icon>
  </view>
</view>

wxss:

.drag-container{
  position: relative;
}
.item-transition {
  transition: transform 0.1s
}
.darg-item{
  position: absolute;
  top: 0;
  left: 0;
  /* width: 100px; */
  /* height: 100px; */


  width: calc(100% / 3);
  height: calc(100% / 3);
}
.darg-item-img{
  width: 100%;
  height: 100%;
  border:2rpx solid #ffffff;
  box-sizing: border-box;
  
  /* position: absolute; */
  object-fit: cover;
  /* left:50%;
  top:0;
  transform: translate(-50%,0); */
}
.drag-item-delete{
  position: absolute;
  top: 2rpx;
  right: 2rpx;
  width: 33rpx;
  height: 33rpx;
  background-color: rgba(0,0,0,0.5);
  font-size: 35rpx;
  line-height: 28rpx;
  text-align: center;
  border-radius: 8rpx;
  /* border-radius: 0 0 0 64rpx; */
  color: #fff;
}
.drag-item-upload{
  background-color: #f7f7f7;
  /* font-size: 200rpx; */
  text-align: center;
  color: white;
  /* line-height: 150rpx; */
  border: 2rpx solid #ffffff;
  box-sizing: border-box;
  position: relative;
}
.iconfont {
  font-size: 80rpx;
  color: #acacac;
  margin-top: 72rpx;
}

json:

{
  "component": true,
  "usingComponents": {}
}

js:


Component({

    /**
     * 组件的属性列表
     */
    properties: {
        data: {
            type: Array,
            value: []
        },
        isPreviewMode: {
            type: Boolean,
            value: false
        },
        dataIntroPicsProps:{
          type: Array,
          value: []
        }
    },
    observers: {
      dataIntroPicsProps: function(dataIntroPics) {
          console.log(dataIntroPics,'图文传过去的数据!!!');
          if(dataIntroPics){
            this.setData({
              dragImgList: dataIntroPics
            });
            console.log(4444444444,this.data.dragImgList)
          }
      }
    },
    /**
     * 组件的初始数据
     */
    data: {
      ITEM_SIZE: 0, // 图片大小 单位px
      dragImgList: [], // 图片列表 { src: string, key: number, tranX: number, tranY: number }[]
      containerRes: {}, // 拖拽容器属性
      currentKey: -1, // 正在拖拽图片的key
      currentIndex: -1, // 正在拖拽图片的index
      tranX: 0, // 正在拖拽图片移动的x距离
      tranY: 0, // 正在拖拽图片移动的y距离
      uploadPosition: { // upload上传图标位移距离
        tranX: 0,
        tranY: 0,
      },
      imgItemHeight:0,
    },
    lifetimes: {
      ready() {
        this.createSelectorQuery()
          .select(".drag-container")
          .boundingClientRect((res) => {
            this.data.containerRes = res
            console.log('宽度111:', res);
            this.setData({
              containerRes:res,
              ITEM_SIZE:res.width/3,
              imgItemHeight:res.width/3
            })
            // ============================= 还原上传的位置
            // 修改剩余图片位置
            this.getListPosition(this.data.dragImgList)
            // 修改上传图标位置
            this.setUploaPosition(this.data.dragImgList.length)
            this.getDragImgListHeight();
          }).exec();
      }
    },
    /**
     * 组件的方法列表
     */
    methods: {
      uploadImage() {
        let that = this;
        let { dragImgList, ITEM_SIZE } = that.data
        wx.chooseImage({
          count: 9 - dragImgList.length,
          success: (res) => {
            const imgList = res.tempFilePaths.map((item, index) => ({
              tranX: ITEM_SIZE * ((dragImgList.length + index) % 3),
              tranY: Math.floor((dragImgList.length + index) / 3) * ITEM_SIZE,
              src: item,
              key: dragImgList.length + index
            }))
            dragImgList = dragImgList.concat(imgList)
            // 修改上传图标位置
            that.setUploaPosition(dragImgList.length)
            that.setData({
              dragImgList,
            })
            that.getListPosition(dragImgList)
            that.getDragImgListHeight();
          }
        })
      },
      getDragImgListHeight(){
        let dragImgList = this.data.dragImgList;
        let ITEM_SIZE_H = this.data.ITEM_SIZE;
        if(dragImgList.length<3){
          this.setData({
            imgItemHeight:ITEM_SIZE_H
          })
        }else if(dragImgList.length>2 && dragImgList.length<6){
          this.setData({
            imgItemHeight:ITEM_SIZE_H*2
          })
        }else if(dragImgList.length>5 && dragImgList.length<9){
          this.setData({
            imgItemHeight:ITEM_SIZE_H*3
          })
        }else if(dragImgList.length>8 && dragImgList.length<12){
          this.setData({
            imgItemHeight:ITEM_SIZE_H*4
          })
        }else if(dragImgList.length>11 && dragImgList.length<15){
          this.setData({
            imgItemHeight:ITEM_SIZE_H*5
          })
        }else if(dragImgList.length>14 && dragImgList.length<19){
          this.setData({
            imgItemHeight:ITEM_SIZE_H*6
          })
        }
      },
      setUploaPosition(listLength) {
        const ITEM_SIZE = this.data.ITEM_SIZE
        const uploadPosition = {
          tranX: listLength % 3 * ITEM_SIZE,
          tranY: Math.floor(listLength / 3) * ITEM_SIZE,
        }
        this.setData({
          uploadPosition,
        })
      },
      deleteImg(e) {
        console.log(e,444777888);
        const key = e.mark.key
        // 删除图片
        const list = this.data.dragImgList.filter((item) => item.key !== key)
        // 修改key值
        list.forEach((item) => item.key > key && item.key--)
        // 修改剩余图片位置
        this.getListPosition(list)
        // 修改上传图标位置
        this.setUploaPosition(list.length)
        this.getDragImgListHeight();
      },
      getListPosition(list) {
        const ITEM_SIZE = this.data.ITEM_SIZE
        const dragImgList = list.map((item) => {
          item.tranX = ITEM_SIZE * (item.key % 3);
          item.tranY = Math.floor(item.key / 3) * ITEM_SIZE;
          return item
        })
        this.setData({
          dragImgList,
        })
        // 向页面传递最新图片列表
        const urlList = [...dragImgList].sort((a, b) => a.key - b.key).map((item) => item.src)
        this.triggerEvent('updateImage', {
          list: urlList,
          dragImgList:JSON.stringify(dragImgList)
        })
      },
      // 
      longPress(e) {
        const index = e.mark.index
        const { pageX, pageY } = e.touches[0]
        const { top, left } = this.data.containerRes
        this.setData({
          currentIndex: index,
          tranX: pageX - 50 - left,
          tranY: pageY - 50 - top
        })
      },
      touchMove(e) {
        // 如果currentIndex < 0,说明并没有触发longPress
        if (this.data.currentIndex < 0) return
        const { pageX, pageY } = e.touches[0]
        const { top, left } = this.data.containerRes
        const tranX = pageX - 50 - left
        const tranY = pageY - 50 - top
        this.setData({
          tranX,
          tranY
        })
        // 对比当前移动的key和停放位置的key,如果不一样就修改位置
        const currentKey = e.mark.key
        const moveKey = this.getMoveKey(tranX, tranY)
        if (currentKey === moveKey || this.data.currentKey === currentKey) return
        this.data.currentKey = currentKey
        this.insert(currentKey, moveKey)
      },
      getMoveKey(tranX, tranY) {
        const { dragImgList: list, ITEM_SIZE } = this.data
        const _getPositionNumber = (position) => {
          const positionNumber = Math.round(position/ ITEM_SIZE)
          return positionNumber > 2 ? 2 : positionNumber < 0 ? 0 : positionNumber
        }
        const endKey = 6 * _getPositionNumber(tranY) + _getPositionNumber(tranX)
        return endKey >= list.length ? list.length - 1 : endKey
      },
      insert(origin, end) {
        const dragImgList = this.data.dragImgList
        dragImgList.forEach((item) => {
          if (origin < end) {
            // 如果起始key小于结束key,就把区间内的key全部减一
            if (item.key > origin && item.key <= end) item.key--
            else if (item.key === origin) item.key = end
          } else if (origin > end) {
            // 如果起始key大于结束key,就把区间内的key全部加一
            if (item.key >= end && item.key < origin) item.key++
            else if (item.key === origin) item.key = end
          }
        })
        this.getListPosition(dragImgList)
      },
      touchEnd() {
        this.setData({
          tranX: 0,
          tranY: 0,
          currentIndex: -1,
        })
        this.data.currentKey = -1
        this.getDragImgListHeight();
      },
      previewImage(e){
        // 获取数据索引
        let that = this;
        const index = e.currentTarget.dataset.index;
        let dragImgListurls = [];
        for(let i=0;i<that.data.dragImgList.length;i++){
          dragImgListurls.push(that.data.dragImgList[i].src);
        }
        console.log(dragImgListurls);
        wx.previewImage({
          current: that.data.dragImgList[index].src, // 当前显示的图片链接
          urls: dragImgListurls// 需要预览的图片链接列表
        })
      },
    },
})

以上就是主要组件模块! 接下来就是要使用这个组件

在app.json里面全局引入:

"usingComponents": {"van-dragImgList": "./pages/app/components/dragImgList/index",}

页面中使用:

wxml:

<van-dragImgList bind:updateImage="updateImage" dataIntroPicsProps="{{dataIntroPics}}"></van-dragImgList>

注意:updateImage 方法,是组件内部上传图片,把图片数据或者其他需要的数据传给当前使用组件的页面;dataIntroPics是当前页面给组件内部传数据(当前传的数据是内部反显图片的数据用的)

js:

 updateImage(e) {
    console.log(e,'组建999')
    this.parentMethod(e.detail);
  },
  parentMethod(data) {
    // 主页面的方法
    console.log('Parent method called with data:', data);

    this.setData({
      ['params.mediaResources']:data.list,
      ['params.pageConfig']:data.dragImgList
    })
  },

注意:

['params.mediaResources']:data.list,

['params.pageConfig']:data.dragImgList

就是当前页面接受组件传过来的数据; 

目前我的组件是根据公司需求支持18张图的;你们可以根据需求修改代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

we_前端全家桶

同行的老铁支援点银两哇,????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值