VUEX的簡單運用
什麼是vuex
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也整合到 Vue 的官方除錯工具 devtools extension,提供了諸如零配置的 time-travel 除錯、狀態快照匯入匯出等高階除錯功能
好的 完全看不懂
簡單來講,我們可以把一些貨物一起放在一個倉庫之中,可以讓我們與貨物的距離只有一條通道,當我們去存取貨物的時候,裡面的東西是共有的,大家都能公用,誰都可以往裡面進行存取操作
安裝、使用 vuex
npm install vuex --save
在src目錄下手動建立目錄檔案 vuex/store.js
在main.js中配置
import Vue from 'vue' import App from './App' import router from './router' import vuex from 'vuex' Vue.use(vuex) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
在vuex/store.js中配置
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex); //必不可少
const state={
count:1
}
export default new vuex.Store({ //暴露vuex.store
state
})
在需要呼叫的元件中引入
import store from '@/vuex/store' export default { store //一定要在例項中註冊 }
獲取store中的state
<template>
<div>
{{$store.state.count}} //1
</div>
</template>
此處提前說明一下moudle 模組組,隨著資料元件狀態越來越多,同寫一個檔案不好維護
新建一個js 暴露出來
export default {
state:{
count:1
}
}
在store.js中匯入
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
import states from './state'
export default new vuex.Store({
modules:{ //此引數固定
state:states
}
})
{{$store.state.state.count}}
//1
其實只是相當於多了一層匯入,方便我們呼叫維護狀態
回到開始
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
export default new vuex.Store({
state
})
簡單改變state
<template>
<div>
{{$store.state.count}}
<p>
<button @click="change">Change</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store'
export default {
store,
methods:{
change(){
this.$store.state.count++
}
}
}
</script>
<style>
</style>
強行改變vuex的state 是流氓行為(違法)
Vuex 使用單一狀態樹——是的,用一個物件就包含了全部的應用層級狀態。至此它便作為一個“唯一資料來源 (SSOT)”而存在。這也意味著,每個應用將僅僅包含一個 store 例項。單一狀態樹讓我們能夠直接地定位任一特定的狀態片段,在除錯的過程中也能輕易地取得整個當前應用狀態的快照。
簡單粗暴理解: 我們要把我們需要做狀態管理的量放到這裡來,然後在後面的操作動它
我們有了state狀態樹,我們要改變它的狀態(值),就必須用vue指定唯一方法 mutation
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字串的 事件型別 (type) 和 一個 回撥函式 (handler)。
簡單粗暴理解:任何不以mutation的方式改變state的值,都是耍流氓(違法)
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={ //簡單編輯操作state的mutations (固定寫法)
add(state){ //此處的state就是上面的state物件
state.count++;
},
reduce(state){
state.count--;
}
}
export default new vuex.Store({
state,mutations
})
在元件中呼叫mutations
<template>
<div>
{{$store.state.count}}
<p>
<button @click="$store.commit('add')">+</button> //此處的呼叫方法注意一下 是commit
//可不是$store.mutations.add
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store'
export default {
store,
}
</script>
<style>
</style>
此時已經可以通過按鈕通過mutations改變state了
在渲染vue的時候,根據鉤子函式生命週期渲染不同的DOM,一般情況下我們不用直接引用,而是賦值computed
computed屬性可以在輸出前,對data中的值進行改變,我們就利用這種特性把store.js中的state值賦值給我們模板中的data值。
export default {
store,
computed:{
count(){ //將狀態賦值給count
return this.$store.state.count;
}
}
}
相應的改變插值中的內容 效果不變
<template>
<div>
{{count}}
<p>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
此寫法稍微有些麻煩,資料多了更是繁瑣
vuex為我們提供了mapState操作
首先先引入mapState
import store from '@/vuex/store'
import {mapState} from 'vuex';
在computed中進行賦值 效果是一樣的 motations也可執行
computed:mapState({
count:state=>state.count
})
可能箭頭函式有點懵
computed:mapState({
count:function(state){
return state.count
}
})
接下來設定一下引數,方法肯定有時候帶引數的嘛 在store.js中
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){ =>此處增加了一個引數n
state.count+=n;
},
reduce(state){
state.count--;
}
}
export default new vuex.Store({
state,mutations
})
接下來只需要在呼叫mutation方法處傳入實參即可
<template>
<div>
{{count}}
<p>
<button @click="$store.commit('add',10)">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
類似開始的state 呼叫方法有些繁瑣 不喜歡看到$store.commit( )
模板獲取Mutations方法 vuex也為我們提供了相應的方法
import store from '@/vuex/store'
import {mapState,mapMutations} from 'vuex'; =>引入模板
方法 我們寫在methods中
methods:mapMutations([
'add','reduce'
]),
然後改變html 這樣就跟vue一樣啦
<template>
<div>
{{count}}
<p>
<button @click="add(10)">+</button>
<button @click="reduce">-</button>
</p>
</div>
</template>
getters計算過濾操作
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count--;
}
}
const getters = {
count:function(state){
return state.count +=100; =>類似filters 過濾得到state
}
}
export default new vuex.Store({
state,mutations,getters
})
在元件中獲取過濾之後的state
import store from '@/vuex/store'
import {mapState,mapMutations} from 'vuex';
export default {
store,
computed:mapState({
count:function(state){
return state.count
}
}),
methods:mapMutations([
'add','reduce'
]),
}
我們先分析一下當前程式碼
我們都知道程式碼屬性相同會覆蓋,也就是我如果在寫一次coumped屬性那麼上面的原有屬性將會覆蓋,此處運用es6的擴充套件運算子進行改寫
import store from '@/vuex/store'
import {mapState,mapMutations} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
count(){
return this.$store.getters.count;=>此時count是過濾後的state
}
},
methods:mapMutations([
'add','reduce'
]),
}
mapState通過擴充套件運算子將$store.state.count 對映this.count 這個this 很重要,這個對映直接對映到當前Vue的this物件上。(這句話不懂也可以記一下)
此時有測試的小夥伴可能發現 count是110 110 加的 而不是10 10 加的
因為當count發生改變的時候 先通過getters過濾得到新的state(此時已經+100) 然後由mutation改變+10
用mapGetters簡化模板寫法
import store from '@/vuex/store'
import {mapState,mapMutations,mapGetters} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
...mapGetters(["count"])
},
methods:mapMutations([
'add','reduce'
]),
}
其實這裡mapMutation也可以簡寫,我想大家知道怎麼寫了
actions非同步修改狀態
actions和之前講的Mutations功能基本一樣,不同點是,actions是非同步的改變state狀態,而Mutations是同步改變狀態。至於什麼是非同步什麼是同步這裡我就不做太多解釋了
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count--;
}
}
const getters = {
count:function(state){
return state.count +=100;
}
}
const actions ={
addAction(context){
context.commit('add',10) =>之前說過 mutation方法通過 commit呼叫 忘記了可以翻翻前面哦
},
reduceAction({commit}){
commit('reduce')
}
}
export default new vuex.Store({
state,mutations,getters,actions
})
這是兩處不同的引用mutations的方法
增加actions 當然 裡面的方法名是自定義的
context — {commit}
context:上下文物件,這裡你可以理解稱store本身。
{commit}:直接把commit物件傳遞過來,可以讓方法體邏輯和程式碼更清晰明瞭。
模板中使用actions
import store from '@/vuex/store'
import {mapState,mapMutations,mapGetters,mapActions} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
...mapGetters(["count"])
},
methods:{
...mapMutations(['add','reduce']),
...mapActions(['addAction','reduceAction'])
}
}
其實寫法太簡單了 練兩下就soeasy了
呼叫非同步方法名
<template>
<div>
{{count}}
<p>
<button @click="addAction">+</button>
<button @click="reduceAction">-</button>
</p>
</div>