1. 基本概念
狀態管理工具,簡單點就是 管理很多公共變量(這些變量標識狀態),比如 用戶的登錄狀態 名稱 頭像 地理位置等
2. 安裝與配置
2.1 安裝
npm i vuex -S
2.2 配置
根目錄創建一個文件夾store 再新建一個index.js,在index.js文件中
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
counter:100
},
mutations: {},
actions: {},
getters: {},
modules: {}
})
export default store
2.3 註冊
import store from './store'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
2.4 使用
數據的訪問
<template>
<div>
<h2>{{$store.state.counter}}</h2>
</div>
</template>
3.vuex的核心概念
3.1 State
保存狀態信息,而且,一般只是用一個store對象
3.2 Getter
類似計算屬性
3.2.1 首先定義
getters: {
powerCounter(state, getters)
{
return state.counter * state.counter
}
//第二個參數 getters就是getters對象,獲取同爲getters下的其他屬性
}
3.2.2 使用
<h2>getters的相關內容:{{$store.getters.powerCounter}}</h2>
3.2.3 getters中獲取外部傳入的數據
getters中獲取外部傳入的數據,需要一些技巧:在getters中返回一個函數
首先定義
getters: {
powerCounter(state, getters)
{
return function (data) {
return data * state.powerCounter * state.powerCounter
}
}
}
使用
<h2>{{$store.state.powerCounter(5)}}</h2>
3.3 Mutation
Mutation裏面定義的類似於事件,分爲事件類型 回調函數.然後通過$store.commit('事件類型')
進行事件註冊,並調用回調,(在我看來,更像定義一個方法)
mutation 是用來修改states裏面的狀態
首先定義
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment(state) {
// 變更狀態
state.count++
}
}
})
通過事件觸發
<button @click="$store.commit('increment')">+</button>
3.3.1 接收外部數據
向 $store.commit
傳入額外的參數,稱爲載荷(payload)
定義
mutations: {
increment(state, payload)
{
state.counter + payload
}
}
觸發
<button @click="$store.commit('increment',data)">+</button>
還有另外一種傳遞方式
$store.commit({
type: '事件類型',
mydata1: mydata1,
mydata1: mydata1
})
這種方式傳入數據,接收的數據是一個對象類型
3.3.2 mutation裏的響應式
在store中state裏初始化好所需的屬性是響應式的,而追加屬性不是響應式的
當給state中的對象添加新屬性時,使用下面的方式添加新屬性纔是響應式的
- 方式一: 使用
Vue.set(obj,'newProp',data)
比如Vue.set(state.屬性,'新添屬性','屬性值')
- 方式二: 用新對象給舊對象重新複製
- 補充一下基礎知識:
刪除對象中的屬性使用 delete ->不是響應式的,Vue中刪除對象的屬性 Vue.delete(對象,屬性)->是響應式的
3.3.3 mutation的類型常量
即 將事件類型的名字,提取爲常量 常量提取一個文件,並導出常量 ,在定義事件類型和回調函數時,導入常量的文件,並使用常量定義即可
mutationType.js
中定義
export INCREMENT = 'increment'
引入
import {INCREMENT} from './mutationType.js'
mutations: {
[INCRENMNT](state)
{
state.counter++
},
decrement(state)
{
state.counter--
}
}
使用時候,也是導入常量文件 再使用
import {INCRENMNT} from './mutationType.js'
<button @click="$store.commit(INCRENMENT)">+</button>
3.4 Action
面向一些異步操作,Action類似於Mutation,是替代Mutation裏的異步操作的
使用:定義方法,然後調用mutations裏面的方法
mutations: {
mutationsUpdate(state) {
state.count++
}
},
actions: {
actionUpdate(context, payload)
{//context指向store
setTimrout(() => {
console.log(payload)
context.commit('mutationsUpdate')//mutationsUpdate是mutations裏定義的方法
}, 1000)
}
}
context說明
context是上下文,通過context可以獲得store的其他數據.但是並不是總是指向store 在module概念時,其指向對應模塊
事件觸發,通過store.dispatch
觸發
<button @click="$store.dispatch('actionUpdate',Mydata)">+</button>
<!-- 顯然action也支持payload載荷-->
3.4.1 actions中向外傳遞消息
方式一:傳遞一個對象,通過對象的回調函數獲取信息
<button @click="$store.dispatch('actionUpdate',{message:'傳遞的信息',success:()=>{console.log('成功後的回調')}})">+</button>
然後actions中使用時:
actionUpdate(context, payload)
{
setTimrout(() => {
context.commit('update')
payload.success()
}, 1000)
}
方式二:使用Promise
<button @click="$store.dispatch('actionUpdate','傳遞信息').then(()=>{console.log(修改提交成功)})">+</button>
actions中
actionUpdate(context, payload)
{
return new Promise((resolve, reject) => {
setTimrout(() => {
context.commit('update')
console.log(patload)
resolve()
}, 1000)
})
}
3.5 Module
作用 將數據分模塊,將store分割成模塊,每個模塊擁有自己的state mutations actions getters
定義
import Vuex from "vuex";
const ModuleA = {
state: {
name: '陳林'
},
mutations: {},
actions: {},
getters: {}
}
const ModuleB = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const store = new Vuex.Store({
state: {
counter: 100
},
modules: {
a: ModuleA,
b: ModuleB
}
})
export default store
使用:
<h2>{{$store.state.a.name}}</h2>
修改數據則在對應模塊裏面的mutations或者actions裏面定義方法進行修改,然後事件觸發:
<button @click="$store.commit('事件類型',payload)">+</button>
原理: modules裏面的a,b等會放入state裏面,所以我們使用時候,直接使用$store.state.a.name
3.5.1 模塊中使用store中的state的變量
在模塊的 getters裏定義的方法有第三個參數 rootState,通過該參數進行數據獲取
getters:{
myFun(state,getters,root){
}
}
3.5.2 模塊的actions使用
定義
actions:{
actionUpdate(context){//此處的context不再是store,而是指向本模塊,可以通過context獲取許多東西
setTimeout(()=>{
context.commit('mutationUpdate')
},1000)
}
}
觸發
<button @click="$store.dispatch('actionUpdate')">+</button>
4. Vuex文件結構:
推薦
index.js 存放state並且管理整個vuex
action.js
mutations.js
modules.js(moduleA.js moduleB.js)
這樣來劃分,然後導出再引入即可