vue---vuex

vuex是一個專爲vue.js應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue

1、npm安裝webpack

npm install vuex --save

 

2、配置:全局配置web

當咱們使用vue腳手架來搭配vue開發環境時,vuex全局該如何配置呢?vuex

(1)首先咱們在項目的src文件下建立一個store文件夾,在store文件夾下新建一個store.js文件,來建立咱們的storenpm

(2) 在全局main.js文件下來全局配置緩存

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/store.js' //引入store

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store, //把store實例註冊到根組件中,這樣全部的子組件均可以用
  components: { App },
  template: '<App/>;'
})

 

3、來簡單講一下vuex的一些比較經常使用到的4個核心概念:state、getter、mutation、actionapp

(1)state異步

每一個vuex應用的核心就是store(倉庫)。說白了,‘store’它就像一個倉庫、一個容器,用它來存儲應用中的態狀(state)。即此,它包含着你的應用中大部分的狀態。 函數

下面介紹一下vuex與單純的全局對象有如下兩點不一樣:ui

1.vuex的狀態存儲是響應式的,當vue組件從store中讀取狀態的時候,若store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。

2.咱們不能直接去改變 store中的狀態(改變store中的狀態,其實就是改變store中的值)。想要改變store中的狀態的惟一途徑就是顯式地提交(commit)mutation。

接下來,咱們去建立一個簡單的state

store.js 文件中:

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
	state: {
		count: 0,
		numbers: 99
	}
})

export default store;

在各個組件中咱們該怎麼去訪問呢?例如,

HelloWorld.vue:

<template>
	<div class="hello">
		<button @click="onClick">點擊</button>
	</div>
</template>

<script>
	export default {
		name: 'HelloWorld',
		data() {
			return {
				
			}
		},
		methods: {
			onClick(){
				console.log(this.$store.state.count);//咱們能夠經過this.$store.state來訪問				
			}
		}
	}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

(2)getter

vuex容許咱們在store中定義'getter'(getter能夠認爲是store的計算屬性),就像計算屬性同樣,getter的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。

下面咱們建立一個getter:

getter它會接收state做爲第一個參數

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
	state: {
		count: 0,
		numbers: 99
	},
	getters: {
		doneTodos(state) { 傳入的state參數,其就是store中的state,也就是咱們存儲的狀態(state)
			return state.count;
		}
	}
})

export default store;

getter會暴露爲store.getters對象,因此咱們能夠經過它(store.getters)以屬性的形式來訪問這些值:

<template>
	<div class="hello">
		<button @click="onClick">點擊</button>
	</div>
</template>

<script>
	export default {
		name: 'HelloWorld',
		data() {
			return {

			}
		},
		methods: {
			onClick(){
				console.log('mm',this.$store.getters.doneTodos); // 0
				
			}
		}
	}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

getter還能夠接收其餘的getter做爲第二個參數:

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
	state: {
		count: 10,
		numbers: 99
	},
	getters: {
		num(state) {//其餘的getter
			return state.numbers;
		},
		doneTodos(state, num) {//接收其餘的getter做爲第二個參數
			return state.count;
		}
	}
})

export default store;

3.mutation

以前咱們說過,不能直接去更改store中的狀態,也就是不能直接去更改state中的值,更改vuex的store中的狀態的惟一方法就是提交mutation;

vuex中的mutation,它很是相似於事件:每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler),這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受state做爲第一個參數。

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
	state: {
		count: 10,
		numbers: 99
	},
	getters: {
		num(state) {
			return state.numbers;
		},
		doneTodos(state, num) {
			return state.count;
		}
	},
	mutations: {
		increment(state) {
			state.count ++;
		}
	}
})

export default store;

如今咱們去觸發mutation handler,來改變store中的狀態,可是咱們又不能直接去調用一個mutation handler。這個選項更像是事件註冊:‘當觸發一個類型爲increment的mutation時,調用此函數’,因此,要觸發一個mutation handler,你須要以相應的type調用store.commit方法:

<template>
	<div class="hello">
		<button @click="onClick">點擊</button>
	</div>
</template>

<script>
	export default {
		name: 'HelloWorld',
		data() {
			return {

			}
		},
		methods: {
			onClick(){
				this.$store.commit('increment');				
			}
		}
	}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

同時mutation除了接收state做爲第一個參數外,它還能夠額外的參數,

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
	state: {
		count: 10,
		numbers: 99
	},
	getters: {
		num(state) {
			return state.numbers;
		},
		doneTodos(state, num) {
			return state.count;
		}
	},
	mutations: {
		increment(state, m) { //m爲傳入的第二個參數
			state.count += m;
		}
	}
})

export default store;

怎麼去調用呢,其實和以前的同樣,一樣調用store.commit()方法

<template>
	<div class="hello">
		<button @click="onClick">點擊</button>
	</div>
</template>

<script>
	export default {
		name: 'HelloWorld',
		data() {
			return {

			}
		},
		methods: {
			onClick(){
				this.$store.commit('increment',80);//第二個參數80其實就是參數m的值			
			}
		}
	}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

⚠️mutation必須是同步的

4.action

咱們知道mutation是同步的,因此在mutation中混合異步調用會致使你的程序很難調試,因此action能夠幫助咱們處理異步操做。

action相似於mutation,不一樣在於:

(1)action提交的mutation,而不是直接去改變狀態。

(2)action能夠包含任意異步操做

下面咱們來註冊一個簡單的action:

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
	state: {
		count: 10,
		numbers: 99
	},
	getters: {
		num(state) {
			return state.numbers;
		},
		doneTodos(state, num) {
			return state.count;
		}
	},
	mutations: {
		increment(state, m) {
			state.count += m;
		}
	},
	actions: {
		textClick(context) {
			context.commit('increment');
		}
	}
})

export default store;

action函數會接受一個與store實例具備相同方法和屬性的context對象(並不是必定是context,能夠是任意參數),context相似於store,你能夠把context看成store,但二者仍是有區別的。

這樣的話你就能夠調用context.commit來提交mutation,或者也能夠經過context.state和context.getters來獲取state和getters。

咱們經過前面能夠知道,mutation經過store.commit()來觸發回調函數,那麼action又是經過什麼呢?

action經過store.dispatch方法觸發:

<template>
	<div class="hello">
		<button @click="onClick">點擊</button>
	</div>
</template>

<script>
	export default {
		name: 'HelloWorld',
		data() {
			return {

			}
		},
		methods: {
			onClick(){
				this.$store.dispatch('textClick');		
			}
		}
	}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

先更新到這吧,回頭繼續補充!!!!

本站公眾號
   歡迎關注本站公眾號,獲取更多信息