本页目录

承接上文,在常用选项中,图片上传和选择功能用的较多,本节来实现这一功能,我们着重讨论功能实现,更多美化样式以及优化性能问题,可自行探索。此处为了便于大家理解,代码言简意赅。
预览
需求如下
-
提供一个图片上传按钮
-
可展示选中的图片
-
提供清空图片按钮
流程如下

效果如下

修改 index.js
存储图片链接值
我们添加键 dataImage 用于存储选中图片的链接
//存储选项值 const datas = Vue.reactive({ dataImage: "", });在获取选项数据时进行赋值,这里,我修改了原来的函数名为 get_option ,更加简洁易懂。
//获取数据 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("连接服务器失败或后台读取出错!数据读取失败"); 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 = ""; };添加展示模版
为了模版可以拿到对应的功能,记得将需要的功能函数返回出来。
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/>此时刷新页面,尝试选择图片并保存,即可看到我们完成了图片上传功能,清理按钮也能正常工作,记得修改选项后点击保存按钮。
选择媒体库文件
修改 index.js 文件
流程
-
创建函数,通过 REST API 从 WordPress 媒体库中获取图片数据
-
vue 将获取的图片数据展示在前端,并提供选择按钮
-
选中图片后,将值传给选项值
-
保存
效果

创建变量
我们创建变量用于存储获取的图片信息,为了便于扩展,这里使用 reactive
//存储获取的值 const getData = Vue.reactive({ //存储获取的媒体库值 mediaList: [], });添加新选项
//存储选项值 const datas = Vue.reactive({ //省略 dataSelectedImage: "", });获取数据也得加上
//获取数据 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("连接服务器失败或后台读取出错!数据读取失败"); console.log(error); }); };获取媒体库图片
通过以下函数获取图片信息并存储信息进键 mediaList 中
//获取媒体库图片 const getMediaList = () => { axios .get(dataLocal.route + "wp/v2/media") .then((response) => { getData.mediaList = response.data; }) .catch((error) => { console.error(error); }); };选择媒体库图片
添加以下代码进行选择
//从媒体库选中图片 const selectImage = (imageUrl) => { datas.dataSelectedImage = imageUrl; };添加模版
将模版用的数据进行导出
return { datas, siteData, update_option, update_img, clear_img, selectImage, getMediaList, getData, };添加模版内容
<button @click="getMediaList">获取媒体库图片</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/>获取选项值
在 php 中,可通过以下方法获取选项值
echo "<br/>"; echo get_option('dataImage'); echo "<br/>"; echo get_option('dataSelectedImage');改进
上述代码还有很多改进空间,此处为便于演示以及篇幅原因,仅叙于此。
以下是几个可以优化的点
-
选中图片后无需上传至 WordPress 即可预览,点击保存按钮后再上传图片,
-
若图片选项有值,则使用上传后的图片链接进行图片预览
-
优化清理按钮,或做成组件,可复用
本地图片预览功能
const datas = Vue.reactive({ dataImage: "", });
const update_img = (event) => { const file = event.target.files[0]; const formData = new FormData();
//预览图片 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() { //存储传来的值 const siteData = dataLocal.data;
//存储获取的值 const getData = Vue.reactive({ //存储获取的媒体库值 mediaList: [], });
//存储选项值 const datas = Vue.reactive({ dataOne: "", dataTwo: "", dataName: [], dataImage: "", dataSelectedImage: "", });
//获取数据 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("连接服务器失败或后台读取出错!数据读取失败"); console.log(error); }); };
//保存数据 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 = ""; };
//获取媒体库图片 const getMediaList = () => { axios .get(dataLocal.route + "wp/v2/media") .then((response) => { getData.mediaList = response.data; }) .catch((error) => { console.error(error); }); };
//从媒体库选中图片 const selectImage = (imageUrl) => { datas.dataSelectedImage = imageUrl; };
//页面初始加载 Vue.onMounted(() => { //获取选项值 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/>
用户选择:<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)按键即可进行多选<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">获取媒体库图片</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");总结
本节我们学习了从本地上传图片和从媒体库选择图片。
代码部分比较乱,尤其是模版部分,这些都会在后续的打包中进行解决的。
能坚持到这里,你已经很棒了,相信到这里,你已经掌握了复选框,布尔值,单选框,多选框等内容,我就不再过多赘述了。
下一节,我们将使用 Vite 对现有 JS 文件进行打包,并使用一些基础的 CSS 样式对现有选项进行外观美化,并进一步研究数据校验问题。