小程序之图片的上传、删除和预览和视频的上传和删除

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yhflyl/article/details/85219194

最近在做一个小程序,帖子中用到了一个关于文字、图片和视频的一些操作。

最终的样式

原始样式 上传图片 上传视频
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

这个可以实现输入文字的统计和限制,图片的上传、预览和删除,视频的上传和删除功能。

如何实现上面的那些样式呢?

大家可以先阅读下面的文档,会发现其实很简单。

小程序关于图片操作的api文档:https://developers.weixin.qq.com/miniprogram/dev/api/wx.compressImage.html

小程序关于视频操作的api文档:https://developers.weixin.qq.com/miniprogram/dev/api/wx.saveVideoToPhotosAlbum.html

首先wxml文件

<view class="containor">
  <view class="publish_text_area">
    <!-- 标题 -->
    <view class="text_area_title">
      <input 
        class="title_input" 
        placeholder="请输入标题" 
        maxlength="25" 
        placeholder-style="color:#b3b3b3;font-size:16px;" 
        bindinput="handleTitleInput"
        value="{{title}}"
      ></input>
      <!-- 标题字数限制 -->  
      <view 
        class="{{ titleCount < 25 ? 'title_input_counter' : 'title_input_error_counter' }}"
      >{{titleCount}}/25</view>
    </view>
    <!-- 内容 -->
    <view class="text_area_content">
      <view class="area_content">
        <view class="area_content_out">
          <textarea 
            class="content-textarea" 
            placeholder="请输入正文内容..." 
            maxlength="255" 
            placeholder-style="color:#b3b3b3;font-size:12px;"
            style="height: 8rem" 
            bindinput="handleContentInput" 
            value="{{content}}"
          />
          <!-- 字数限制 -->  
          <view class="{{ contentCount < 255 ? 'content_textarea_counter' : 'content_textarea_error_counter'}}">{{contentCount}}/255</view>
        </view>
      </view>
    </view>
  </view>

  <view class="publish_imgs_area">
    <!-- 图片 -->
    <view class="imgs_area" wx:for="{{images}}" wx:key="*this">
      <view class="iamge_item">
        <image 
          class="iamge_content" 
          src="{{item}}" 
          data-id="{{index}}"
          mode="aspectFill" 
          bindtap="previewIamge"
        />
        <image 
          class="iamge_cancel" 
          src="./images/cancel.png" 
          mode="aspectFill" 
          data-id="{{index}}"
          bindtap="deleteImage"
        />
      </view>
    </view>
    <!-- 视频 -->
    <view class="video_area" wx:if="{{video != ''}}">
      <video
        class="video_item"
        src="{{video}}"
        controls
      ></video>
      <!-- 防止视频组件层级太高,导致部分机型覆盖悬浮按钮 -->
      <cover-image 
        class="video_delete" 
        src="./images/video_del.png" 
        mode="aspectFill" 
        bindtap="videoDelete"
      />
    </view>
    <!-- 图片上传图片按钮 -->
    <view class="imgs_area" bindtap="chooseImage" wx:if="{{images.length < 9 && video == ''}}">
      <view class="iamge_item">
        <image class="iamge_content" src="./images/upload.png" mode="aspectFill" />
      </view>
    </view>
    <!-- 视频上传图片按钮 -->
    <view class="imgs_area" bindtap="chooseVideo" wx:if="{{video == '' &&  images.length == 0}}">
      <view class="iamge_item">
        <image class="iamge_content" src="./images/video.png" mode="aspectFill" />
      </view>
    </view>
  </view>
  <view class="btn_all_area">
    <button
      class="btn_area"
      type="primary"
      bindtap="submitClick"
    >提交</button>
    <button
      class="btn_area"
      type="warn"
      bindtap="resetClick"
    >重置</button>
  </view>
</view>

接下来wxss文件

page {
    background-color: #f1efef;
}

.containor {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.publish_text_area {
    background-color: #ffffff;
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin:20rpx 20rpx 6rpx 20rpx;
    border-radius: 15rpx;
}

.text_area_title {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    margin: 10rpx;
}

.text_area_content {
    
}

.title_input {
    font-size: 30rpx;
    width:590rpx;
}

.title_input_counter {
    font-size:32rpx;
    color:#b3b3b3;
    margin-top:5rpx;
}

.title_input_error_counter {
    font-size:32rpx;
    color:#ce2f2f;
    margin-top:5rpx;
}

.area_content {
    border-top: 1rpx solid #f1efef;
    margin-left: 10rpx;
    margin-right: 10rpx;
}

.area_content_out {
    /* border-top: 1px solid #f1efef; */
    margin-top: 10rpx;
}

.content-textarea {
    width: 690rpx;
    font-size: 24rpx;
}

.content_textarea_counter {
    color:#d4d0d0;
    font-size:30rpx;
    text-align:right;
}

.content_textarea_error_counter {
    color:#ce2f2f;
    font-size:30rpx;
    text-align:right;
}
/* 图片部分 */
.publish_imgs_area{
    background-color: #ffffff;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    flex-wrap: wrap;
    border-radius: 15rpx;
    margin: 20rpx;
    padding-left: 8rpx;
    padding-top: 8rpx;
    padding-bottom: 8rpx;
    /* height: 450rpx; */
}

.iamge_item {
    width: 225rpx;
    height: 225rpx;
    padding: 4rpx;
}

.iamge_content{
    width: 223rpx;
    height: 223rpx;
    border-radius: 15rpx;
    border: 1px solid #f1efef;
}

.iamge_cancel{
    width:40rpx;
    height:40rpx;
    border-radius:50%;
    position:relative;
    top:-259rpx;
    right:-204rpx;
    z-index:800;
}

/* 视频部分样式 */
.video_area {
    width: 700rpx;
    position: relative;
}

.video_item {
    width: 700rpx;
}
.video_delete {
    width: 50rpx;
    height: 50rpx;
    position: absolute;
    top: 10rpx;
    right: 2rpx;    
}

.btn_all_area {
    background-color: #ffffff;
    display: flex;
    flex-direction: row;
    justify-content: center;
    margin:20rpx 20rpx 6rpx 20rpx;
    border-radius: 15rpx;
    /* position: absolute;
    bottom: 0; */
}

.btn_area {
    width: 350rpx;
}

最后是Js文件

对于图片的上传,可以存在两种情况:1、第一次就上传了九张图片;2、第一次不够九张,第二次接着上传。所有我们需要对这个条件就行判断。

Page({
  /**
   * 页面的初始数据
   */
  data: {
    // 标题数
    titleCount: 0,
    // 详情数
    contentCount: 0,
    // 标题内容
    title: '',
    // 标题内容
    content: '',
    // 图片列表
    images: [],
    // 视频
    video : '',
  },

  // 图片操作的具体函数
  ImageOperator() {
    wx.chooseImage({
      count: 9,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: res =>  {
        // 上传的图片数据
        const imgList = res.tempFilePaths;
        // 原始的图片数据
        const imageList = this.data.images;

        // 原来的图片数量
        let imageLenght = imageList.length;
        // 当前的图片数量
        let nowLenght = imgList.length;
        console.log(imageLenght);

        if ( imageLenght == 9 ) {
          console.log("数量已经有9张,请删除在添加...");
        }
        if ( imageLenght < 9 ) {
          let images = [];
          // 获取缺少的图片张数
          let residue = 9 - imageLenght;
          // 如果缺少的张数大于当前的的张数  
          if ( residue >= nowLenght ) {
            // 直接将两个数组合并为一个  
            images = imageList.concat(imgList);
          }else {
            // 否则截取当前的数组一部分  
            images = imageList.concat(imgList.slice(0, residue));
          }  
          this.setData({
            images
          })
        }
      }
    })
    
  },

  // 标题操作
  handleTitleInput(event) {
    let inputValue = event.detail.value;
    // 确保标题不存在空格  
    if(inputValue.lastIndexOf(" ") != -1){
      inputValue = inputValue.substring(0, inputValue.lastIndexOf(" "));
    }
    let titleCount = inputValue.length;
    if(titleCount <= 25){
      this.setData({
        titleCount: titleCount ,
        title: inputValue
      })
    }
  },
  // 内容操作
  handleContentInput(event) {
    let textareaValue = event.detail.value;
    let contentCount = textareaValue.length;
    if(contentCount <= 255){
      this.setData({
        contentCount: contentCount,
        content: textareaValue
      })
    }
  },
  // 图片获取
  chooseImage() {
    if (this.data.images.length == 0) {
      wx.showToast({
        title: '视频和图片只能选择上传一种类型!',
        icon: 'none',
        duration: 2000,
        success: res => {
          this.ImageOperator()
        }
      })
    }else {
      this.ImageOperator()
    }
    
  },
  // 删除图片
  deleteImage(event) {
    //获取数据绑定的data-id的数据
    const nowIndex = event.currentTarget.dataset.id;
    let images = this.data.images;
    images.splice(nowIndex, 1);
    this.setData({
      images
    })
  },
  // 预览图片
  previewIamge(event) {
    const nowIndex = event.currentTarget.dataset.id;
    const images = this.data.images;
    wx.previewImage({
      current: images[nowIndex],  //当前预览的图片
      urls: images,  //所有要预览的图片
    })
  },
  // 上传视频
  chooseVideo() {
    // 弹层  
    wx.showToast({
      title: '视频和图片只能选择上传一种类型!',
      icon: 'none',
      duration: 2000,
      success: res => {
        wx.chooseVideo({
          sourceType: ['album', 'camera'],
          compressed: true,
          maxDuration: 10,
          camera: 'back',
          success: res => {
            console.log(res);
            const video = res.tempFilePath;
            this.setData({video})
          }
        })
      }
    })
  },
  // 删除视频
  videoDelete(){
    wx.showModal({
      title: '警告',
      content: '确定要删除该视频吗',
      success: res => {
        if (res.confirm) {
          this.setData({
            video: ''
          })
        }
      }
    })
  },
  // 表单提交事件
  submitClick() {

  },
  // 重置表单
  resetClick() {
    wx.showModal({
      title: '警告',
      content: '重置表单将需要重新上传数据',
      success: res => {
        if (res.confirm) {
          this.setData({
            titleCount: 0,
            contentCount: 0,
            title: '',
            content: '',
            images: [],
            video : ''
          })
        }
      }
    })
  }
})

这样就实现了,代码还有很多需要优化的地方,如果需要请自行斟酌使用!

猜你喜欢

转载自blog.csdn.net/yhflyl/article/details/85219194