iT邦幫忙

0

Vue pinia 在重整或跳轉頁面Store的資料會重製(消失)?

  • 分享至 

  • xImage

專案使用quasar Vue init創立
我在練習登入的部分
登入會把登入資料寫入store內
然後再判斷是否有登入
目前登入後 到index.vue時 store的資料是有的
但按重新整理或是跳轉到/home
store的資料應該是消失 所以會變預設值
LoginState的值會變回false
想問是設定問題還是有哪的觀念錯誤 謝謝

index.vue跟home.vue 程式碼一樣用於測試
localhost:3000 是用json-server 當測試DB

main.js

import { boot } from "quasar/wrappers";
import { createPinia } from "pinia";
export default boot(({ app }) => {
  const pinia = createPinia();
  app.use(pinia);
});

login.js

import { defineStore } from "pinia";

export const useLoginStore = defineStore("login", {
  state: () => ({
    loginState: false,
    userInfo: [],
    permissions: 0,
    localLanguage: "zh-TW",
  }),
  getters: {
    getLoginState: (state) => state.loginState,
  },
  actions: {
    changeLoginState(bool) {
      this.loginState = bool;
    },
    changeUserInfo(info) {
      this.userInfo = info;
    },
    changePermissions(permission) {
      this.permissions = permission;
    },
  },
});

Login.vue

<template>
  <q-layout view="hHh Lpr fFf">
    <q-page-container>
      <div class="row items-center">
        <div class="col-8">
          <img
            alt="Quasar logo"
            src="~src\assets\login_bk.jpg"
            style="width: 98%; height: 100%"
          />
        </div>
        <div class="col-4">
          <div class="offset-md-3 col-12">
            <q-input
              class="loginInput"
              standout="bg-teal text-white"
              v-model="account"
              label="Account"
            />
          </div>
          <div class="offset-md-3 col-12">
            <q-input
              class="loginInput"
              standout="bg-teal text-white"
              v-model="password"
              label="Password"
            />
          </div>
          <div class="offset-md-3 col-12">
            <q-btn color="teal" @click="login">{{ $t("login") }}</q-btn>
          </div>
        </div>
      </div>
    </q-page-container>
  </q-layout>
</template>

<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import { useLoginStore } from "stores/login";
import axios from "axios";
const router = useRouter();
const loginStore = useLoginStore();
const account = ref(null);
const password = ref(null);
const login = () => {
  if (checkVal(account.value) && checkVal(password.value)) {
    axios
      .get(
        `http://localhost:3000/user?account=${account.value}&password=${password.value}`,
      )
      .then((res) => {
        if (res.data.length == 0) {
          alert("登入失敗,請確認帳號密碼是否正確");
        } else {
          loginStore.changeLoginState(true);
          loginStore.changeUserInfo(res.data[0]);
          alert(t("login") + " " + t("success"));
          router.push({
            path: "/",
          });
        }
      })
      .catch((error) => {
        alert("登入失敗, Error:", error);
      });
  } else {
    alert("帳號或密碼請勿空白!");
  }
};

const checkVal = (val) => {
  var validate = true;
  if (val.length == 0) {
    validate = false;
  }
  return validate;
};
</script>

<style scoped>
.loginInput {
  width: 75%;
  margin-bottom: 10px;
}
</style>

index.vue & home.vue

<template>
  <q-page class="flex flex-center">
    <img
      alt="Quasar logo"
      src="~src\assets\quasar-logo-vertical.svg"
      style="width: 200px; height: 200px"
    />
  </q-page>
</template>

<script setup>
import { useRouter } from "vue-router";
import { storeToRefs } from "pinia";
import { useLoginStore } from "stores/login";

const router = useRouter();
const loginStore = useLoginStore();
const { loginState, userInfo, permissions, localLanguage } =
  storeToRefs(loginStore);
if (!loginState.value) {
  router.push({
    path: "/login",
  });
}
</script>

db.json

{
  "user": [
    {
      "account": "mary",
      "name": "瑪莉",
      "email": "mary@gmail.com",
      "password": "a123",
      "id": 1
    },
    {
      "account": "Admin",
      "name": "管理者",
      "email": "mail@gmail.com",
      "password": "123456",
      "id": 2
    }
  ]
}
store 的應用。你要將其試為一種NEW物件的使用方式。
所以當重新刷頁的情況下。也就是VUE程式會重載的情況下。
它是會再重新NEW一個新物件出來的。

一般使用VUE的情況下。並不太需要重載的動作。
所以store才會一直存在。

如果說今天會重載的話。你需要將資料放到不會消失的地方。例如 COOKIE或是瀏器的 storage 上。
然後設計的 store 。多做一個 init 在每次NEW 物件時,將資料再移回來。
柯柯 iT邦新手 3 級 ‧ 2024-04-24 14:58:55 檢舉
我大概了解了
我再去查看看router的設定部分
應該是router的問題 不是用SPA
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
pblaten
iT邦新手 3 級 ‧ 2024-04-24 16:23:06
最佳解答

但按重新整理或是跳轉到/home

在Vue app按重新整理或是網址列輸入跳轉,都會使Vue程式會重載(如同浩瀚星空大大所說)
可以使用vue-router進行跳轉:
router.push OR <router-link to="/home">就會是SPA內跳轉,不會造成Vue重載
2.
如果使用pinia然後想要儲存狀態在瀏覽器(localStorage/COOKIE)可以參考pinia-plugin-persistedstate

柯柯 iT邦新手 3 級 ‧ 2024-04-30 07:59:08 檢舉

後來看完後 發現 我router是正確的 只是因為menu的連結是用標籤 所以它是跳轉過去 所以測試一直錯誤 後來改成用click event 去router.push就正常了

我要發表回答

立即登入回答