这里我是用的自定义组件component——uploadImages
一.单张图片上传
uploadImages.wxml
<button bindtap='doUpload'>上传图片</button>
<view class='flexCenter w100' wx:if='{{imgUrl}}'>
<image src='{{imgUrl}}' class='w100' mode="aspectFit" ></image>
</view>
uploadImages.js
var app=getApp()
// component/public-component/uploadImages/uploadImages.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
count:0,
imgUrl:""
},
/**
* 组件的方法列表
*/
methods: {
doUpload:function(){
var that=this;
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
console.log(res);
const filePath=res.tempFilePaths[0];
that.setData({
imgUrl: filePath //在wxml中显示图片的路径 ,要保存下来传入数据库(传入page)
})
//上传图片:这里我是要把文件上传到云存储管理的“images-roomType/此用户的open_id/”的文件夹下
var cloudPath="images-roomType/"+app.globalData.openId+"/"+that.data.count + filePath.match(/\.[^.]+?$/)[0]; //count+".后缀", 如“0.png”
console.log(cloudPath);
wx.cloud.uploadFile({
cloudPath:cloudPath,
filePath:filePath,
success:res=>{
console.log("上传成功");
console.log(res)
}
})
},
})
}
}
})
二.多张图片上传
uploadImages.wxml
<!--component/public-component/uploadImages/uploadImages.wxml-->
<view class="upload-box">
<view class="img" wx:for="{{imgUrl}}">
<image src="{{item}}"></image>
<!-- 删除按钮 --->
<icon type="clear" bindtap='doDelete' id="{{index}}"></icon>
</view>
<!-- 添加图片:最多只能八张 --->
<view class="add" bindtap='doUpload' wx:if="{{count<8}}">+</view>
</view>
uploadImages.js
var app=getApp()
// component/public-component/uploadImages/uploadImages.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
count: 0, //count=imgUrl.length
imgUrl: [], //结束后将imgUrl返回page记录下来
cloudPath: [], //在云文件中的存储位置:fileId=app.global.fileIdPre+cloudPath ,app.global.fileIdPre就是云开发控制台的路径
//我的fileIdPre为:"cloud://zb-database-cd1fc2.7a62-zb-database-xxx1fc2/"
},
/**
* 组件的方法列表
*/
methods: {
//上传
doUpload:function(){
var that=this;
//选择图片
wx.chooseImage({
count: 8, //最多8张
sizeType: ['compressed'], //图片压缩
sourceType: ['album', 'camera'],
success: function(res) {
var imgUrl = that.data.imgUrl;
var filePath = res.tempFilePaths;
//判断已经上传的图片有没有,如果有就要将两个数组合并
if (imgUrl.length !== 0) {
imgUrl = imgUrl.concat(filePath)
}
else {
imgUrl = filePath
}
that.setData({
imgUrl: imgUrl
})
//上传图片
var cloudPath = [];
//上传文件只能单个上传
for (var i in filePath) {
//获取数据库中图片数量count,通过“count.后缀”来添加图片保证图片不覆盖
var url = "images-roomType/" + app.globalData.openId + "/" + that.data.count + filePath[i].match(/\.[^.]+?$/)[0];
cloudPath.push(url); //记录下云文件的位置
wx.cloud.uploadFile({
cloudPath: url,
filePath: filePath[i],
success:res=>{
console.log("上传成功");
that.setData({ //从渲染中删除
count: that.data.count + 1,
cloudPath: cloudPath
})
//将记录存入数据库(我的方法时先传入页面,再由页面传入数据库。但也可以直接传入数据库,稍后会有说明)
//此处省略,请看下面补充
//...
},
fail:res=>{
console.log(res)
}
})
}
},
})
},
//删除图片
doDelete:function(e){
//数据库中删除
var index = e.target.id;
var imgUrl = this.data.imgUrl;
imgUrl.splice(index, 1);
//云存储中删除:获取此云文件id
var cloudPath = this.data.cloudPath
var fileId = app.globalData.fileIdPre + cloudPath[index]
wx.cloud.deleteFile({
fileList:[fileId],
success:res=>{
console.log("删除成功");
this.setData({ //从渲染中删除
imgUrl: imgUrl,
count:that.data.count-1
})
//将记录存入数据库(我的方法时先传入页面,再由页面传入数据库。但也可以直接传入数据库,稍后会有说明)
//此处省略,请看下面补充
//...
},
fail:res=>{
console.log(res)
}
})
}
}
})
补充说明
除了以上将图片渲染到界面和存入云文件 ,还有一个很重要并且必不可少的步骤:将图片路径和fileId(fileId是处理云文件函数里面必不可少的)保存到数据库
- 为什么是必不可少的呢?
你在这个页面把文件数据都渲染出来了?那下一个页面呢,还要显示这张图片的话,怎么办?总不能把所有的图片位置都存储到全局吧,所以老老实实的把路径送到数据库吧 - 怎么存入数据库?
这里有两种方法:
1.直接存入数据库(这里只说明了存入,删除类似)
//存入数据
_saveData:function(){
var that=this;
var id="";
//定义数据
var data=[];
var imgUrl = that.data.imgUrl;
var cloudPath = that.data.cloudPath;
for (var i in imgUrl){
data[i] = [imgUrl[i], cloudPath[i]]
}
console.log(data)
//处理数据库
wx.cloud.init();
const db = wx.cloud.database();
//通过openid找数据
db.collection('roomType').where({
_openid:app.globalData.openId
}).get({
success(res){
console.log(res);
//如果res.data==""代表roomType表里面没有这个用户的数据
if(res.data==""){
//直接插入数据 add
db.collection('roomType').add({
data: {
images:data
},
success(res){
console.log(res)
}
})
}
else{
//找到id后更新数据
id=res.data[0]._id;
db.collection('roomType').doc(id).update({
data:{
images:data
},
success(res){
console.log(res);
}
})
}
}
})
}
这是将数据{ [ imgUrl , cloudPath ] }存入数据库的函数 , 直接在前面插入数据的success函数里调用即可
2.传入页面之后再传入数据库(这里我是用这个方法的原因是,我在一个表单里有一项功能传入图片,但是我想要在最后用户点了确定之后,再把数据传入数据库)
这里先说明组件与页面之间的数据传递
参考:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html
- 首先在调用组件的页面中,将此组件绑定事件
index.wxml
//uploadImages 是上面的组件名
<uploadImages bind:myevent="onMyEvent"></uploadImages>
index.js
onMyEvent:function(e){
console.log(e.detail)
}
- 在组件中,只要任何事件中有triggerEvent()就可以传递数据 ,这里我同样选择在上传和删除文件success后传递数据
//传递数据给页面的函数:直接在success调用即可
sendDataToPage:function(){
console.log(1)
var that=this
var imgUrl = that.data.imgUrl;
var cloudPath = that.data.cloudPath;
var imageData = []
for (var i in imgUrl) {
imageData[i] = [imgUrl[i], cloudPath[i]]
}
const myEventDetail = { imageData} // detail对象,提供给事件监听函数
const myEventOption = {} // 触发事件的选项
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
网友评论