第四节:Vue3 开发WordPress设置选项 - 添加图片上传功能

本节实现了从本地上传图片至WordPress媒体库和从媒体库中选择图片的功能,并进一步探究了后续文章发展节奏

承接上文,在常用选项中,图片上传和选择功能用的较多,本节来实现这一功能,我们着重讨论功能实现,更多美化样式以及优化性能问题,可自行探索。此处为了便于大家理解,代码言简意赅。

预览

需求如下

  • 提供一个图片上传按钮
  • 可展示选中的图片
  • 提供清空图片按钮

流程如下

第四节:Vue3 开发WordPress设置选项 - 添加图片上传功能

效果如下

第四节:Vue3 开发WordPress设置选项 - 添加图片上传功能

修改 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将获取的图片数据展示在前端,并提供选择按钮
  • 选中图片后,将值传给选项值
  • 保存

效果

第四节:Vue3 开发WordPress设置选项 - 添加图片上传功能

创建变量

我们创建变量用于存储获取的图片信息,为了便于扩展,这里使用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样式对现有选项进行外观美化,并进一步研究数据校验问题。

教程

第三节:Vue3 开发WordPress设置选项 - 从筛选功能研究前后台数据交互

2023-6-27 23:21:00

教程

00:讲透WordPress 菜单开发 - 添加菜单和子菜单

2023-6-28 22:20:00

⚠️
Npcink上的部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。
无意侵害您的权益,请发送邮件至 1355471563#qq.com 或点击右侧 私信:Muze 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索