iT邦幫忙

1

[學習筆記] Vuex 保存登入的用戶名

這篇是透過網路教學資源自我學習,並將學到的東西做個紀錄
主要是在說明各個component中(XXX.vue 獨立分割的component)如何透過Vuex來存取資料
網路教學資源:https://www.bilibili.com/video/av62476309

Login.vue

<el-input v-model="ruleForm.userId" placeholder="请输入会员帐号" class="loginInput"></el-input>

<script>
import { mapMutations } from "vuex";

export default {
  name: "Login",
  methods: {
    ...mapMutations(["setUserId"]),
    login(formName) {
      this.$refs[formName].validate(valid => {
        if (!valid) {
          return false;
        } else {
          this.setUserId(this.$refs[formName].model.userId);
          this.$router.replace({ path: "/" });
        }
      });
    }
  }
};
</script>

main.js

import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  // 存放全局資料(共用的資料)
  state: {
    userId: "",
    nickName:"AABBCC"
  },
  // 過濾,比較,取得狀態資料的方法,操作狀態(似計算屬性)
  getters: {
    userId(state) {
      return state.userId || sessionStorage.getItem("loginId")
      // 如果state裡面的userId沒有值,改用一開始輸入帳號後存進sessionStorage的值
      // 解決vue 刷新後(重新整理 F5)數據會跟著刷掉的問題
    }
  },
  // 更動資料的地方(似事件)
  mutations: {
    setUserId(state, val) {
      state.userId = val;
      sessionStorage.setItem("loginId", val);
    }
  }
})

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>',
  render: h => h(App)
})

AppNavbar.vue

<span>{{userId}}</span>

<script>
import { mapGetters } from "vuex";

export default {
  name: "AppNavbar",
  computed: {
    ...mapGetters(["userId"])
  }
}
</script>

  1. ...(ES6 展開語法):
    參考資料(MDN):https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax

♛♛ 範例 ♛♛

// 範例1 ======================================
var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4); 

// arr2 此时变成 [1, 2, 3, 4]
// arr 不受影响

console.log(...arr) // 1 2 3 4 ,會展開而非是一個陣列
console.log(arr) // [1,2,3,4]

// 範例2 =======================================
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象: { foo: "baz", x: 42, y: 13 }

個人理解與整理:
...展開語法,可以將整個資料(參數,對象...等)整個搬移,不管內容有多少
但是,當物件屬性的名稱相同時,後面的值會覆蓋(範例2)

!! 所以 ...mapGetters(["userId"]) => 可以將getters裡的userId整個資料帶入
或者多筆資料,如: ...mapGetters(["userId","nickName"])


  1. Vuex輔助函數用法:
    (Vuex辅助函数:mapState、mapGetters、mapMutations、mapActions。)
  • 原始寫法:
    在要取得資料的vue檔案中這麼寫(AppNavbar.vue)

    computed: {
        userId() {
          return this.$store.state.userId;
        }
     },
    
  • 透過Vuex輔助函數+(ES6 展開語法)寫法:

    computed: {
        ...mapGetters(["userId"])
     },
    

    透過mapGetters引入資料 => 從(檔案位置: main.js )store的getters找userId,

    ♛♛ 範例 ♛♛
    變成我們不用自己一個變數就要寫一個
    userId() {return this.$store.state.userId;}
    nickName() {return this.$store.state.nickName;}

    ♛♛ 同理 ♛♛
    ...mapMutations(["setUserId"]) => 從(檔案位置: main.js )store的mutations找setUserId

!!! 注意 !!!
要使用 mapMutations ,要先從vuex import進來才會有作用
import { mapMutations } from "vuex";

要使用Vuex輔助函數 + ES6展開語法,才有辦法設置vue檔案各自的computed

    {{ priceUSA }}

   <script>
       import { mapGetters } from "vuex";

       export default {
         name: "AppNavbar",
         computed: {
             priceUSA(){
               return this.price / 7 ;
             },
             ...mapGetters(["userId"])
         },
         data(){
             return {
                 price:200
             }
         }
       }
   </script>

  1. this.setUserId(this.$refs[formName].model.userId):

Login.vue

  methods: {
    ...mapMutations(["setUserId"]),
    login(formName) {
      this.$refs[formName].validate(valid => {
        if (!valid) {
          return false;
        } else {
          this.setUserId(this.$refs[formName].model.userId);
          this.$router.replace({ path: "/" });
        }
      });
    }
  }

因為已經引入資料

...mapMutations(["setUserId"])

所以可以直接調用,並將input內的值傳給setUserId應用

this.setUserId(this.$refs[formName].model.userId);

前端新手,紀錄學到的新東西,如有錯誤觀念再麻煩糾正,謝謝/images/emoticon/emoticon13.gif


1 則留言

1
dragonH
iT邦大師 1 級 ‧ 2019-10-22 20:48:37

我比較習慣把 vuex 獨立出來

且再細分(e.g. user.store.js, posts.store.js)

最後再用一個 index.store.js export 一個 vuex object 出去

以下舉例

user.store.js

export default {
    state: {},
    mutations: {},
    actions: {},
};

posts.store.js

export default {
    state: {},
    mutations: {},
    actions: {},
};

index.store.js

import userStore from 'user.store.js';
import postsStore from 'posts.store.js';

export default new Vuex.Store({
    modules: {
        userStore,
        postsStore,
    }
})

在 main.js

就引用這個 index.store.js 就好

會看起來比較舒服XD

甚至有人也會再把 state mutations 再繼續細分

看更多先前的回應...收起先前的回應...

感謝大師分享~
看起來真的比較清爽不混亂

dragonH iT邦大師 1 級‧ 2019-10-23 13:17:37 檢舉

如果有用 vue router

也可以用類似的做法

/images/emoticon/emoticon12.gif

dragonH
好喔,我再找找,感謝~
我的router目前就是一長串 哈哈

dragonH iT邦大師 1 級‧ 2019-10-23 15:18:24 檢舉

/images/emoticon/emoticon37.gif

我要留言

立即登入留言