前言
在《微信小程序云開發快速入門(2/4)》分享中,我們已經將列表的查詢和分頁全部搞定了,可以說對于備忘錄來說已經非常好用了,此時此刻碼仔在腦海中已經開始幻想自己走上了人生的巔峰場景了。
接下來那來分析下需求的具體步驟:
圖片替換需求
- 選擇圖片
- 上傳圖片
- 再次上傳
- 選擇圖片
- 刪除圖片
在這里需要對圖片的數據管理,同時還需要上傳到云存儲當中去。
本地圖片操作
布局走起
很久沒有寫布局樣式了,是不是有些生疏了?感覺復習一下,溫故知新。當我們要調試一個頁面的樣式的時候,首先需要鎖定當前的編譯模式:
先在頭部使用 image 圖片組件區域放上一個拍照的icon,當用戶點擊icon的時候我們就去選擇圖片。
<!-- 頭部 -->
<view class="head-bg">
<!-- 省略無關布局 -->
<image class="img-add" src="../../images/img_add.png"></image>
</view>
然后再給它配置上樣式把位置大概放在茶杯上面去,使用 position 定位。
.img-add{
width: 50rpx;
height: 50rpx;
position: absolute;
right: 65rpx;
top: 450rpx;
}
最終的效果
然后通過 bindtap 綁定一個點擊事件起去選擇圖片。
<image bindtap="chooseImg" class="img-add" src="../../images/img_add.png" />
選擇圖片
在這個 chooseImg 方法中,可以通過 wx.chooseImage() 從本地相冊選擇圖片或使用相機拍照。
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success (res) {
// 由于是數組然后只取一張圖片,所以默認取下標為0的圖片
console.log(res.tempFilePaths[0])
}
})
chooseImage 參數解釋:
- count:可以選擇的照片數量,默認為9張
- sourceType:選擇圖片的來源,默認可以從手機和相機中都支持。
- sizeType:所選的圖片的尺寸,默認是原圖和壓縮圖都支持。
- success(res)
替換圖片
選擇完成之后,接下里就要把圖片來顯示出來,先在data中定義一個變量存放已經選擇好的圖片路徑。
data: {
topImgUrl:''
}
然后把獲取到的值存放在這個變量中
chooseImg(){
let that = this
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success (res) {
that.data.topImgUrl = res.tempFilePaths[0]
}
})
}
之前背景圖片是通過在 css 中使用 background-image 屬性設置的。
.head-bg {
width: 750rpx;
height: 540rpx;
background-image: url('https://6465-demo-3gf9i3wu06a03ab1-1306451997.tcb.qcloud.la/head_bg.png');
background-size: 100% 100%;
}
小程序無法把參數傳遞到css里面只能在wxml里面,所以我們需要把寫成行內樣式。
<!-- 頭部 -->
<view class="head-bg" style="background-image: url('https://6465-demo-3gf9i3wu06a03ab1-1306451997.tcb.qcloud.la/head_bg.png');" >
<!-- 省略無關布局 -->
</view>
然后把 topImgUrl 對圖片路徑進行替換
<!-- 頭部 -->
<view class="head-bg" style="background-image: url('{{topImgUrl}}');" >
<!-- 省略無關布局 -->
</view>
然后運行一下看效果:
這個時候我們會發現一開始進來用戶沒有圖片,所以需要給 topImgUrl 設置一個默認值。
data: {
topImgUrl:'https://6465-demo-3gf9i3wu06a03ab1-1306451997.tcb.qcloud.la/head_bg.png'
}
然后我們再選擇相片試試看效果,我們會發現還是沒有效果,因為不支持本地圖片。那么這個時候我們就需要上傳到云存儲。
圖片上傳云存儲
云端文件存儲,自帶 CDN 加速,支持在前端直接上傳/下載,可在云開發控制臺可視化管理。
云存儲可視化
這張默認圖片其實就是我們之前手動上傳到云存儲上面的,打開云開發控制面板選擇「存儲」可以看到之前上傳的背景圖和氣泡圖。
除了可以直接對文件進行管理之外,它還支持像云數據庫一樣設置權限。
以及還支持緩存配置,支持多種配置策略。
上傳到云存儲
話不多說,接下來通過小程序把選擇好的圖片上傳到云存儲中去,在這里要使用 wx.cloud.uploadFile 將本地資源上傳至云存儲空間。
wx.cloud.uploadFile({
cloudPath: 'example.png',
filePath: '', // 文件路徑
}).then(res => {
// get resource ID
console.log(res.fileID)
})
uploadFile 參數解釋:
- cloudPath:路徑名稱
- filePath:文件路徑
- 返回值 res
通過上傳代碼結合剛才到選擇圖片代碼
chooseImg: function () {
const that = this
wx.chooseImage({
count: 1, // 只選擇一張圖片
sizeType: ['compressed'], // 使用壓縮圖
sourceType: ['album', 'camera'], // 支持照相,相冊
success: function (res) {
const filePath = res.tempFilePaths[0] //上傳第一張圖片
// 生成規則:文件夾路徑 + 時間戳 + 隨機數 + 文件后綴
const cloudPath = `top-img/${Date.now()}-${Math.floor(Math.random(0, 1) * 100000)}` + filePath.match(/.[^.]+?$/)[0]
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
console.log('上傳成功后獲得的res:', res)
that.setData({
topImgUrl:res.fileID
})
},
fail:err=>{
console.log(err)
}
})
}
})
}
上傳成功 res
存儲管理,自動生成了一個文件夾且圖片上傳到這里來了
刪除在線文件
當然上傳那就肯定有刪除,因為總會有不喜歡的圖片需要刪除。需要使用 wx.cloud.deleteFile 從云存儲空間刪除文件。
wx.cloud.deleteFile({
fileList: ['cloud://demo-3gf9i3wu06a03ab1.6465-demo-3gf9i3wu06a03ab1-1306451997/top-img/1627462991919-39954.png']
}).then(res => {
console.log(res.fileList)
})
deleteFile 參數解釋:
- fileList:文件ID數組
- 返回值 res
接下來我來拿剛才的文件ID來使用看下返回結果
獲取在線鏈接
當獲取到FileID還是無法顯示,這個時候需要通過FileID去獲取圖片路徑,使用 wx.cloud.getTempFileURL 用云文件 ID 換取真實鏈接。
wx.cloud.getTempFileURL({
fileList: ['cloud://xxx', 'cloud://yyy'],
success: res => {
// get temp file URL
console.log(res.fileList)
},
fail: err => {
// handle error
}
})
getTempFileURL 參數解釋:
- fileList:文件ID數組
- 返回值 res
接下來我來拿剛才的文件ID來使用看下返回結果
接下來我們需要娶到路徑,最終代碼
chooseImg: function () {
const that = this
// 1. 選擇圖片
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
const filePath = res.tempFilePaths[0] //上傳第一張圖片
const cloudPath = `top-img/${Date.now()}-${Math.floor(Math.random(0, 1) * 100000)}` + filePath.match(/.[^.]+?$/)[0]
console.log(cloudPath)
// 2. 上傳圖片
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
// 3. 獲取鏈接
wx.cloud.getTempFileURL({
fileList: [res.fileID],
success: res => {
that.setData({
topImgUrl: res.fileList[0].tempFileURL
})
}
})
}
})
}
})
}
終于通過幾經波折上傳到圖片顯示出來了
相信你看到這里,肯定會吐槽為什么這么麻煩?能不能簡單點?
當然可以,其實我們可以省略一步,就是去獲取鏈接,因為 image 組件的 src 屬性支持文件ID,這樣機會你需要獲取鏈接這一步驟了。
除此之外可以看到如果是自定義頭部圖片氣泡就沒有存在的意義了,因為會擋住圖片本身的內容,所以我們就做個調整,如果有自定義圖片就顯示一張圖片,如果沒有就按照原來的設計來。
- 修改布局,抽象出來樣式
/* 頭部大小 */
.head {
width: 750rpx;
height: 540rpx;
}
/* 頭部背景 */
.head-bg {
background-image: url('https://6465-demo-3gf9i3wu06a03ab1-1306451997.tcb.qcloud.la/head_bg.png');
background-size: 100% 100%;
}
- 具體布局結構變化,通過topImgUrl這個參數來控制顯示隱藏
<!-- 頭部 -->
<image wx:if="{{fileID}}" src="{{fileID}}" class="head"></image>
<view wx:if="{{! fileID}}" class="head head-bg" >
<view bindtap="randomMsg" class="head-bubble">
<!-- 頭像 -->
<view class="user-avatar">
<open-data type="userAvatarUrl"></open-data>
</view>
<!-- 問候語 -->
<text>,{{message}}</text>
</view>
<image bindtap="chooseImg" class="img-add" src="../../images/img_add.png" />
</view>
- 上傳圖片完整代碼
chooseImg: function () {
const that = this
// 選擇圖片
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
const filePath = res.tempFilePaths[0] //上傳第一張圖片
const cloudPath = `top-img/${Date.now()}-${Math.floor(Math.random(0, 1) * 100000)}` + filePath.match(/.[^.]+?$/)[0]
// 上傳圖片
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
// 設置文件ID
that.setData({
fileID: res.fileID
})
}
})
}
})
},
雖然效果以及達到了,但是這樣還是有個問題就是下次進來還是顯示默認的圖片,數據沒有保存下來,所以這個時候要用到我們學到的數據庫操作,如果將背景數據進行在云端數據庫管理?
背景圖片管理
別小看這個功能,這個功能雖然在之前我們已經實現了小程序端的業務,但是在數據邏輯處理,還是有些東西需要思考全面的。
按照慣例,先分析具體實現思路:
- 新建背景集合存放背景信息
- 保存背景的時候需添加記錄
- 替換背景時候需刪除再新增
- 刪除背景時同時需刪除圖片
- 用戶進入查詢背景數據顯示
以上所使用到的只是都是在之前分享內容學習過的內容,本次用同樣的知識來實現下不一樣的業務,相當于對大家之前知識的一個鞏固復習的過程,加強大家對這些知識點的印象。
新建數據集合
用于存放背景圖片信息
新建一個叫做 background 存放管理背景數據,然后我們看下權限:
因為實際業務需求中,這個背景只是當前用戶可以看到,所以默認的權限就適合我們當前的業務,不需要再做調整。
定義操作接口
小程序端需要操作 background 數據庫,所以我們在 api 文件夾在創建一個 background.js 來寫相關的數據庫操作方法。
// 獲取背景
function getBackground() {
}
// 添加背景
function addBackground(data)
}
// 刪除背景
function delBackground(id) {
}
// 導出聲明
export {
getBackground,
addBackground,
delBackground
}
根據實際的需求,分貝定義來獲取背景、添加背景、刪除背景,然后為了讓其他js能引入使用,在最后做了一個導出聲明。
保存上傳背景
首先實現下添加數據的方法
// 添加背景
function addBackground(data) {
// 1. 獲取數據庫引用
const db = wx.cloud.database()
// 2. 找到集合獲取數據
const background = db.collection('background')
// 3. 添加創建時間
data.createTime = db.serverDate()
// 4. 集合添加數據
return background.add({data})
}
在這個我給大家做了一個小小的加餐,使用了 serverDate 獲取服務端時間,可用于查詢條件、更新字段值或新增記錄時的字段值。
serverDate 參數說明:
- offset:單位毫米,可以設置時間偏移量
然后再到列表頁面去進行使用,先引入文件方法:
添加到 list.js 頭部
import {
addBackground
} from '../../api/background.js'
在選擇完圖片上傳完成之后,使用添加方法:
chooseImg: function () {
const that = this
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
const filePath = res.tempFilePaths[0] //上傳第一張圖片
const cloudPath = `top-img/${Date.now()}-${Math.floor(Math.random(0, 1) * 100000)}` + filePath.match(/.[^.]+?$/)[0]
console.log(cloudPath)
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
let data = {
fileID: res.fileID
}
that.setData(data)
addBackground(data)
}
})
}
})
},
經過添加操作后,數據被添加到了數據庫:
我們可以編輯下 createTime 字段:
可以看到這個是一個時間類型的字段參數。
添加完成之后還需要做兩件事情:
- 進入的時候去查詢背景信息
- 替換背景時候先刪除再添加
查詢背景信息
首先實現查詢數據方法:
// 獲取背景
function getBackground() {
// 1. 獲取數據庫引用
const db = wx.cloud.database()
// 2. 找到集合獲取數據
const background = db.collection('background')
// 3. 查詢集合數據
return background.get()
}
在 list.js 引入查詢方法:
import {
addBackground,
getBackground
} from '../../api/background.js'在 onLoad 進行查詢調用:
在 onLoad 進行查詢調用:
/**
* 生命周期函數--監聽頁面加載
*/
onLoad: function (options) {
// 獲取背景圖
this.getBackground()
// 獲取問候語
this.randomMsg()
},
// 獲取背景圖
getBackground(){
getBackground().then(res => {
// 判斷是否有數據
if (res.data.length) {
this.setData({
fileID:res.data[0].fileID // 獲取第一條數據
})
}
})
}
當用戶進入列表頁面就會顯示顯示已上傳的背景。
替換背景信息
這里需要采用先刪除后添加的方式,當然也可以采用修改的方式進行實現。在這里需要注意,無論采用什么方式都需要對之前背景文件進行刪除,無用的圖片就需要及時清理掉,要不然就會白白的占用服務器資源,存儲資源是需要收費。雖然存儲費用不貴,但是要保持一個良好的節約習慣。
先實現刪除方法:
// 刪除背景數據同時刪除背景圖片
function delBackground(id,fileID) {
// 1. 獲取數據庫引用
const db = wx.cloud.database()
// 2. 獲取集合對象
const background = db.collection('background')
// 3. 刪除背景圖片
wx.cloud.deleteFile({
fileList: [fileID]
})
// 4. 刪除當條背景數據
return background.doc(id).remove()
}
在 lis.js 引入刪除方法:
import {
addBackground,
getBackground,
delBackground
} from '../../api/background.js'
在這里因為刪除需要id,所以在獲取的背景的時候需要保存id
getBackground(){
getBackground().then(res => {
if (res.data.length) {
const background = res.data[0]
this.data.background = background
this.setData({
fileID:background.fileID
})
}
})
}
然后在選擇圖片的邏輯中判斷是否有id,如果有的話證明之前上傳過圖片則進行刪除操作
chooseImg: function () {
const that = this
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
const filePath = res.tempFilePaths[0] //上傳第一張圖片
const cloudPath = `top-img/${Date.now()}-${Math.floor(Math.random(0, 1) * 100000)}` + filePath.match(/.[^.]+?$/)[0]
console.log(cloudPath)
wx.cloud.uploadFile({
cloudPath,
filePath,
success: res => {
let data = {
fileID: res.fileID
}
that.setData(data)
addBackground(data)
// 判斷是否之前上傳過圖片
if(that.data.background){
let id = that.data.background._id
let fileID = that.data.background.fileID
delBackground(id,fileID)
}
}
})
}
})
}
JS邏輯處理代碼寫完,意外發現上傳完圖片后居然發現拍照的ICON不見了,后來查看布局代碼發現原來拍照ICON在未上傳圖片狀態布局的里面,所以一并沒隱藏了,我們需要把布局移除來。
<!-- 頭部 -->
<image wx:if="{{fileID}}" src="{{fileID}}" class="head"></image>
<view wx:if="{{!fileID}}" class="head head-bg" >
<view bindtap="randomMsg" class="head-bubble">
<!-- 頭像 -->
<view class="user-avatar">
<open-data type="userAvatarUrl"></open-data>
</view>
<!-- 問候語 -->
<text>,{{message}}</text>
</view>
<!-- 原來的位置 -->
<!-- <image bindtap="chooseImg" class="img-add" src="../../images/img_add.png" /> -->
</view>
<image bindtap="chooseImg" class="img-add" src="../../images/img_add.png" />
大功告成!碼仔內心竊喜,于是偷偷的換上了一張它和碼妞的合影。碼仔前后想了想“這個功能,還是很有必要的!”。
總結
- 學習了小程序圖片操作:wx.chooseImage() ,選擇圖片
- 小程序圖片云存儲管理:
- wx.cloud.uploadFile:上傳文件
- wx.cloud.deleteFile :刪除文件
- wx.cloud.getTempFileURL:獲取在線鏈接
- 還對之前的學習過的數據庫:新增、查詢、刪除操作通過實現一個需求進行了組合使用