參考資料
Vue3.0官方文檔:https://cn.vuejs.org/
Element Plus文檔:https://element-plus.gitee.io/zh-CN/
打開默認的stroe/index.js
vuex中一共有五個狀態 State Getter Mutation Action Module 下面進行詳細講解
import { createStore } from 'vuex'
export default createStore({
//全局的狀態初始化
state: {
},
//計算state,獲取對應的值
getters: {
},
//更新狀態的方法 更新state的唯一方法 commit mutations
mutations: {
},
//可以異步操作,可以返回promise 更改數據還是傳遞到mutations去更改
actions: {
},
//數據比較多,分模塊
modules: {
}
})
vuex的具體語法
1:state
提供唯一的公共數據源,所有共享的數據統一放到store的state進行儲存,相似與data
首先在index.js裏面初始一個數值
在登錄界面login.vue引入store
在setup裏面獲取
在data裏面定義
在頁面展示一下
這個時候是可以拿到值的
2:mutations
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字符串的事件類型 (type)和一個回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,並且它會接受 state 作爲第一個參數:
接下來進行修改
setCount裏面有兩個屬性
在登錄按鈕上寫一個點擊事件
在頁面觸發
登錄按鈕綁定觸發事件
<el-button type="primary" @click="handleLogin()">登錄</el-button>
打印一下結果
3:actions:進行異步操作
Action和Mutation相似,Mutation 不能進行異步操作,若要進行異步操作,就得使用Action
//可以一步操作,可以返回promise,根呷
比如說修改 setCount()是異步的
//可以異步操作,可以返回promise 更改數據還是傳遞到mutations去更改
actions: {
setCountPromise(context, num) {
return new Promise((resolve, reject) => {
if (num > 100) {
reject("值不能大於100")
} else {
context.commit("setCount", num)
resolve()
}
})
}
},
const handleLogin = () => {
// store.commit("setCount", 100);
store.dispatch("setCountPromise", 100)
.then((res) => {
alert("修改成功");
})
.catch((err) => {
alert(err);
});
console.log(store.state.count);
};
點擊登錄按鈕 彈出修改成功
並打印100
4:Getters
類似於vue中的computed,進行緩存,對於Store中的數據進行加工處理形成新的數據
//計算state,獲取對應的值
getters: {
countStatus(state){
return state.count>=1
}
},
在login.vue裏面去拿countStatus
console.log("修改前getters", store.getters.countStatus);
const handleLogin = () => {
// store.commit("setCount", 100);
store
.dispatch("setCountPromise", -100)
.then((res) => {
alert("修改成功");
})
.catch((err) => {
alert(err);
});
console.log(store.state.count);
console.log("修改後getters", store.getters.countStatus);
};
5:Modules:分模塊
當遇見大型項目時,數據量大,store就會顯得很臃腫,爲了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。
每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割:
在store裏面新建一個state的文件夾、在文件夾下新建num.state.js的文件
將store/index.js裏面的vuex全部都剪切到num.state.js
num.state.js
export default {
namespaced: true,
//全局的狀態初始化
state: {
count: 1,
},
//計算state,獲取對應的值
getters: {
countStatus(state) {
return state.count >= 1
}
},
//更新狀態的方法 更新state的唯一方法 commit mutations
mutations: {
setCount(state, num) {
state.count = num
}
},
//可以異步操作,可以返回promise 更改數據還是傳遞到mutations去更改
actions: {
setCountPromise(context, num) {
return new Promise((resolve, reject) => {
if (num > 100) {
reject("值不能大於100")
} else {
context.commit("setCount", num)
resolve()
}
})
}
},
}
store/index.js刪減
import { createStore } from 'vuex'
import number from "./state/num.state.js"
export default createStore({
//數據比較多,分模塊
modules: {
number
}
})
login.vue裏面也需要修改一下
<template>
<div class="login_wrap">
<div class="form_wrap">
<el-form
ref="formRef"
:model="loginData"
label-width="100px"
class="demo-dynamic"
>
<el-form-item
prop="username"
label="用戶名"
:rules="[
{
required: true,
message: '此項爲必填項',
trigger: 'blur',
},
]"
>
<el-input v-model="loginData.username" />
</el-form-item>
<el-form-item
prop="password"
label="密碼"
:rules="[
{
required: true,
message: '此項爲必填項',
trigger: 'blur',
},
]"
>
<el-input type="password" v-model="loginData.password" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleLogin()">登錄</el-button>
<p>{{ num }}</p>
<!-- <el-button @click="addDomain">New domain</el-button>
<el-button @click="resetForm(formRef)">Reset</el-button> -->
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
//引入useStore
import { useStore } from "vuex";
export default {
name: "login",
setup() {
const store = useStore();
const count = store.state.number.count;
const data = reactive({
loginData: {
username: "",
password: "",
},
num: count,
// countStatus:
});
console.log("修改前getters", store.getters["number/countStatus"]);
const handleLogin = () => {
// store.commit("setCount", 100);
store
.dispatch("number/setCountPromise", -100)
.then((res) => {
alert("修改成功");
})
.catch((err) => {
alert(err);
});
console.log(store.state.number.count);
console.log("修改後getters",store.getters["number/countStatus"]);
};
return {
...toRefs(data),
handleLogin,
};
},
};
</script>
<style scoped>
.login_wrap {
width: 100%;
height: 100vh;
background: #2d3761;
position: relative;
}
.form_wrap {
position: fixed;
top: 50%;
transform: translate(130%, -50%);
background: #fff;
padding: 30px 50px;
border-radius: 5px;
}
</style>
修改成功之後看一下效果