iT邦幫忙

0

頁面重新整理後,Vuex的getter無法跟state同步

你好,
我想請教一下,頁面重新整理後,Vuex的getter無法跟state同步的問題。
我的環境是:Vue3、Vite
遇到問題的情境是:製作會員登出登入的功能。
問題:在登入狀態時,F5重新整理後,重新抓取LocalStorage的資料並更新state的資料,getter的資料同時更新。但畫面卻無法渲染。
這是我的App.vue

//App.vue
<script setup>
//進入網頁
  //獲取token 並存到state跟localStorage
  import { useStore } from "vuex";
  const store = useStore()

  window.addEventListener('load', function(event) {
    if(localStorage.getItem('user')){
      store.commit('onMountedLogin',localStorage.getItem('user'))
    }
    console.log(store.state);
    console.log('重新更新');
  });
  
</script>

這是我的Home.vue

//Home.vue
<script setup>
    import {computed,ref} from 'vue'
    import { useStore } from "vuex";
    const store = useStore()
//獲取登入者資料
    const loginUser =computed(()=>{
        return store.getters.getLoginUser
    })
    const userName =ref(loginUser.value.name)
    const userPermissions =ref(loginUser.value.permissions)
    const getStorage =computed(()=>{
        return localStorage.getItem('user')
    })
</script>
<template>
    <p>{{loginUser}}</p>
    <p>登入者是: {{userName}}</p>
    <p>登入者權限是: {{userPermissions}}</p>
    <p>我是localStorage:{{getStorage}}</p>
</template>

這是我的Vuex

export default createStore({
 state(){
        return{
            loginUser:{}
        }
    },
    getters:{
        getLoginUser(state){
            console.log('getter');
            console.log(state.loginUser);
            return state.loginUser
        }
    },
    mutations:{
        onMountedLogin(state,data){
            //將登入者的資料重新賦予state,防止重整後,資料遺失
            state.loginUser = data
        }
    }
}

渲染的畫面:(使用ref也無法渲染...)

但是getter的資料明明有做更動

這是甚麼原因呢?
忘記補充:這是我的db.json資料格式(測試用會員假資料)

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
listennn08
iT邦高手 5 級 ‧ 2021-10-07 18:46:57
最佳解答

computed 有執行沒錯,但是不會重新賦給 userNameuserPermissions
因為程式碼在一開始 loading 的時候就執行完畢了。

ref 做的監聽是修改自身的變數,所以即使 loginUser 變更了他也不會去觸發,因為一開始已經賦完值了。

可以使用 computed 來計算,

const userName = computed(() => loginUser.value.userName)

或使用 watch 來監聽 loginUser 去更改 userName

import { watch } from 'vue'

// ...

const userName = ref('')

watch(loginUser, (newVal) => {
    userName.value = newVal.userName
})

或是直接在 html 上使用 loginUser.userName

看更多先前的回應...收起先前的回應...
greenriver iT邦研究生 5 級 ‧ 2021-10-08 11:21:43 檢舉

還是不行耶。
發現問題是出在key。

就算在state裡,先定義好key,也是不行。

只要拿掉key,就可以渲染到template!
不懂為什麼?

greenriver iT邦研究生 5 級 ‧ 2021-10-08 11:43:55 檢舉

發現好像是因為localStorage儲存的格式跟state不同的關係?


這該怎麼辦?

如果你是指 refresh 的話,問題是在 localStorage,
取回來要 JSON.parse(localStorage.getItem('user'))

example

greenriver iT邦研究生 5 級 ‧ 2021-10-08 11:56:00 檢舉

我試看看

greenriver iT邦研究生 5 級 ‧ 2021-10-08 12:05:21 檢舉

解決了!!!!!!謝謝。
少了JSON.parse(data)

我要發表回答

立即登入回答