Nuxt2中使用VueX

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式 + 庫。它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。

Vuex中四大部分

  • state:用於存儲應用程序的數據和狀態,是唯一的、單一的數據源。Vuex 的狀態存儲是響應式的,當狀態發生變化時,組件將自動更新。

  • mutations:用於修改 state 中的數據和狀態,是唯一允許同步修改狀態的方法。mutations 中的方法必須是同步的,並且必須通過調用 commit 方法來觸發。

  • actions:用於處理異步操作,可以包含任意異步操作,如 API 調用、異步等待、定時器等。actions 中的方法可以包含任意異步操作,但是不能直接修改 state 中的數據和狀態,必須通過調用 commit 方法來觸發 mutations 中的方法。

  • getters:用於從 state 中派生出一些狀態,類似於組件中的計算屬性。getters 可以接收其他 getters 作為依賴項,並且在狀態發生變化時具有緩存功能,只有當依賴項發生變化時才會重新計算

    呼叫store內的函示

  • 在主程式使用mapState 導入vueX的狀態參數

  • commit來呼叫mutations方法

  • dispatch呼叫actions方法

    範例

    簡單的登入系統

    // store/index.js
    // 建立需要的參數
    export const state = () => ({
    isLoggedIn: false,
    userName: ''
    })
    // 處理異步方法
    export const actions = {
    login({ commit } , {userName}) {
    try {
      commit('setUserName', userName)
      commit('setLoggedIn', true)
    } catch (e) {
      console.log(e);
    }
    },
    // 登出
    async logout({ commit }){
    const response = await this.$axios.delete("/api/logout",{
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      }
    });
    console.log(response.data.message)
    localStorage.removeItem('token');
    this.$router.push({ path: '/' })
    commit('setLoggedIn', false)
    commit('setUserName', '')
    },
    }
    // 用於修改 state 中的數據和狀態
    export const mutations = {
    setLoggedIn(state, data) {
      state.isLoggedIn = data;
    },
    setUserName(state, data) {
    state.userName = data;
    },
    }
// /pages/index.vue
<template>
  <v-container>
    會員系統
    <ValidationObserver v-slot="{ invalid }">
      <ValidationProvider v-slot="{ errors }" rules="required|email" name="電子信箱">
        <v-text-field v-model="loginEmail" label="email" :error-messages="errors"></v-text-field>
      </ValidationProvider>
      <ValidationProvider v-slot="{ errors }" rules="required|min:8" name="密碼" vid="confirmation">
        <v-text-field v-model="loginPassword" label="密碼" :error-messages="errors" name="密碼" type="password"></v-text-field>
      </ValidationProvider>
      <v-btn :disabled="invalid" @click="login">登入</v-btn>
    </ValidationObserver>

    <ValidationObserver v-slot="{ invalid }">
      <ValidationProvider v-slot="{ errors }" rules="required" name="檔案標題">
        <v-text-field v-model="registerUsername" label="使用者名稱" :error-messages="errors"></v-text-field>
      </ValidationProvider>
      <ValidationProvider v-slot="{ errors }" rules="required|email" name="電子信箱">
        <v-text-field v-model="registerEmail" label="email" :error-messages="errors"></v-text-field>
      </ValidationProvider>
      <ValidationProvider v-slot="{ errors }" rules="required|min:8" name="密碼" vid="confirmation">
        <v-text-field v-model="registerPassword" label="密碼" :error-messages="errors" name="密碼" type="password"></v-text-field>
      </ValidationProvider>
      <ValidationProvider v-slot="{ errors }" rules="required|confirmed:confirmation" name="確認密碼" type="password">
        <v-text-field label="請再次輸入密碼" :error-messages="errors" ></v-text-field>
      </ValidationProvider>
      <v-btn :disabled="invalid" @click="register">註冊</v-btn><br/>
    </ValidationObserver>
  </v-container>
</template>

<script>
    // nuxt專案會自動引入store中的vueX,無需另外import
  import { mapState } from "Vuex";
  export default {
    name: 'IndexPage',
    data(){
      return{
        registerUsername:'',
        registerEmail:'',
        registerPassword:'',
        loginEmail:'',
        loginPassword:'',
      }
    },
    computed() {
      // 導入vueX狀態
      mapState(['isLoggedIn'])
    },
    methods:{
            // 註冊
      async register(){
          const registerData ={
            "name": this.registerUsername,
            "email": this.registerEmail,
            "password": this.registerPassword
          }
          await this.$axios.post("/api/register", registerData);

      },
            // 登入
      async login(){
        const loginData ={
          "email": this.loginEmail,
          "password": this.loginPassword
        }
        try{
          // await this.$store.dispatch('login',loginData)
          const response = await this.$axios.post("/api/login", loginData);
          if(response.data.token){
            localStorage.setItem('token', response.data.token)
                        // 呼叫actions方法
            this.$store.dispatch('login', response.data.user.name) 
                        // 呼叫mutations方法
            // this.$store.commit('setUserName', response.data.user.name)
            this.$router.push({ path: '/files' })
          }
        }
        catch(e){
          console.log(e);
        }
      },
    },
  }
</script>