??前言
這篇文章是本專欄 uni-app 的項(xiàng)目實(shí)戰(zhàn)篇,主要內(nèi)容的是模擬前端通過(guò)調(diào)用接口,然后獲取到數(shù)據(jù)圖片的路徑數(shù)據(jù),然后授權(quán)相冊(cè),最后把圖片保存到本地(相冊(cè))。
?關(guān)于專欄
本專欄主要是分享和介紹從零到一學(xué)習(xí)和使用的 uni-app 的筆記和個(gè)人經(jīng)驗(yàn)。通過(guò)個(gè)人的學(xué)習(xí)經(jīng)驗(yàn)和工作經(jīng)驗(yàn)來(lái)給大家分享關(guān)于 uni-app 開(kāi)發(fā)的技巧,以及快速入門(mén)的訣竅等等。
專欄主頁(yè):uni-app_黛琳ghz的博客-CSDN博客
??需求描述
案例場(chǎng)景:用戶通過(guò)點(diǎn)擊某個(gè)按鈕可以把圖片保存到相冊(cè),比如說(shuō)含有二維碼的名片圖片、海報(bào)圖片等等。
需求分析:這里以分享海報(bào)的需求為例子,用戶點(diǎn)擊分享海報(bào),然后后臺(tái)生成含二維碼、海報(bào)內(nèi)容的圖片,前端通過(guò)調(diào)用此接口獲取到圖片的路徑信息(路徑后端拼接好返回),然后用戶點(diǎn)擊按鈕,然后先授權(quán)相冊(cè),最后再保存圖片到相冊(cè)。(可以參考下圖的原型圖,僅供參考)
??前置知識(shí)點(diǎn)
在編寫(xiě)代碼之前,我們先熟悉一下本次實(shí)戰(zhàn)所需用到的一些知識(shí)點(diǎn)和 uni-app 的內(nèi)置 API。
??uni.showLoading()
uni.showLoading() 是 uni-app 框架提供的一個(gè) API ,用于顯示加載提示框。它的作用是在頁(yè)面上展示一個(gè)加載中的提示框,告知用戶當(dāng)前正在進(jìn)行一些耗時(shí)的操作,比如加載數(shù)據(jù)或進(jìn)行網(wǎng)絡(luò)請(qǐng)求。
uni.showLoading() 方法接受一個(gè)對(duì)象參數(shù),可以包含以下屬性:
- title(可選):加載提示框的標(biāo)題文本,默認(rèn)為"加載中"。
- mask(可選):是否顯示透明蒙層,防止用戶在加載過(guò)程中進(jìn)行其他操作,默認(rèn)值為true,表示顯示蒙層。
調(diào)用 uni.showLoading() 方法后,加載提示框會(huì)顯示在頁(yè)面上,直到調(diào)用uni.hideLoading() 方法或者一段時(shí)間后自動(dòng)消失。示例代碼:
uni.showLoading({
title: '加載中',
mask: true
});
在上述示例中,uni.showLoading() 方法被調(diào)用,顯示一個(gè)標(biāo)題為"加載中"的加載提示框,并且顯示透明蒙層。當(dāng)加載完成后,應(yīng)該調(diào)用 uni.hideLoading() 來(lái)隱藏加載提示框。
??uni.authorize()
uni.authorize() 是 uni-app 框架提供的一個(gè) API ,用于請(qǐng)求用戶授權(quán)。它的作用是向用戶申請(qǐng)獲得指定的授權(quán)權(quán)限,比如獲取用戶的地理位置、相機(jī)、相冊(cè)等權(quán)限。
uni.authorize() 方法接受一個(gè)對(duì)象參數(shù),可以包含以下屬性:
- scope:要申請(qǐng)的授權(quán)權(quán)限的標(biāo)識(shí)符。不同的授權(quán)權(quán)限有不同的標(biāo)識(shí)符,例如獲取用戶信息的標(biāo)識(shí)符為 scope.userInfo,獲取用戶相冊(cè)的標(biāo)識(shí)符為 scope.writePhotosAlbum。
- success(可選):授權(quán)成功時(shí)執(zhí)行的回調(diào)函數(shù)。
- fail(可選):授權(quán)失敗時(shí)執(zhí)行的回調(diào)函數(shù)。
在調(diào)用 uni.authorize() 方法時(shí),會(huì)向用戶展示一個(gè)授權(quán)對(duì)話框,詢問(wèn)用戶是否允許獲取指定的權(quán)限。如果用戶同意授權(quán),則執(zhí)行 success 回調(diào)函數(shù);如果用戶拒絕授權(quán)或授權(quán)失敗,則執(zhí)行 fail 回調(diào)函數(shù)。示例代碼:
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
// 授權(quán)成功時(shí)的操作
// 可以在這里進(jìn)行保存圖片等操作
},
fail: () => {
// 授權(quán)失敗時(shí)的操作
// 可以給用戶提示授權(quán)失敗的信息
}
});
在上述示例中,uni.authorize() 方法被調(diào)用,申請(qǐng)獲取寫(xiě)入用戶相冊(cè)的權(quán)限。如果用戶同意授權(quán),則執(zhí)行 success 回調(diào)函數(shù);如果用戶拒絕授權(quán)或授權(quán)失敗,則執(zhí)行 fail 回調(diào)函數(shù)。通常在 success 回調(diào)函數(shù)中進(jìn)行后續(xù)的操作,比如保存圖片到相冊(cè)等操作。
??uni.downloadFile()
uni.downloadFile() 是 uni-app 框架提供的一個(gè)API,用于下載文件。它的作用是通過(guò)網(wǎng)絡(luò)請(qǐng)求下載文件,可以是圖片、音頻、視頻等內(nèi)容。
uni.downloadFile() 方法接受一個(gè)對(duì)象參數(shù),可以包含以下屬性:
- url:要下載的文件的遠(yuǎn)程地址。
- success(可選):文件下載成功時(shí)執(zhí)行的回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)中包含了本地臨時(shí)文件路徑 tempFilePath。
- fail(可選):文件下載失敗時(shí)執(zhí)行的回調(diào)函數(shù)。
在調(diào)用 uni.downloadFile() 方法時(shí),uni-app 將發(fā)送請(qǐng)求去下載指定的文件,并將文件保存在本地臨時(shí)路徑中。如果文件下載成功,則執(zhí)行 success 回調(diào)函數(shù)并傳遞本地臨時(shí)文件路徑作為參數(shù);如果文件下載失敗,則執(zhí)行 fail 回調(diào)函數(shù)。示例代碼:
uni.downloadFile({
url: 'https://example.com/image.jpg',
success: res => {
// 文件下載成功時(shí)的操作
// 可以使用 res.tempFilePath 獲取本地臨時(shí)文件路徑
},
fail: err => {
// 文件下載失敗時(shí)的操作
// 可以給用戶提示下載失敗的信息
}
});
在上述示例中,uni.downloadFile() 方法被調(diào)用以下載名為 “image.jpg” 的圖片文件。如果文件下載成功,則執(zhí)行 success 回調(diào)函數(shù)并使用 res.tempFilePath 獲取本地臨時(shí)文件的路徑;如果文件下載失敗,則執(zhí)行 fail 回調(diào)函數(shù)。你可以根據(jù)需求在 success 回調(diào)函數(shù)中進(jìn)行后續(xù)的操作,比如將文件顯示在頁(yè)面上或保存到相冊(cè)等。
??uni.saveImageToPhotosAlbum()
uni.saveImageToPhotosAlbum() 是 uni-app 框架提供的一個(gè)API,用于將圖片保存到用戶的相冊(cè)。它的作用是將指定路徑的圖片保存到用戶的相冊(cè)中。
uni.saveImageToPhotosAlbum() 方法接受一個(gè)對(duì)象參數(shù),可以包含以下屬性:
- filePath:要保存到相冊(cè)的圖片文件路徑。
- success(可選):保存成功時(shí)執(zhí)行的回調(diào)函數(shù)。
- fail(可選):保存失敗時(shí)執(zhí)行的回調(diào)函數(shù)。
在調(diào)用 uni.saveImageToPhotosAlbum() 方法時(shí),uni-app 將嘗試將指定路徑的圖片保存到用戶的相冊(cè)中。如果保存成功,則執(zhí)行 success 回調(diào)函數(shù);如果保存失敗,則執(zhí)行 fail 回調(diào)函數(shù)。示例代碼:
uni.saveImageToPhotosAlbum({
filePath: 'path/to/image.jpg',
success: () => {
// 保存成功時(shí)的操作
// 可以給用戶提示保存成功的信息
},
fail: () => {
// 保存失敗時(shí)的操作
// 可以給用戶提示保存失敗的信息
}
});
在上述示例中,uni.saveImageToPhotosAlbum() 方法被調(diào)用以將指定路徑的 “image.jpg” 圖片保存到用戶的相冊(cè)中。如果保存成功,則執(zhí)行 success 回調(diào)函數(shù);如果保存失敗,則執(zhí)行 fail 回調(diào)函數(shù)。你可以根據(jù)需求在回調(diào)函數(shù)中給用戶提示保存成功或失敗的信息。請(qǐng)確保傳入的 filePath 參數(shù)是正確的本地文件路徑。
??演示代碼
這個(gè)演示代碼延用之前項(xiàng)目 (具體看該專欄的文章《uni-app 經(jīng)驗(yàn)分享,從入門(mén)到離職(二)—— tabBar 底部導(dǎo)航欄實(shí)戰(zhàn)基礎(chǔ)篇》) 的代碼頁(yè)面,如下圖是簡(jiǎn)單的操作流程,以及簡(jiǎn)單的演示頁(yè)面。流程為點(diǎn)擊綠色的按鈕,然后出現(xiàn)加載中提示框,然后出現(xiàn)授權(quán)相冊(cè)的提示框,允許授權(quán)后,彈出另存為圖片的窗口表示圖片可以下載了,最后點(diǎn)擊保存即可。
下面是該項(xiàng)目頁(yè)面的完整代碼。
<template>
<view class="downloadbtn" @click="downloadimg">
點(diǎn)擊下載圖片
</view>
</template>
<script>
export default {
data() {
return {
img: ''
}
},
onLoad() {
},
methods: {
downloadimg() {
uni.showLoading({
title: '加載中',
mask: true,
});
uni.request({
url: 'http://127.0.0.1:3000/getImage',
method: 'GET',
header: {
'Content-Type': 'application/x-www-form-urlencoded',
},
success: res => {
// 請(qǐng)求成功時(shí)的操作
// console.log(res.data); // 打印返回的數(shù)據(jù)
console.log(res)
this.img = res.data.imagePath
this.saveToAlbum(this.img)
},
fail: err => {
// 請(qǐng)求失敗時(shí)的操作
console.error(err);
}
});
},
saveToAlbum(url) {
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
// 在授權(quán)成功后執(zhí)行保存圖片的操作
this.saveImage(url);
},
fail: () => {
uni.hideLoading()
uni.showModal({
// title: '授權(quán)失敗,請(qǐng)前往設(shè)置頁(yè)授權(quán)',
title: '授權(quán)失敗',
// icon: 'none',
content: '請(qǐng)前往設(shè)置頁(yè)手動(dòng)授權(quán)該權(quán)限',
showCancel: false,
confirmText: '去設(shè)置',
success: res => {
if (res.confirm) {
// 用戶點(diǎn)擊確定,跳轉(zhuǎn)到設(shè)置頁(yè)
uni.openSetting({
success: () => {
// 設(shè)置頁(yè)打開(kāi)成功后的操作
uni.hideLoading()
}
});
}
}
});
}
});
},
saveImage(url) {
uni.downloadFile({
url: url,
success: (res) => {
console.log(res)
// if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '保存失敗',
icon: 'none'
});
}
});
},
fail: () => {
uni.showToast({
title: '下載失敗',
icon: 'none'
});
}
});
},
}
}
</script>
<style>
.downloadbtn {
margin: 0 auto;
width: 300rpx;
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
background: #007e00 !important;
border-radius: 24px;
font-size: 14px;
margin-top: 12px;
color: #fff !important;
}
</style>
??關(guān)于圖片接口
原計(jì)劃是用網(wǎng)上的在線 API 接口來(lái)模擬從后臺(tái)獲取圖片,比如說(shuō)這個(gè)搏天 api 的隨機(jī)壁紙接口,如下圖的 https://api.btstu.cn/sjbz/api.php?lx=dongman&format=images 請(qǐng)求接口。
我們可以請(qǐng)求一下,看看返回的數(shù)據(jù)效果。
我們可以看到返回了一張壁紙,這張壁紙是在線的,后續(xù)我們會(huì)使用到。然后我們可以看到上面代碼中的請(qǐng)求接口并不是用到這個(gè)在線 API ,而是 http://127.0.0.1:3000/getImage 這個(gè)本地寫(xiě)的 Nodejs 接口。接下來(lái)我們看看為什么不用這個(gè)在線 API ,以及如何寫(xiě)這個(gè) Nodejs 接口。
首先看為什么不能用這個(gè)在線 API 的原因,我們?cè)陧?xiàng)目中請(qǐng)求看看,看看是否可以走完這個(gè)保存圖片到本地的流程。我們可以發(fā)現(xiàn)這個(gè)接口請(qǐng)求返回的參數(shù)出現(xiàn)了亂碼,而且在請(qǐng)求的響應(yīng)過(guò)程非常緩慢,而且出現(xiàn) 302 的情況 (當(dāng)服務(wù)器接收到請(qǐng)求后,可能會(huì)返回狀態(tài)碼為 302 的響應(yīng)。這意味著您發(fā)送的請(qǐng)求需要進(jìn)行臨時(shí)重定向。在 302 響應(yīng)中,服務(wù)器通常會(huì)在響應(yīng)頭中包含一個(gè)名為 “Location” 的字段,該字段指示了新的請(qǐng)求目標(biāo) URL。) ,接口是沒(méi)有問(wèn)題的,但是并不適用于這個(gè)頁(yè)面的保存圖片邏輯所需的圖片文件路徑。因此我們使用這個(gè)接口返回的圖片的在線地址作為這個(gè)項(xiàng)目返回的參數(shù),寫(xiě)一個(gè)本地的 Nodejs 服務(wù)。
接下來(lái)我們看看后臺(tái)的代碼,創(chuàng)建一個(gè)文件夾,然后新建一個(gè) js 文件,然后在此文件下安裝一個(gè) Express 框架,具體操作如下。
- 打開(kāi)命令行界面
- 在命令行界面中,進(jìn)入您要?jiǎng)?chuàng)建 Express 應(yīng)用程序的目錄。
- 輸入以下命令來(lái)初始化一個(gè)新的 Node.js 項(xiàng)目,并創(chuàng)建 package.json 文件:npm init
- 安裝 Express。在命令行界面中輸入以下命令:npm install express
通過(guò)上面的步驟就可以創(chuàng)建好初始的結(jié)構(gòu)了,然后是 js 代碼,下面是 js 文件的完整代碼。
const express = require('express');
const app = express();
// 定義接口路由
app.get('/getImage', (req, res) => {
// 處理請(qǐng)求邏輯,獲取圖片路徑或地址
const imagePath = 'https://img.btstu.cn/api/images/5ab5ea3775fb5.jpg'; // 根據(jù)實(shí)際情況替換為圖片的路徑或地址
// 返回圖片路徑或地址給前端
res.json({ imagePath });
});
// 定義獲取接口IP的路由
app.get('/getInterfaceIP', (req, res) => {
// 獲取服務(wù)器的IP地址
const interfaceIP = req.headers.host.split(':')[0];
// 返回接口IP給前端
res.json({ interfaceIP });
});
// 定義接口用例地址路由
app.get('/getExampleAddress', (req, res) => {
// 構(gòu)建接口用例地址
const exampleAddress = `http://${req.headers.host}/getImage`;
// 返回接口用例地址給前端
res.json({ exampleAddress });
});
// 啟動(dòng)服務(wù)器,監(jiān)聽(tīng)指定端口
const port = 3000; // 你可以根據(jù)需要修改端口號(hào)
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
最后通過(guò) node xxx.js 啟動(dòng)這個(gè)本地服務(wù),然后我們就可以去前端頁(yè)面調(diào)用這個(gè)接口了,然后實(shí)現(xiàn)保存圖片到本地的需求,接下來(lái)我們?nèi)L試一下,首先是啟動(dòng)本地服務(wù)。
然后我們?cè)谛〕绦蝽?yè)面測(cè)試一下是否可以成功下載到圖片。
最后點(diǎn)擊保存按鈕,即可保存成功,然后頁(yè)面返回保存成功的提示即完成了該需求的功能,形成閉環(huán)。
??代碼解析簡(jiǎn)述
關(guān)于這個(gè)項(xiàng)目的代碼簡(jiǎn)述,這里就不過(guò)多介紹前端代碼的邏輯了,因?yàn)樵陧?xiàng)目前置的知識(shí)點(diǎn)中已經(jīng)大致介紹了該項(xiàng)目所需用到的 API 和大概的邏輯思路了。所以這里就簡(jiǎn)單介紹一下 Nodejs 的代碼。
這段代碼使用了 Express 框架創(chuàng)建了一個(gè)簡(jiǎn)單的服務(wù)器,該服務(wù)器有三個(gè)接口路由:
- ‘/getImage’:返回圖片路徑或地址給前端;
- ‘/getInterfaceIP’:獲取服務(wù)器IP地址,并返回給前端;
- ‘/getExampleAddress’:構(gòu)建并返回 ‘/getImage’ 接口的完整請(qǐng)求地址給前端。
其中,對(duì)于每個(gè)路由,都通過(guò) app.get() 方法進(jìn)行定義,指定了請(qǐng)求方式為 GET 請(qǐng)求,并提供了相應(yīng)的處理邏輯和響應(yīng)。
最后,通過(guò) app.listen() 方法啟動(dòng)服務(wù)器并監(jiān)聽(tīng)指定的端口,以等待客戶端發(fā)起請(qǐng)求。在本例中,指定的端口號(hào)是 3000。
當(dāng)某個(gè)客戶端向服務(wù)器發(fā)起 GET 請(qǐng)求時(shí),如果請(qǐng)求路徑匹配了其中之一的路由,則相應(yīng)的處理邏輯會(huì)被執(zhí)行,并向客戶端返回相應(yīng)的響應(yīng)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-713215.html
??最后
到此就是本篇文章的全部?jī)?nèi)容了,這篇文章記錄的主要內(nèi)容的是模擬前端通過(guò)調(diào)用接口,然后獲取到數(shù)據(jù)圖片的路徑數(shù)據(jù),然后授權(quán)相冊(cè),最后把圖片保存到本地(相冊(cè))的項(xiàng)目實(shí)戰(zhàn)。這篇文章是博主 uni-app 專欄的實(shí)戰(zhàn)篇的文章,后續(xù)會(huì)不斷的更新更多關(guān)于 uni-app 的干貨、實(shí)戰(zhàn)經(jīng)驗(yàn)、學(xué)習(xí)經(jīng)驗(yàn),期待你的關(guān)注和留言。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-713215.html
到了這里,關(guān)于uni-app 經(jīng)驗(yàn)分享,從入門(mén)到離職(實(shí)戰(zhàn)篇)——模擬從后臺(tái)獲取圖片路徑數(shù)據(jù)后授權(quán)相冊(cè)以及保存圖片到本地(手機(jī)相冊(cè))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!