目錄:
- 簡介
- Vuex原理圖
- 基本用法
一、簡介
1.1、Vuex的概念和作用
Vuex 是一個專為 Vue.js 引用程序並發的狀態管理模式,它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式放生變化。簡單來說:Vuex是用來集中管理數據,類似於React中的Redux(回來,回家),都是基於Flux(融化了)的前端狀態管理框架。Vuex 一般小項目,寫兩個頁面是用不到的,但是中大型項目是需要用到的。
1.2、訪問Vuex官網方式
1.Vuex的官網:https://vuex.vuejs.org/zh/
2.也可以通過 Vue.js 官網進入 Vuex的官網:生態系統 -> 核心插件 -> Vuex
1.3、什么是組件狀態?
比如說你的組件會有不同的狀態,這個狀態比如說顯示或者隱藏,或者你的數據的需要展示,你的數據管理等等,都可以使用Vuex來操作。
1.4、Vuex在集中管理數據起到什么作用?
集中管理數據的,你的項目當中很多數據需要管理,包括你的組件間需要數據的傳遞,傳遞的方式我們也可以用不同的方式,如:父子組件的數據傳遞(props和觸發事件),非父子組件的數據傳遞(中央總線方式)。但是如果說你的項目太復雜,以組件的方式傳遞數據,用這種方式特別費勁,而且很亂。項目真的變大了之后,這種單線傳遞太麻煩了,所以現在基本都用Vuex。但是你的項目很簡單,沒有必要使用Vuex。
二、Vuex的原理圖
這個原理圖在官網也有,只不過我說明了一下。官網管理圖
原理圖說明:
1. Vue組件上操作,會發出(dispatch)一個動作(actions) -> 2. 提交(commit) 改變(mutation)的數據 -> 3.突變或者說改變(mutate) 狀態(state)中的數據 -> 4.改變之后,重新渲染(render)組件(Vue Components) ->5.組件就會更新,展示更新過后的數據。
三、基本使用
3.1、安裝Vuex
>npm install vuex -S
3.2、目錄結構
|-vuex-demo |-node-modules |-src |-assets |-App.vue |-main.js |-store.js //vuex的相關配置都在store.js中 |-.babelrc |-... |-webpack.config.js
3.3、創建store.js文件,在main.js中導入並且配置store對象
說明:Vuex的相關配置都在這個里面配置的
import Vue from 'vue' import App from './App.vue' import store from './store.js' //導入store對象 new Vue({ el: '#app', render: h => h(App), //配置store選項,指定為store對象,會自動將store對象注入到所有子組件中(Vue實例是根組件,其他的都是子組件),在子組件中通過this.$store訪問store對象 store //(縮寫) store:store,導入Vuex后就有store這么一個選項,store值就是你導入的store });
注意了:Vue實例是根組件,Vue實例下注冊的組件,都是vue根組件下的子組件。
3.4、編輯 store.js
Vuex的核心是store(倉庫),相當於一個容器,一個store實例中包含以下屬性方法:
state: 定義屬性(狀態、數據) getters: 用來獲取屬性 actions: 定義方法(動作) commit: 提交變化,修改數據的唯一方式就是現實的提交mutations mutations: 定義變化(或突變),來改變數據
注:不能直接修改數據,必須是顯式提交變化,目的是為了追蹤到狀態的變化
store.js的內容(方式1:通過this.$store訪問) :
/* * Vuex 配置 * */ import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); //1.定義屬性(數據) var state={ count:6 }; //2.創建store對象 const store = new Vuex.Store({ state //(縮寫) state:state }); //3.導出store對象 export default store;
store.js的內容(方式2:通過mapGetters、mapActions訪問) :
/* * Vuex 配置 * */ import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); //1.定義屬性(數據) let state={ count:6 }; //2.定義getters let getters = { count(state){ //參數state就是上面的state return state.count; } }; //3.定義actions,要執行的操作,如流程判斷,一部請求等 const actions = { /*increment(context){ //對應的increment的就是App.vue中綁定的事件 console.log(context); }*/ increment({commit,state}){ //es6的語法 commit('increment'); //提交(commit)一個名為increment的變化,名稱自定義,可以認為是類型名 } }; //4.定義mutations處理狀態(數據)的改變 const mutations = { increment(state){ //increment函數名必須跟 actions中的commit是一樣的 state.count++; } }; //5.創建store對象 const store = new Vuex.Store({ state, //(縮寫) state:state getters, actions, mutations }); //6.導出store對象 export default store;
我們先來看看actions是中的context有哪些東西:
▼{getters: {…}, state: {…}, rootGetters: {…}, dispatch: ƒ, commit: ƒ, …} ▶dispatch: ƒ boundDispatch(type, payload) ▶commit: ƒ boundCommit(type, payload, options) ▶getters: {} ▶state: {__ob__: Observer} ▶rootGetters: {} ▶rootState: {__ob__: Observer} ▶__proto__: Object
很明顯是一個對象,但是我們用es6的語法使用,不然用起來比較麻煩!!!
3.5、編輯App.vue
在子組件中訪問store對象的兩種方式:
方式1:通過this.$store訪問
方式2:通過MapState、mapGetters、mapActions訪問,Vuex提供了2個方法:
MapState:獲取state mapGetters: 獲取getters,獲取屬性(數據) mapActions: 獲取actions,獲取方法(動作)
App.vue編輯(方式1:通過this.$store訪問)
<template> <div id="app"> <!--獲取計算屬性count--> <p>當前數據為:{{count}}</p> </div> </template> <script> export default { name: 'app', //方式1: 通過this.$store訪問 computed:{ count(){ return this.$store.state.count; } } } </script>
App.vue編輯(通過mapGetters、mapActions訪問)
<template> <div id="app"> <!--觸發事件--> <button @click="increment">增加</button> <!--獲取數據--> <p>當前數據為:{{count}}</p> </div> </template> <script> //先導入mapState(匹配state),mapGetters(匹配屬性),mapActions(匹配方法)方法 import {mapState,mapGetters,mapActions} from 'vuex' export default { name: 'app', //方式2:通過mapGetters、mapActions訪問 //computed:mapGetters([ // 'count' //對應的store.js中的getters中的count()方法 //]), computed:mapState([ 'count' //對應就是state中的count ]), methods:mapActions([ 'increment' //匹配store.js中的actions中的increment方法 ]) } </script>
通過mapState或者mapGetters都可以獲取count值,這個就要看你喜歡用什么了,只不過mapState是直接獲取 state中的值,而mapGetters是通過定義方法獲取,而且用getters,來獲取處理過的數據不一定就是直接的count,例子下面代碼練習有。
3.6、Vuex的練習所有代碼
說明:main.js就直接引用上面的,其他的完整練習代碼如下,這邊特別注意的是:我們在調代碼的時候 可以 配合 vue-devtools 配合使用,使用方法:1-1 基本用法-第一個vue程序
1、App.vue組件
<template> <div id="app"> <button @click="increment">增加</button> <button @click="decrement">減少</button> <button @click="incrementAsync">增加</button> <!--獲取數據--> <p>當前數據為:{{count}}</p> <p>{{isEvenOrOdd}}</p> </div> </template> <script> import {mapState,mapGetters,mapActions} from 'vuex' export default { name: 'app', //方式2:通過mapGetters、mapActions訪問 computed:mapGetters([ 'count', //對應的store.js中的getters中的count()方法 'isEvenOrOdd' ]), // computed:mapState([ // 'count' //對應就是state中的count // ]), methods:mapActions([ 'increment', 'decrement', 'incrementAsync' ]) } </script> <style> </style>
2、store.js代碼:
/* * Vuex 配置 * */ import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); //1.定義屬性(數據) let state={ count:6 }; //2.定義getters let getters = { count(state){ //參數state就是上面的state return state.count; }, isEvenOrOdd(state){ //getters,來獲取處理過的數據不一定就是直接的count return state.count%2 == 0?'偶數':'奇數'; } }; //3.定義actions,要執行的操作,如流程判斷,一部請求等 const actions = { /*increment(context){ //對應的increment的就是App.vue中綁定的事件 console.log(context); }*/ increment({commit,state}){ //es6的語法 commit('increment'); //提交(commit)一個名為increment的變化,名稱自定義,可以認為是類型名 }, decrement({commit,state}){ //在提交條件這邊做判斷 if(state.count>10){ commit("decrement"); } }, incrementAsync({commit,state}){ //異步操作 let p = new Promise((resolve,reject) => { setTimeout(() => { resolve(); },3000); }); p.then(()=> { commit('increment'); //狀態改變可以是同一個操作 }).catch(() => { console.log('異步操作'); }); } }; //4.定義mutations處理狀態(數據)的改變 const mutations = { increment(state){ //increment函數名必須跟 actions中的commit是一樣的 state.count++; }, decrement(state){ state.count--; } }; //5.創建store對象 const store = new Vuex.Store({ state, //(縮寫) state:state getters, actions, mutations }); //6.導出store對象 export default store;
實現界面如下:
當前數據為:6
偶數