unicloud33-自定义上传 chooseImage选择本地上传

165 阅读2分钟

自定义上传组件 手写上传组件和方法

创建一个新页面file,先写布局,放几张图占位,放一个添加图片的盒子,还有一个删除图片的叉号

<template>
  <view class="file">
    <view class="uploadGroup">
      <view class="box" v-for="item in 5">
        <image src="../../static/logo.png" mode="aspectFill"></image>
        <view class="close">×</view>
      </view>
      
      <view class="box add">+</view>
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        
      };
    }
  }
</script>

<style lang="scss" scoped>
  .uploadGroup {
    padding: 30rpx;
    // 使按钮和图片在一行显示
    display: flex;
    // 使图片自动换行,否则全挤在一行会出错
    flex-wrap: wrap;
    .box {
      width: 200rpx;
      height: 200rpx;
      background: #eee;
      // 给图片和按钮加右边距
      margin-right: 15rpx;
      // 给图片和按钮加下边距
      margin-bottom: 15rpx;
      position: relative;
      image {
        width: 100%;
        height: 100%;
      }
      .close {
        // 给子级加固定定位,通过就要给父级.box加相对定位
        position: absolute;
        // 将关闭叉号x定位到右上角
        right: 0;
        top: 0;
        width: 50rpx;
        height: 50rpx;
        background: rgba(0,0,0,0.7);
        color: #fff;
        // 把关闭按钮变成圆角
        border-radius: 0 0 0 80rpx;
        // 使乘号居中显示
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
    .add {
      font-size: 80rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #888;
    }
  }
</style>

image.png

上传方法

给添加按钮写点击事件 文档在uni-app \rightarrow API \rightarrow 媒体 \rightarrow 图片中可以找到uni.chooseImage方法

    methods:{
      // 点击添加图片
      addFile(){
        uni.chooseImage({
          // compressed 压缩图 original原图
          // sizeType:["compressed"]
          // 限制图片个数
          count:3,
          success:res=>{
            console.log(res);
          }
        })
      }
    }

选择四张图片,控制台会打印前三张

image.png

tempFilePaths里面的这三个文件名是临时地址,把它作为参数给云上传使用

限制图片张数不能通过uni.chooseImagecount属性,这个属性仅能限制每一次选择的张数,如果选择多次,会超出设定的最大值

如果选择了多次,后选的图片会覆盖之前的图片,所以需要将新老图片的临时地址进行拼接,然后在这里对图片的数量进行限制

到这里为止,还没有进行上传,因为保存的是临时路径

<template>
  <view class="file">
    <view class="uploadGroup">
      <view class="box" v-for="item in temFiles">
        <image :src="item" mode="aspectFill"></image>
        <view class="close">×</view>
      </view>
      <!-- 添加图片的图标在图片达到设置的最大数量后就不显示了 -->
      <view class="box add" @click="addFile" v-show="temFiles.length<maxSize">+</view>
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        temFiles:[],
        maxSize:9
      };
    },
    methods:{
      // 点击添加图片
      addFile(){
        uni.chooseImage({
          // compressed 压缩图 original原图
          // sizeType:["compressed"]
          // 限制图片个数,这是每一次选择最多9张,不是一共只能选9张
          // count:9,
          success:res=>{
            // 选择图片时,如果选择了多次,后选择的图片会覆盖前面的图片
            // 所以要把不同次选中的图片路径拼接起来
            let oldTem=this.temFiles;
            let newTem=[...oldTem, ...res.tempFilePaths];
            // 控制图片数量张数,通过变量传递方便以后做功能控制具体的张数
            // count属性是控制每一次选择的图片张数.不能限制总共的图片数量
            newTem = newTem.slice(0,this.maxSize);
            // 把图片的临时地址保存到data
            this.temFiles = newTem
          }
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
  .uploadGroup {
    padding: 30rpx;
    // 使按钮和图片在一行显示
    display: flex;
    // 使图片自动换行,否则全挤在一行会出错
    flex-wrap: wrap;
    .box {
      width: 200rpx;
      height: 200rpx;
      background: #eee;
      // 给图片和按钮加右边距
      margin-right: 15rpx;
      // 给图片和按钮加下边距
      margin-bottom: 15rpx;
      position: relative;
      image {
        width: 100%;
        height: 100%;
      }
      .close {
        // 给子级加固定定位,通过就要给父级.box加相对定位
        position: absolute;
        // 将关闭叉号x定位到右上角
        right: 0;
        top: 0;
        width: 50rpx;
        height: 50rpx;
        background: rgba(0,0,0,0.7);
        color: #fff;
        // 把关闭按钮变成圆角
        border-radius: 0 0 0 80rpx;
        // 使乘号居中显示
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
    .add {
      font-size: 80rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #888;
    }
  }
</style>

选择图片数据达到9张之后,添加图片的按钮隐藏了 image.png

取消选中的图片

要先知道选中的是哪一张图,所以在循环时,要拿到图片的索引,然后,将索引通过点击事件进行传递,这样在点击取消的事件中就能拿到要取消的图片是哪一张了

splice会改变原数组,他通过删除或者替换现有元素或者原地添加新的元素来修改数组,并且以数组形式返回被修改的内容

slice返回由start和end决定的一个浅拷贝的新数组,原数组不会改变

      <view class="box" v-for="(item,index) in temFiles" :key="index">
        <image :src="item" mode="aspectFill"></image>
        <view class="close" @click="onClose(index) ">×</view>
      </view>

完整的方法

<template>
  <view class="file">
    <view class="uploadGroup">
      <view class="box" v-for="(item,index) in temFiles" :key="index">
        <image :src="item" mode="aspectFill"></image>
        <!-- 删除已选择图片 -->
        <view class="close" @click="onClose(index)">×</view>
      </view>
      <!-- 添加图片的图标在图片达到设置的最大数量后就不显示了 -->
      <view class="box add" @click="addFile" v-show="temFiles.length<maxSize">+</view>
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        temFiles:[],
        maxSize:9
      };
    },
    methods:{
      // 取消选中的图片
      onClose(e){
        // 根据索引删除选中的图片
        this.temFiles.splice(e,1)
      },
      // 选择本地图片
      addFile(){
        uni.chooseImage({
          // compressed 压缩图 original原图
          // sizeType:["compressed"]
          // 限制图片个数,这是每一次选择最多9张,不是一共只能选9张
          // count:9,
          success:res=>{
            // 选择图片时,如果选择了多次,后选择的图片会覆盖前面的图片
            // 所以要把不同次选中的图片路径拼接起来
            let oldTem=this.temFiles;
            let newTem=[...oldTem, ...res.tempFilePaths];
            // 控制图片数量张数,通过变量传递方便以后做功能控制具体的张数
            // count属性是控制每一次选择的图片张数.不能限制总共的图片数量
            newTem = newTem.slice(0,this.maxSize);
            // 把图片的临时地址保存到data
            this.temFiles = newTem
          }
        })
      }
    }
  }
</script>

现在选择图片右上角的叉号,已经可以删除图片了

image.png