一峻厚、優(yōu)點(diǎn)
Vuex狀態(tài)管理跟使用傳統(tǒng)全局變量的不同之處:
1.Vuex的狀態(tài)存儲(chǔ)是響應(yīng)式的:就是當(dāng)你的組件使用到了這個(gè)Vuex的狀態(tài),一旦它改變了焕毫,所有關(guān)聯(lián)的組件都會(huì)自動(dòng)更新相對(duì)應(yīng)的數(shù)據(jù),這樣開(kāi)發(fā)者省事很多驶乾。
2.不能直接修改Vuex的狀態(tài):如果是個(gè)全局對(duì)象變量邑飒,要修改很容易,但是在Vuex中不能這樣做级乐,想修改就得使用Vuex提供的唯一途徑:顯示地提交(commit)mutations來(lái)實(shí)現(xiàn)修改(沒(méi)了解過(guò)這里沒(méi)關(guān)系疙咸,下一節(jié)前端君會(huì)有介紹)。這樣做的好處就是方便我們跟蹤每一個(gè)狀態(tài)的變化风科,在開(kāi)發(fā)過(guò)程中調(diào)試的時(shí)候罕扎,非常實(shí)用。否則就全局都會(huì)修改
二丐重、安裝VueX步驟
1.安裝
cnpm install vuex-localstorage
2.引用VueX
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
3.在引入Store
image.png
創(chuàng)建vuex的用法
import Vue from 'vue'
import Vuex from 'vuex'
import usersov from './user'
import createPersist from 'vuex-localstorage'
Vue.use(Vuex)
// 創(chuàng)建vuex 構(gòu)造器
export default new Vuex.Store({
state:{
}
})
主要包括以下幾個(gè)模塊:
1.State:定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu)腔召,可以在這里設(shè)置默認(rèn)的初始狀態(tài)。
2.Getter:允許組件從 Store 中獲取數(shù)據(jù)扮惦,mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性臀蛛。
3.Mutation:是唯一更改 store 中狀態(tài)的方法,且必須是同步函數(shù)崖蜜。
4.Action:用于提交 mutation浊仆,而不是直接變更狀態(tài),可以包含任意異步操作豫领。
5.Module:可以將 store 分割成模塊(module)抡柿。每個(gè)模塊擁有自己的 state、mutation等恐、action洲劣、getter备蚓、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割
1.State
//state存儲(chǔ)應(yīng)用層的狀態(tài)
state:{ // 聲明數(shù)據(jù)
// n:0,
// username:'',
shopCar:[ 1,2,3,4,5],
count:5
},
2.Getter
getters:{// 類(lèi)似與 state 的計(jì)算屬性 可以根據(jù)state中的數(shù)據(jù)的變化 計(jì)算出新的值
rgetShopCarLen(state){
var sum = 0
console.log(state.shopCar);
for(var i=0; i<state.shopCar.length; i++){
sum+=state.shopCar[i]
}
return sum
}
}
3.Mutation
我們?cè)?mutations中定義了一個(gè)叫increment的函數(shù),函數(shù)體就是我們要進(jìn)行更改的地方
mutations:{ // 修改數(shù)據(jù)的 方法
increment(state,val){ // 添加這個(gè)名字state就可以不用this
// 變更狀態(tài)
state.count += val;
},
},
我們?cè)谔峤籧ommit時(shí)候囱稽,字符串參數(shù)increment,就是對(duì)應(yīng)在 mutations中的increment郊尝。
一般通過(guò)方法或鉤子觸發(fā),例如:
methods: {
getVal(item) {
//通過(guò)commit提交一個(gè)名為increment的mutation
this.$store.commit("increment", item);
}
}
4.Action
// 用來(lái)保存用戶信息的 store
export default {
//存放數(shù)據(jù)
state:{
userInfo:{},
key:''
},
//通過(guò)commit mutations中的方法來(lái)處理
mutations:{
// 定義接收用戶信息的方法
updateUserInfo(state,val){
state.userInfo=val
console.log(state.userInfo);
},
undateKey(state,val){
state.key=val
}
},
//接受dispatch傳遞過(guò)來(lái)的方法和參數(shù)
actions:{
undateKey(state,val){
//處理異步操作
setTimeout(() => {
//通過(guò)commit提交一個(gè)名為getParam的mutation
//action 函數(shù)接收一個(gè) store 的實(shí)例對(duì)象战惊,因此你可以調(diào)用 store.commit 提交一個(gè) mutation
state.commit('undateKey',val)
}, 0);
}
}
}
然后我們就在組件里這么調(diào)用就可以了
methods: {
getVal() {
var name= 'xia';
var age= '26';
var sex= 'man';
//1.通過(guò)dispatch將方法getParamSync和多個(gè)參數(shù){name,age,sex}傳遞給actions
this.$store.dispatch('undateKey',{name,age,sex})
}
}
5.Module
隨著項(xiàng)目的復(fù)雜度增大流昏,為了方便管理vuex,一般會(huì)將其按功能分割成不同的模塊(Module)吞获,方便日后管理况凉。每個(gè)模塊擁有自己的 state、mutation各拷、action茎刚、getter、甚至是嵌套子模塊
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user' // 模塊
import createPersist from 'vuex-localstorage'
Vue.use(Vuex)
// 創(chuàng)建vuex 構(gòu)造器
export default new Vuex.Store({
actions,
getters,
state,
mutations,
// 模塊或模組
modules:{
user // 引入的模塊
},
})
user.js 文件
// 每個(gè)模塊擁有自己的 state撤逢、mutation、action粮坞、getter蚊荣、甚至是嵌套子模塊
export default {
state: {
text: 'moduleA'
},
getters: {},
mutations: {},
actions: {}
}
然后我們就在組件里這么調(diào)用就可以了
<template>
<div class="demo">
<h1>{{getText1}}</h1>
</div>
</template>
computed: {
getText1(){
return this.$store.state.user.text;
},
}
由此可知,模塊內(nèi)部的 state 是局部的莫杈,只屬于模塊本身所有互例,所以外部必須通過(guò)對(duì)應(yīng)的模塊名進(jìn)行訪問(wèn)
vuex最最簡(jiǎn)單的項(xiàng)目實(shí)例
1.存儲(chǔ)數(shù)據(jù)( a.vue文件 )
import { mapMutations } from "vuex"; // 引入mapMutations
export default {
methods: {
...mapMutations({
// 將changeNews與mutations中的SET_NEWS關(guān)聯(lián)
changeNews: "SET_NEWS"
}),
submit(){
// 提交一個(gè)名為changeNews的mutation,并傳入?yún)?shù)val
let val = 'test news';
this.changeNews(val);// 相當(dāng)于this.$store.commit("changeNews", val);
}
}
}
2.獲取數(shù)據(jù)( b.vue文件 )
import { mapGetters } from "vuex"; // 引入mapGetters
export default {
computed: {
// 用vuex讀取數(shù)據(jù)(讀取的是getters.js中的數(shù)據(jù))
// 相當(dāng)于this.$store.getters.news(vuex語(yǔ)法糖)
...mapGetters(["news"])
},
created() {
// 獲取getters中news數(shù)據(jù)
console.log(this.news);
}
}
.
3.store文件目錄結(jié)構(gòu)
index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import * as getters from './getters'
//每次修改state都會(huì)在控制臺(tái)打印log
import createLogger from 'vuex/dist/logger'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
actions,
getters,
state,
mutations,
strict: debug, // 當(dāng)debug=true時(shí)開(kāi)啟嚴(yán)格模式(性能有損耗)
plugins: debug ? [createLogger()] : []
})
state.js:
const state = {
news: {}
}
export default state
mutations.js:
const mutations = {
SET_NEWS(state, val) {
state.news= val
}
}
export default mutations
actions.js:
//異步處理
const actions = {
M_NEWS({ commit }, val) {
commit('SET_NEWS', val); // commit mutations修改
}
}
export default actions
4.使用store
在main.js中引用
import Vue from 'vue'
import App from './App'
import router from './router/index'
Vue.config.productionTip = false
import axios from 'axios'
Vue.prototype.axios=axios;
import store from './store/index'
new Vue({
el: '#app',
router:router,
store:store,
components: { App},
template: '<App/>'
})