您好,登錄后才能下訂單哦!
一、概覽
1、Vuex是什么
二、Vuex核心概念
1、store:類似容器,包含應用的大部分狀態
三、使用Vuex
1、安裝Vuex模塊
npm install vuex --save
2、作為插件使用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
3、定義容器
let store = new Vuex.Store({
state:{
count:100
},
mutations:{ //對象,里面是各種更改state狀態值的函數,同步立即更改狀態
add( state,payload ){ //參數state就是上面的state,payload是要傳遞的值
state.count+=payload.n;
}
},
actions:{ //異步更改狀態,可以是ajax請求成功之后改變狀態,這里用定時器模擬,1秒鐘之后提交mutations改變狀態
//異步的更改狀態是直接在index.js里面的actions里面定義action然后commit的(附帶參數),而不是在組件內提交,注意區別,異步是在組件內dispatch這個actions(actions里面已經包含了mutations),同步是在組件內commit這個mutations(附帶參數)
//異步也可以在index.js里面直接dispatch這個actions(附帶參數),在第一個ajax里面接著請求第二個ajax
addAction( context ){ //ajax1
setTimeout(function(){
context.commit('add',{n:200}); //這里用的mutations還是上面定義的add
context.dispatch('textAction',{test:'測試'}) //觸發ajax2
},1000)
}
textAction( context,obj ){ //ajax2
console.log(obj)
}
//利用es6解構賦值改寫上面的代碼,因為context對象下面有commit和dispatch方法
addAction( {commit,dispatch} ){
setTimeout(function(){
commit('add',{n:200}); //直接可以獲取到commit方法,不用是context.commit
dispatch('textAction',{test:'測試'})
},1000)
}
textAction( context,obj ){ //ajax2
console.log(obj)
}
},//異步更改狀態,一段時間之后再改變狀態,只要是異步的改變都寫在actions里面
getters:{ //類似計算屬性,對狀態做進一步的處理
filterCount(state){
return state.count>=120?120:state.count++;
}
}
})
export default store
4、注入根實例
import store from './store'
new Vue({
store
})
5、在state里面定義的是狀態,如果在組件內部要使用這個狀態,那么一般在組件內部通過計算屬性來得到它
<button @click="addHandle()"></button>
<p>{{count}}</p>
<p>{{count2}}</p>
computed:{
count(){
return this.$store.state.count
},
count2(){
return this.$store.getters.filterCount //被getters進一步處理過的狀態
}
},
methods:{
addHandle(){ //要動態的改變狀態,就需要顯示的提交一個mutations —> add
//同步,寫法一
this.$store.commit('add',{n:10})
//同步,寫法二
this.$store.commit({
type:'add',
n:5
})
//異步,寫法
this.$store.dispatch('addAction')
}
}
6、context是一個對象,不是state實例
7、使用輔助函數
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
//這是改寫state和getters
computed:{
num(){
return this.$store.state.count
},
num2(){
return this.$store.getters.filterNum
}
}
computed:mapState({
num:state => state.count
num:'count'
num(state){
return state.count+100
}
count:'count' //此時渲染的是count,不是num
})
computed:{
abc(){
return 123
},
...mapGetters({
num2:'filterCount' //如果key值(即要渲染到頁面的變量值)和vuex里面定義的是一樣的,那么就可以是下面那種寫法
}),
...mapState(['count']) //count:count count是要渲染到頁面 state:{count:100},state里面定義的狀態名也是count
}
//這是改寫actions和mutations
methods:{
add(){ //異步actions
this.$store.dispatch('addAction')
}
},
reduce(){ //普通mutations,參數可以直接跟在對象里
this.$store.commit({
type:'reduceMutation',
n:10
})
}
methods:{
...mapActions({
add:'addAction' //add是頁面點擊函數,addAction是vuex里面定義的action
})
...mapMutations({ //這種方法要傳參,只能是在調用的時候傳進去
reduce:'reduceMutation'
})
}
<input type="button" value="-" @click="reduce({n:10})"> 參數在這里傳,和普通寫法不同
四、案例
**index.js**
let store = new Vuex.Store({
state:{ //對象,應用所需要的狀態數據都放在這里面
count:100
},
mutations:{ //對象,顯示的同步提交mutations,狀態是點擊之后立即改變
addIncrement(state,payload){ //這里是自定義addIncrement事件
state.count+ = payload.n
}
},
actions:{ //異步的改變狀態,比如發送請求成功之后才改變狀態,不是即時的改變
addAction( context ){ //這里新加自定義事件addAction
setTimeout( ()=>{ /模擬異步操作
//改變狀態,提交mutations,仍然是上面mutations里面定義的事件addIncrement
context.commit('addIncrement',{n:15})
context.dispatch('textAction',{test:'測試'}) //這里執行該異步操作
},1000 )
},
textAction(context,obj){ //定義第二個異步操作
console.log(obj) //{test:'測試'}
},
getListAction( context ){ //這里定義了異步接口action,在子組件created里面調用
axios.get('url')
.then( (data)=>{
console.log(data); //得到了接口數據
} )
}
},
getters:{ //對store里面的數值進行邏輯操作
filterState(state){
return state.count>=120?120:state.count
}
}
})
export default store
**increment組件:**
<template>
<p>{{num}}</p>
<span>{{filterNewNum}}</span>
<input type="button" value="+" @click="addHandle" />
</template>
<script>
computed:{
num(){
rerurn this.$store.state.count //接收原始狀態值
},
filterNewNum(){ //這里面接收過濾后的,倉庫里面的數據
return this.$store.getters.filterState //注意是return,不要漏了
}
},
methods:{
addHandle(){ //改變狀態,提交一個mutations
this.$store.commit('addIncrement',{ //這里是commit addIncrement
n:5 //參數
});
}
//這里是異步觸發一個action,注意和上面同步的不同之處
this.$store.dispatch('addAction') //這里是dispatch addAction
},
created(){
this.$store.dispatch('getListAction'); //dispatch
}
也可以這樣寫:
methods:{
addHandle(){
this.$store.commit({
type:'addIncrement', //改變的狀態類型
n:5 //參數
})
}
}
</script>
//上面是同步操作數據,使用mutations,如果要異步操作數據,就用到Actions,注意,不管是同步還是異步操作,改變數據前都得先提交mutations
//向后端發送ajax請求就放在Actions里面。在methods里面創建方法,通過axios獲取數據,然后更新到store里面定義的變量,這一系列操作都在index.js文件里面完成
如果要對store里面的數值進行邏輯判斷(數據過濾、數據的加減乘除),那么就用到getters,用法類似于計算屬性computed,getters可以看做是Vuex的計算屬性
在Store倉庫里,state就是用來存放數據,在Vue里面若是對數據進行處理輸出,比如數據要過濾,一般我們可以寫到computed中。但是如果很多組件都使用這個過濾后的數據,比如餅狀圖組件和曲線圖組件,我們是否可以把這個數據抽提出來共享?這就是getters存在的意義。我們可以認為,【getters】是store的計算屬性。因為getters是對數據進行邏輯運算,而不是新添加的方法或功能,僅僅是是數據的邏輯運算,所以要始終返回一個新值,可以先在getters下面的方法里面定義一個新值變量,經過計算,然后return出這個新變量
五、Vuex輔助函數
使用這些輔助函數,首先需要引入vuex,這些都是vuex下面的方法,使用解構賦值
import { mapState } from 'vuex'
mapState
mapGetters
mapMutations
mapActions
改寫上面的代碼:
Increment.vue組件
<template>
<p>{{count}}</p>
<span>{{filterNum}}</span>
<input type="button" value="+" @click="add" />
<input type="button" value="-" @click="reduce({n:11})"/>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
export default {
data(){
},
computed:{
abc(){
return 123 //普通的計算屬性
},
...mapState(['count']) //這里的count就是store里面定義的倉庫里面的count
...mapGeters(['filterNum']) //從getters里面取值(經過邏輯處理的值)
},
methods:{
/*reduce(){ //同步觸發action
this.$store.commit('reduceAction',{n:5}) //同步每次減5
}*/
...mapMutations({ //改寫mutations,要傳參,參數在模板里面添加reduce({n:11})
reduce:'reduceAction'
})
/*add(){ //異步觸發actions
this.$store.dispatch('addAction')
}*/
...mapActions({ //改寫actions
add:'addAction'
})
}
}
</script>
index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let store = new Vuex.Store({
state:{
count:100
},
mutations:{
addHandle(state,payload){ //payload是參數
state.count+=payload.n;
},
reduceAction(state,payload){
state.count-=payload.n
}
},
actions:{
addAction(context){
setTimeout(()=>{
context.commit('addHandle',{n:15}) //異步每次加15
},1000)
}
},
getters:{
filterNum(state){
return state.count>=102?102:state.count
}
}
})
export default store
六、在vue-cli里面使用Vuex
1、npm install vuex --save
2、在src目錄下面新建store文件夾,里面新建index.js
3、store/index.js代碼:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
let store = new Vuex.Store({
state:{
shopCarData:[] //購物車的數據默認數據格式是數組,使用Vuex對這個數組進行操作
},
mutations:{
addShopCarData(state,data){
//do something
}
},
getters:{
}
})
export default store
4、main.js代碼
import store from './store'
new Vue({
el:'#app',
router,
store,
template:'<App/>',
components:{
App
}
})
七、vuex使用心得1、在state里面定義全局共用的狀態數據,state是一個對象,里面定義鍵值對,在組件頁面,獲取state狀態值,通過computed計算屬性來獲取
2、即時修改state狀態值,通過提交mutations來進行,mutations是一個對象,里面定義各種修改state狀態值的方法,方法接收state和payload兩個參數
3、異步修改state狀態值,通過actions來獲取數據,然后也要通過提交mutations來修改state里面定義的狀態值
用的較多的是通過axios來獲取遠程數據,然后在then方法里面commit一個mutations來修改state里面的原始狀態值,mutations要先定義
在created(){}里面通過this.$store.dispatch('fetchDataAction')來執行這個actions,
定義@click方法來即時提交mutations,
br/>1、在state里面定義全局共用的狀態數據,state是一個對象,里面定義鍵值對,在組件頁面,獲取state狀態值,通過computed計算屬性來獲取
2、即時修改state狀態值,通過提交mutations來進行,mutations是一個對象,里面定義各種修改state狀態值的方法,方法接收state和payload兩個參數
3、異步修改state狀態值,通過actions來獲取數據,然后也要通過提交mutations來修改state里面定義的狀態值
用的較多的是通過axios來獲取遠程數據,然后在then方法里面commit一個mutations來修改state里面的原始狀態值,mutations要先定義
在created(){}里面通過this.$store.dispatch('fetchDataAction')來執行這個actions,
定義@click方法來即時提交mutations,
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。