承接上文,在常用選項(xiàng)中,圖片上傳和選擇功能用的較多,本節(jié)來(lái)實(shí)現(xiàn)這一功能,我們著重討論功能實(shí)現(xiàn),更多美化樣式以及優(yōu)化性能問(wèn)題,可自行探索。此處為了便于大家理解,代碼言簡(jiǎn)意賅。
預(yù)覽
需求如下
- 提供一個(gè)圖片上傳按鈕
- 可展示選中的圖片
- 提供清空?qǐng)D片按鈕
流程如下

效果如下

修改 index.js
存儲(chǔ)圖片鏈接值
我們添加鍵 dataImage
用于存儲(chǔ)選中圖片的鏈接
//存儲(chǔ)選項(xiàng)值
const datas = Vue.reactive({
dataImage: "",
});
在獲取選項(xiàng)數(shù)據(jù)時(shí)進(jìn)行賦值,這里,我修改了原來(lái)的函數(shù)名為 get_option
,更加簡(jiǎn)潔易懂。
//獲取數(shù)據(jù)
const get_option = () => {
axios
.post(dataLocal.route + "pf/v1/get_option", datas, {
headers: {
"X-WP-Nonce": dataLocal.nonce,
"Content-Type": "application/json",
},
})
.then((response) => {
//省略
datas.dataImage = data.dataImage;
})
.catch((error) => {
window.alert("連接服務(wù)器失敗或后臺(tái)讀取出錯(cuò)!數(shù)據(jù)讀取失敗");
console.log(error);
});
};
添加圖片上傳功能
我們通過(guò)以下兩個(gè)函數(shù),實(shí)現(xiàn)圖片上傳功能
//上傳圖片
const upload_img = (file) => {
const formData = new FormData();
formData.append("file", file);
return axios
.post(dataLocal.route + "wp/v2/media", formData, {
headers: {
"X-WP-Nonce": dataLocal.nonce,
"Content-Type": "multipart/form-data",
},
})
.then((response) => {
// 圖片上傳成功后的處理邏輯
const data = response.data;
//返回圖片URL
return data.source_url;
})
.catch((error) => {
console.error(error);
// 圖片上傳失敗后的處理邏輯
});
};
//處理圖片上傳事件
const update_img = (event) => {
const file = event.target.files[0];
upload_img(file).then((url) => {
//將拿到的圖片URL傳給圖片變量
datas.dataImage = url;
});
};
添加清空功能
添加以下代碼,實(shí)現(xiàn)清空功能
//清空選擇圖片
const clear_img = () => {
datas.dataImage = "";
};
添加展示模版
為了模版可以拿到對(duì)應(yīng)的功能,記得將需要的功能函數(shù)返回出來(lái)。
return {
datas,
siteData,
update_option,
update_img,
clear_img,
};
模版代碼如下
<input type="file" @change.native="update_img"><br/>
<button type="button" @click="clear_img">清理</button><br/>
<img style="width: 300px;height: auto;" :src=datas.dataImage v-if =datas.dataImage ><hr/>
此時(shí)刷新頁(yè)面,嘗試選擇圖片并保存,即可看到我們完成了圖片上傳功能,清理按鈕也能正常工作,記得修改選項(xiàng)后點(diǎn)擊保存按鈕。
選擇媒體庫(kù)文件
修改 index.js 文件
流程
- 創(chuàng)建函數(shù),通過(guò)REST API 從WordPress 媒體庫(kù)中獲取圖片數(shù)據(jù)
- vue將獲取的圖片數(shù)據(jù)展示在前端,并提供選擇按鈕
- 選中圖片后,將值傳給選項(xiàng)值
- 保存
效果

創(chuàng)建變量
我們創(chuàng)建變量用于存儲(chǔ)獲取的圖片信息,為了便于擴(kuò)展,這里使用reactive
//存儲(chǔ)獲取的值
const getData = Vue.reactive({
//存儲(chǔ)獲取的媒體庫(kù)值
mediaList: [],
});
添加新選項(xiàng)
//存儲(chǔ)選項(xiàng)值
const datas = Vue.reactive({
//省略
dataSelectedImage: "",
});
獲取數(shù)據(jù)也得加上
//獲取數(shù)據(jù)
const get_option = () => {
axios
.post(dataLocal.route + "pf/v1/get_option", datas, {
headers: {
"X-WP-Nonce": dataLocal.nonce,
"Content-Type": "application/json",
},
})
.then((response) => {
//省略
datas.dataSelectedImage = data.dataSelectedImage;
})
.catch((error) => {
window.alert("連接服務(wù)器失敗或后臺(tái)讀取出錯(cuò)!數(shù)據(jù)讀取失敗");
console.log(error);
});
};
獲取媒體庫(kù)圖片
通過(guò)以下函數(shù)獲取圖片信息并存儲(chǔ)信息進(jìn)鍵 mediaList
中
//獲取媒體庫(kù)圖片
const getMediaList = () => {
axios
.get(dataLocal.route + "wp/v2/media")
.then((response) => {
getData.mediaList = response.data;
})
.catch((error) => {
console.error(error);
});
};
選擇媒體庫(kù)圖片
添加以下代碼進(jìn)行選擇
//從媒體庫(kù)選中圖片
const selectImage = (imageUrl) => {
datas.dataSelectedImage = imageUrl;
};
添加模版
將模版用的數(shù)據(jù)進(jìn)行導(dǎo)出
return {
datas,
siteData,
update_option,
update_img,
clear_img,
selectImage,
getMediaList,
getData,
};
添加模版內(nèi)容
<button @click="getMediaList">獲取媒體庫(kù)圖片</button>
<div style="max-width: 800px;;display: flex; margin: 1em 0;">
<div v-for="media in getData.mediaList" :key="media.id" style="float: left;">
<img :src="media.source_url" style="max-width: 150px; height: auto;vertical-align: top; ">
<button @click="selectImage(media.source_url)">選擇</button>
</div>
</div>
<h2>{{datas.dataSelectedImage ? "已" : "未"}}選擇圖片</h2>
<img :src="datas.dataSelectedImage" v-if="datas.dataSelectedImage" style="width: 150px;height: auto;"><hr/>
獲取選項(xiàng)值
在php 中,可通過(guò)以下方法獲取選項(xiàng)值
echo "<br/>";
echo get_option('dataImage');
echo "<br/>";
echo get_option('dataSelectedImage');
改進(jìn)
上述代碼還有很多改進(jìn)空間,此處為便于演示以及篇幅原因,僅敘于此。
以下是幾個(gè)可以?xún)?yōu)化的點(diǎn)
- 選中圖片后無(wú)需上傳至WordPress即可預(yù)覽,點(diǎn)擊保存按鈕后再上傳圖片,
- 若圖片選項(xiàng)有值,則使用上傳后的圖片鏈接進(jìn)行圖片預(yù)覽
- 優(yōu)化清理按鈕,或做成組件,可復(fù)用
本地圖片預(yù)覽功能
const datas = Vue.reactive({
dataImage: "",
});
const update_img = (event) => {
const file = event.target.files[0];
const formData = new FormData();
//預(yù)覽圖片
datas.dataImage = URL.createObjectURL(file);
}
<input type="file" @change.native="update_img"><br/>
<img style="width: 300px;height: auto;" :src=datas.dataImage ><hr/>
完整代碼
//vite/dist/index.js
//console.log(dataLocal.route);
//console.log(dataLocal.data.user);
const App = {
setup() {
//存儲(chǔ)傳來(lái)的值
const siteData = dataLocal.data;
//存儲(chǔ)獲取的值
const getData = Vue.reactive({
//存儲(chǔ)獲取的媒體庫(kù)值
mediaList: [],
});
//存儲(chǔ)選項(xiàng)值
const datas = Vue.reactive({
dataOne: "",
dataTwo: "",
dataName: [],
dataImage: "",
dataSelectedImage: "",
});
//獲取數(shù)據(jù)
const get_option = () => {
axios
.post(dataLocal.route + "pf/v1/get_option", datas, {
headers: {
"X-WP-Nonce": dataLocal.nonce,
"Content-Type": "application/json",
},
})
.then((response) => {
const data = response.data;
datas.dataOne = data.dataOne;
datas.dataTwo = data.dataTwo;
datas.dataName = data.dataName;
datas.dataImage = data.dataImage;
datas.dataSelectedImage = data.dataSelectedImage;
})
.catch((error) => {
window.alert("連接服務(wù)器失敗或后臺(tái)讀取出錯(cuò)!數(shù)據(jù)讀取失敗");
console.log(error);
});
};
//保存數(shù)據(jù)
const update_option = () => {
console.log(datas);
axios
.post(dataLocal.route + "pf/v1/update_option", datas, {
headers: {
"X-WP-Nonce": dataLocal.nonce,
},
})
.then((response) => {
alert("保存成功");
})
.catch((error) => {
alert("保存失敗");
console.log(error);
});
};
//上傳圖片
const upload_img = (file) => {
const formData = new FormData();
formData.append("file", file);
return axios
.post(dataLocal.route + "wp/v2/media", formData, {
headers: {
"X-WP-Nonce": dataLocal.nonce,
"Content-Type": "multipart/form-data",
},
})
.then((response) => {
// 圖片上傳成功后的處理邏輯
const data = response.data;
//返回圖片URL
return data.source_url;
})
.catch((error) => {
console.error(error);
// 圖片上傳失敗后的處理邏輯
});
};
//處理圖片上傳事件
const update_img = (event) => {
const file = event.target.files[0];
upload_img(file).then((url) => {
//將拿到的圖片URL傳給圖片變量
datas.dataImage = url;
});
};
//清空選擇圖片
const clear_img = () => {
datas.dataImage = "";
};
//獲取媒體庫(kù)圖片
const getMediaList = () => {
axios
.get(dataLocal.route + "wp/v2/media")
.then((response) => {
getData.mediaList = response.data;
})
.catch((error) => {
console.error(error);
});
};
//從媒體庫(kù)選中圖片
const selectImage = (imageUrl) => {
datas.dataSelectedImage = imageUrl;
};
//頁(yè)面初始加載
Vue.onMounted(() => {
//獲取選項(xiàng)值
get_option();
});
return {
datas,
siteData,
update_option,
update_img,
clear_img,
selectImage,
getMediaList,
getData,
};
},
template: `
文本框1:<input type="text" v-model="datas.dataOne"><br/>
文本框2:<input type="text" v-model="datas.dataTwo"><hr/>
用戶(hù)選擇:<select v-model="datas.dataName" multiple>
<option v-for="option in siteData.user" :key="option.id" :value="option.id">
{{ option.name }}
</option>
</select>
<p>你選擇了:{{ datas.dataName }}</p><br/>
按住command(control)按鍵即可進(jìn)行多選<hr/>
<input type="file" @change.native="update_img"><br/>
<button type="button" @click="clear_img">清理</button><br/>
<img style="width: 300px;height: auto;" :src=datas.dataImage v-if =datas.dataImage ><hr/>
<button @click="getMediaList">獲取媒體庫(kù)圖片</button>
<div style="max-width: 800px;;display: flex; margin: 1em 0;">
<div v-for="media in getData.mediaList" :key="media.id" style="float: left;">
<img :src="media.source_url" style="max-width: 150px; height: auto;vertical-align: top; ">
<button @click="selectImage(media.source_url)">選擇</button>
</div>
</div>
<h2>{{datas.dataSelectedImage ? "已" : "未"}}選擇圖片</h2>
<img :src="datas.dataSelectedImage" v-if="datas.dataSelectedImage" style="width: 150px;height: auto;"><hr/>
<button class="button button-primary" @click="update_option">保存</button>`,
};
Vue.createApp(App).mount("#vuespa");
總結(jié)
本節(jié)我們學(xué)習(xí)了從本地上傳圖片和從媒體庫(kù)選擇圖片。
代碼部分比較亂,尤其是模版部分,這些都會(huì)在后續(xù)的打包中進(jìn)行解決的。
能堅(jiān)持到這里,你已經(jīng)很棒了,相信到這里,你已經(jīng)掌握了復(fù)選框,布爾值,單選框,多選框等內(nèi)容,我就不再過(guò)多贅述了。
下一節(jié),我們將使用Vite對(duì)現(xiàn)有 JS 文件進(jìn)行打包,并使用一些基礎(chǔ)的CSS樣式對(duì)現(xiàn)有選項(xiàng)進(jìn)行外觀(guān)美化,并進(jìn)一步研究數(shù)據(jù)校驗(yàn)問(wèn)題。