前置作業1:調用 Pinia store 資料<script></script> 將 LoginStore.js 檔裡的 useLoginStore 方法取出。透過 computed 監控資料更動時就重新渲染畫面的特性,把 Pinia store 剛更新的會員 name 、 email 、 id 給顯示。再運用 mapState 取用 Pinia store 資料。
前置作業2:取得網路請求 axios 的路徑
created 裡的 apiUserResUrl 與 apiUserResIdUrl 是網路請求的路徑。路徑會在提交表單和畫面下方渲染出的口袋清單被使用,為使這兩個函式能取用該變數(全域變數),將之定義於此。created 是 Vue 生命週期中實例創建完成階段,可訪問 data 、 computed 、 watch、 methods 上的方法和數據。此時可把 apiUserResUrl 與 apiUserResIdUrl 在 data 裡的初始值給重新賦值。
vue 的生命週期介紹可以參考此篇文章。
(3-3)動作拆解-表單提交
表單提交只有觸發方法的說明。
1.表單提交的限制
2.導出的資料增加屬性<script></script> 中資料實體增加以下屬性。
3.當表單按鈕「加入口袋」被操作時
event.preventDefault(); 處理。<template>
  ...
  <form>
    ...
    <div class="d-flex justify-content-end">
      <button
        class="btn btn-lg btn-primary mb-4"
        type="submit"
        @click="submitPucket()">
        加入口袋
      </button>
    </div>
  </form>
  ...
</template>
<script>
import axios from "axios";
import { mapState } from "pinia";
// 定義好的 store 賦值給變數 useLoginStore
// 在元件中引入並呼叫 useLoginStore() 來訪問 store
import { useLoginStore } from "../../components/LoginStore.js";
export default {
  data() {
    return {
      restaurants: [],
      filterRes: {
        filterBrandName: [],
        filterType: [],
        filterAddress: [],
      },
      tempRes: {
        selectBrandName: "",
        selectType: "",
      },
      saveRes: {
        saveBrandName: "",
        saveType: "",
        saveAddress: "",
      },
      ...
      apiUserResUrl: "",
      apiUserResIdUrl: "",
      ...
    };
  }
  methods: {
    ...
    submitPucket() {
      event.preventDefault();
      if (
        (this.saveRes.saveBrandName !== "") &
        (this.saveRes.saveAddress !== "") &
        (this.saveRes.saveType !== "")
      ) {
        axios.get(this.apiUserResUrl)
          .then((res) => {
            // res.data是陣列要變成物件後面才能用push,所以取第一個內容(這裡是物件)
            const userData = res.data[0];
            const newRestaurant = {
              brandName: this.saveRes.saveBrandName,
              address: this.saveRes.saveAddress,
              type: this.saveRes.saveType,
            };
            // 使用陣列方法 some 檢查會員餐廳API是否有已存在的brandName
            const exists = userData.userRestaurants.some(
              (item) => item.brandName === newRestaurant.brandName
            );
            if (!exists) {
              userData.userRestaurants.push(newRestaurant);
              alert("口袋添加成功");
              return axios.put(apiUserResIdUrl, userData);
            } else {
              alert("該餐廳已存在!");
            }
          })
          .catch((error) => {
            console.log(error);
            alert("口袋添加失敗");
          });
      } else {
        alert("欄位不可空值!");
      }
    }
    this.tempRes.selectType = "";
    this.tempRes.selectBrandName = "";
    this.filterRes.filterAddress = "";
  },
  ...
  created() {
      this.apiUserResUrl = `http://localhost:3002/userRes?email=${this.userEmail}`;
      this.apiUserResIdUrl = `http://localhost:3002/userRes/${this.userId}`;
    }
  },
  ...
  // 監聽data
  computed: {
    ...mapState(useLoginStore, {
      // 'name' 是 store 中的狀態名,'userName' 是在組件中的名稱
      userName: (state) => state.name,
      userEmail: (state) => state.email,
      userId: (state) => state.id,
    }),
  },
};
</script>
附上用 axios.put() 回寫到會員餐廳 API 結果。