Day15 - 产品编辑 modal 还丑但功能 OK 了

https://ithelp.ithome.com.tw/upload/images/20210929/20140513r87Ukndov0.png

<template>
  <!-- Button trigger modal -->
  <button
    type="button"
    class="btn btn-primary"
    data-bs-toggle="modal"
    data-bs-target="#exampleModal"
  >
    按这边
  </button>

  <!-- Modal -->
  <!-- class="" -->
  <div
    class="modal fade"
    id="exampleModal"
    tabindex="-1"
    aria-labelledby="exampleModalLabel"
    aria-hidden="true"
  >
    <div
      class="
        modal-dialog modal-xl modal-fullscreen-md-down modal-dialog-scrollable
      "
    >
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">商品资讯</h5>
          <button
            type="button"
            class="btn-close"
            data-bs-dismiss="modal"
            aria-label="Close"
          ></button>
        </div>
        <div class="modal-body">
          <div class="row">
            <!-- 画面左边用来夹带图片连结/上传商品图片档案 -->
            <div class="col-md-4 scrollspy-example">
              <!-- 总是比 tempProduct.imageUrl 数量 多留一个 input 增加图片连结 -->
              <div
                v-for="i in tempProduct.imageUrl.length + 1"
                :key="'img' + i"
                class="mb-3"
              >
                <label :for="'img' + i" class="form-label">图片网址</label>
                <input
                  type="text"
                  class="form-control mb-2"
                  :id="'img' + i"
                  placeholder="image url"
                  v-model="tempProduct.imageUrl[i - 1]"
                />
                <img
                  :src="
                    tempProduct.imageUrl[i - 1] ||
                    'https://memes.tw/user-tmp/1632928923215.png'
                  "
                  :alt="tempProduct.title"
                  class="w-100"
                />
              </div>
              <div class="mb-3">
                <label for="imageFile" class="form-label">上传图片</label>
                <input
                  @change="uploadImageFile"
                  ref="imageFile"
                  type="file"
                  class="form-control mb-2"
                  id="imageFile"
                  placeholder="upload image file"
                />
              </div>
            </div>
            <!-- 画面右边用来填写商品资讯 -->
            <div class="col-md-8">
              <!-- title: "",
              category: "",
              content: "",
              description: "",
              imageUrl: [""],
              enabled: false,
              origin_price: 0,
              price: 0,
              unit: "", -->
              <div class="mb-3">
                <label for="productName" class="form-label">产品名称</label>
                <input
                  v-model="tempProduct.title"
                  type="text"
                  class="form-control"
                  id="productName"
                  placeholder="product name"
                />
              </div>
              <form class="row g-3 mb-3">
                <div class="col-md-6">
                  <label for="category" class="form-label">类别</label>
                  <input
                    v-model="tempProduct.category"
                    type="text"
                    class="form-control"
                    id="category"
                    placeholder="category"
                  />
                </div>
                <div class="col-md-6">
                  <label for="unit" class="form-label">单位</label>
                  <input
                    v-model="tempProduct.unit"
                    type="text"
                    class="form-control"
                    id="unit"
                    placeholder="unit"
                  />
                </div>
                <div class="col-md-6">
                  <label for="originPrice" class="form-label">原价</label>
                  <input
                    v-model="tempProduct.origin_price"
                    type="number"
                    class="form-control"
                    id="originPrice"
                    placeholder="origin price"
                  />
                </div>
                <div class="col-md-6">
                  <label for="price" class="form-label">售价</label>
                  <input
                    v-model="tempProduct.price"
                    type="number"
                    class="form-control"
                    id="price"
                    placeholder="price"
                  />
                </div>
              </form>
              <div class="mb-3">
                <label for="content" class="form-label">产品简介</label>
                <input
                  v-model="tempProduct.content"
                  type="text"
                  class="form-control"
                  id="content"
                  placeholder="product content"
                />
              </div>
              <div class="mb-3">
                <label for="description" class="form-label">详细介绍</label>
                <input
                  v-model="tempProduct.description"
                  type="text"
                  class="form-control"
                  id="description"
                  placeholder="description"
                />
              </div>
              <br />
              <div class="form-check">
                <input
                  v-model="tempProduct.enabled"
                  class="form-check-input"
                  type="checkbox"
                  value=""
                  id="enabled"
                />
                <label class="form-check-label" for="enabled">
                  是否公开上架,若勾选则消费者就看得到此产品资讯喔
                </label>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button @click="login">login</button>
          <button @click="getProductList">getProductList</button>
          <button @click="getProduct">getProduct</button>
          <button
            type="button"
            class="btn btn-secondary"
            data-bs-dismiss="modal"
          >
            Close
          </button>
          <button @click="updateProduct" type="button" class="btn btn-primary">
            Save changes
          </button>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
export default {
  name: "Modal",
  data() {
    return {
      user: {
        email: "---",
        password: "---",
      },
      token: "",
      uuid: "---",
      id: "---",
      tempProduct: {
        id: "",
        title: "",
        category: "",
        content: "",
        description: "",
        imageUrl: [],
        enabled: false,
        origin_price: 0,
        price: 0,
        unit: "",
        options: {
          message: "Hello World!",
        },
      },
    };
  },
  methods: {
    login() {
      const api = "---";
      axios
        .post(api, this.user)
        .then((res) => {
          const token = res.data.token;
          const expired = res.data.expired;
          // 将 token 与他的到期时间存到浏览器 cookie 里
          document.cookie = `loginToken = ${token}; expires = ${new Date(
            expired * 1000
          )};`;
        })
        .catch((err) => {
          console.log(err);
        });
    },
    getProductList() {
      const api = `---`;
      // 先从浏览器 cookie 取得 token
      this.token = document.cookie.replace(
        /(?:(?:^|.*;\s*)loginToken\s*=\s*([^;]*).*$)|^.*$/,
        "$1"
      );

      // https://github.com/axios/axios#global-axios-defaults
      // 并且 header 按照後端 api 文件的规格要求填上 Bearer token 字样
      axios.defaults.headers.common.Authorization = `Bearer ${this.token}`;
      axios
        .get(api)
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        });
    },
    getProduct() {
      const api = `---`;
      // 先从浏览器 cookie 取得 token
      this.token = document.cookie.replace(
        /(?:(?:^|.*;\s*)loginToken\s*=\s*([^;]*).*$)|^.*$/,
        "$1"
      );

      // https://github.com/axios/axios#global-axios-defaults
      // 并且 header 按照後端 api 文件的规格要求填上 Bearer token 字样
      axios.defaults.headers.common.Authorization = `Bearer ${this.token}`;
      axios
        .get(api)
        .then((res) => {
          console.log(res);
          this.tempProduct = res.data.data;
        })
        .catch((err) => {
          console.log(err);
        });
    },
    updateProduct() {
      const api = `---`;
      // 先从浏览器 cookie 取得 token
      this.token = document.cookie.replace(
        /(?:(?:^|.*;\s*)loginToken\s*=\s*([^;]*).*$)|^.*$/,
        "$1"
      );

      // https://github.com/axios/axios#global-axios-defaults
      // 并且 header 按照後端 api 文件的规格要求填上 Bearer token 字样
      axios.defaults.headers.common.Authorization = `Bearer ${this.token}`;
      axios
        .patch(api, this.tempProduct)
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        });
    },
    uploadImageFile() {
      const file = this.$refs.imageFile.files[0];
      // 将图片档案转成 FormData 格式才好上传
      const formData = new FormData();
      formData.append("file", file);
      const api = `---`;
      // https://github.com/axios/axios#global-axios-defaults
      // 并且 header 按照後端 api 文件的规格要求填上 Bearer token 字样
      axios.defaults.headers.common.Authorization = `Bearer ${this.token}`;
      axios
        .post(api, formData)
        .then((res) => {
          console.log(res);
          this.tempProduct.imageUrl.push(res.data.data.path);
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },
};
</script>


祝大家健康开心~内容有出入都希望能多多提醒~感谢 (っಠ‿ಠ)っ


<<:  简单了解VR头盔中,重要且相辅相成的Eye tracking 与Foveated Rendering技术 1

>>:  Day 14 Introducing Serial Communication

第 10 集:浅谈 Container Wrapper 差异

此篇会探讨 container 与 wrapper 用法,会着重在 wrapper 的探讨。 在开...

[DAY 26] 利用Python程序码让机器人走出隧道1

前言 大家好,经过昨天对於控制 waffle 机器人程序码的介绍,相信大家都已经了解了相关的基本函式...

[Day 22] 谈 test double 的五种类型

昨天我们讲了针对 removeTag() 的单元测试 不过,如果我们考虑到针对 updateUser...

[Day22] Emmet 学习笔记 - CSS篇

CSS的简写通常很直觉,会取每个音节的第一个字母来用,但有些似乎是有重叠的关系,就会不太一样,需要特...

JavaScript Call, Bind, Apply

Call, Bind, Apply 这些方法可以让你去指定绑定的 this 如果没有绑定this的话...