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>