一 初識Vuex
Vuex是vue官方推出的一款插件,採用“集中式存儲“管理所有組件的狀態(其實就是使數據共享)
1. vuex安裝
npm install vuex
1. State單一狀態樹
單一狀態樹是指Vuex將所有的狀態(數據)都放在一個store中,便於管理和維護,而不是把不同的數據放在不同的store中,容易讓人混淆
二 vuex 模塊
- /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
//存放一些數據(狀態)
state: {
//在state中定義的數據是響應式的,數據改變頁面會馬上改變
counter: 1000,
stu: [
{id:11,age:30},
{id:17,age:50},
{id:14,age:20}
],
info: {
name: 'kobe',
age: 50
}
},
//存放改變數據的方法,官方推薦改變數據時用mutations中的方法來實現,而不是直接修改數據
//同步操作
mutations: {
increment(state){
state.counter++
},
decrement(state){
state.counter--
},
//參數被稱作mutations的載荷,多參數可以傳一個對象
incrementCount(state,payload){
//普通的提交
//state.counter += payload
//特殊的提交
state.counter += payload.count
},
addStudent(state,stu){
state.stu.push(stu)
},
updateInfo(state){
//state.info.name = 'woshishui' //數據在state中,響應式改變
//state.info['address'] = 'china' //數據不在state中,不會響應式改變
//Vue.set(state.info, 'address', 'china')//用的set 響應式改變
//delete state.info.age //非響應式
Vue.delete(state.info, 'age') //響應式
}
},
//異步操作 修改數據還是得調用mutations中的方法
actions: {
/* aUpdateInfo(context,payload){
setTimeout(()=>{
context.commit('updateInfo')
console.log(payload)
},1000)
}*/
aUpdateInfo(context,payload) {
return new Promise((resolve,reject) => {
setTimeout(() => {
context.commit('updateInfo')
console.log(payload)
resolve('111')
},1000)
})
}
},
//數據篩選和數據變換
getters: {
doubleCn(state){
return state.counter * state.counter;
},
stuFilter(state){
return state.stu.filter(s=> s.age>=30)
},
//第一個參數一定是state 第二個參數一定是getters
len(state,get){
return get.stuFilter.length;
},
//傳參寫法
studentFilter(state){
/*return function(age){
return state.stu.filter(s=>s.age>=age)
}*/
//箭頭函數寫法
return age => {return state.stu.filter(s => s.age >= age)}
}
},
//模塊,用於把一些數據分離出來,使結構更清晰,
//編譯時會將modules中的內容加載到state中
modules: {
a: {
state: {
name: 'zan'
},
mutations: {
updateName(state, payload){
state.name = payload
}
},
//modules中的action只能對modules中的mutations進行調用
actions:{},
getters:{
fullName(state){
return state.name + '1111'
},
fullName2(state, getters){
return getters.fullName + '222'
},
//獲得跟內的數據
fullName3(state, getters, rootState){
return getters.fullName2 + rootState.counter
}
}
}
}
})
export default store
- src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
- src/App.vue
<template>
<div>
<h1>全局變量{{$store.state.counter}}</h1>
<button @click="incre">+</button>
<button @click="decre">-</button>
<h1>getters double {{$store.getters.doubleCn}}</h1>
<h1>getters filter {{$store.getters.stuFilter}}</h1>
<h1>getters length {{$store.getters.len}}</h1>
<h1>getters params {{$store.getters.studentFilter(50)}}</h1>
<button @click="addCount(10)">addCount</button>
<button @click="addStudent()">添加數據</button>
<button @click="updateInfo">{{$store.state.info}}</button>
<h1>=============modules=================</h1>
<h2>{{$store.state.a.name}}</h2>
<button @click="updateName">修改名字</button>
<!--modules中getters調用和平常的一樣-->
<h2>{{$store.getters.fullName}}</h2>
<h2>{{$store.getters.fullName2}}</h2>
<h2>{{$store.getters.fullName3}}</h2>
</div>
</template>
<!---->
<script>
export default {
name: 'App',
//封裝mutations中的方法
methods: {
incre(){
this.$store.commit('increment')
},
decre(){
this.$store.commit('decrement')
},
addCount(count){
//1. 普通的提交封裝,傳回去的是普通數據類型
//this.$store.commit('incrementCount',count)
//2. 特殊的提交封裝,傳回去的是對象
this.$store.commit({
type: 'incrementCount',
count
})
},
addStudent(){
const stu={id:4454,age:100}
this.$store.commit('addStudent',stu)
},
updateInfo(){
//同步操作
//this.$store.commit('updateInfo')
//異步操作
this.$store.dispatch('aUpdateInfo', 'payload')
.then(res => {
console.log('裏面完成了提交');
console.log(res);
})
},
updateName(){
this.$store.commit('updateName','newName')
}
}
}
</script>
<style>
</style>
三 vuex 模塊分佈式寫法
- /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'
Vue.use(Vuex)
const state ={
count:100,
students:[
{id:100,name:'kobe',age:30},
{id:200,name:'james',age:32},
{id:300,name:'curry',age:31},
],
info:{
name:'kobe',
age:19
}
}
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
modules:{
a:moduleA
},
})
export default store
- /src/store/mutations.js
export default {
increment(state){
state.count++
},
decrement(state){
state.count--
},
//普通提交的封裝 傳入的是具體數字
/* incrementCount(state,count){
state.count += count
},*/
//特殊提交的封裝 傳入的是對象
incrementCount(state,payload){
state.count +=payload.count
},
addStudent(state, data){
state.students.push(data)
},
updateInfo(state){
//state.info.name = 'james' 修改已有的數據是響應式的
//state.info['address'] = 'LA' 添加未有的數據不是響應式的
//Vue.set(state.info,'address','LA') //響應式
//delete state.info.age 非響應式
Vue.delete(state.info, 'age') //響應式
//或者用響應式方法 push pop shift unshift splice 等
}
}
- /src/store/getters.js
export default{
powerCount(state){
return state.count * state.count
},
more20stu(state){
return state.students.filter(s => s.age >20)
},
len(state,getters){//可以有第二個參數拿其他getters
return getters.more20stu.length
},
moreAge(state){//getters裏的方法只能有兩個參數,不接收第三個參數
return age => {return state.students.filter(s => s.age >age)}
},
fullName1(state){
return state.a.name + 'root中的name'
},
}
- /src/store/actions.js
export default {
aUpdateInfo(context, payload){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
context.commit('updateInfo')
console.log(payload);
resolve('裏面異步操作')
},1000)
})
}
}
- /src/store/modules/moduleA.js
export default {
state:{
name:'wo'
},
mutations:{
updateName(state,payload){
state.name = payload
}
},
getters:{
fullName(state,getters){
return getters.fullName1 + '模塊裏的name'
},//可以調用root中的getters
fullName3(state,getters,rootState){
//模塊中的getters方法可以有第三個參數
return getters.fullName + rootState.count
}
},
actions:{
//模塊actions中context指向本模塊 其中封裝有getters rootGetters
//rootState state
aUpdateName(context) {
setTimeout(()=>{
context.commit('updateName','wangwu')
},1000)
}
}
}