Vuex 是一個專門為 Vue.js 應用所設計的集中式狀態管理架構。
官方文檔:http://vuex.vuejs.org/zh-cn/ 2.0和1.0都能在此找到
每一個 Vuex 應用的核心就是 store(倉庫)。"store" 基本上就是一個容器,它包含着你應用里大部分的 狀態(即 state). Vuex 和單純的全局對象有以下兩點不同:
1. Vuex 的狀態存儲是響應式的. 當 Vue 組件從 store 中讀取狀態的時候, 若 store 中的狀態發生變化,那么相應的組件也會相應地高效地得到更新.
2. 你不能直接改變 store 中的狀態。改變 store 中的狀態的唯一途徑就是顯式地分發 狀態變更事件(explicitly dispatching mutations)。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。
二話不說,先來個簡單的。本文先后步驟與官網不太一樣
創建store
創建 Vuex store 的過程相當直截了當 - 只要提供一個初始化的 state 對象,以及一些 mutations:
vuex/store.js
import Vue from 'vue' import Vuex from 'vuex' //使用vuex Vue.use(Vuex) //創建一個對象來保存應用啟動時的初始狀態 const state = { serviceUrl:"http://192.168.20.166:8989/rest/",//接口地址,請求數據時使用 city:{'city':'成都','id':'2'}//城市對象,本示例中有時候請求數據需要提供站點id } // 創建一個對象存儲一系列我們接下來要寫的 mutation 函數 const mutations = { // TODO: 放置我們的狀態變更函數 } // 整合初始狀態和變更函數,我們就得到了我們所需的 store // 至此,這個 store 就可以連接到我們的應用中 export default new Vuex.Store({ state, mutations })
創建action
創建一個新文件 vuex/actions.js
這地方我們先不寫actions,暫時不需要。
獲取值
創建一個新文件 vuex/actions.js
//這個getter函數會返回store.js里state中的值 export function getUrl (state) { return state.serviceUrl//返回serviceUrl的值 } export function getCity (state) { return state.city//返回city對象 }
現在,我們在組件中加入這個getter 函數
拿vue-router中列表跳轉詳情的示例來做修改(http://www.cnblogs.com/jyichen/p/5660865.html)

<div class='box'> <div class='know-list-box'> <ul> <li v-for="item in alllist"> <a v-link="{ name: 'getReceiptDetail',params:{id: item.id }}"> <div class='fl know-info'> <p class='font-normal nomal-height'>{{item.title | limit 30 }}</p> <p class='co9a9a9a' ><span style='margin-right: 1rem;'>{{item.viewTimes}}K</span><span>{{item.publishTime | timer }}</span></p> </div> <div class='fr know-img'> <img v-bind:src=item.coverImage /> </div> <div class='clearfix'></div> </a> </li> </ul> </div> </div> <script> import limit from '../fitter/limit.js' //導入getter import { getUrl,getCity } from '../vuex/getter.js' export default{ vuex: { getters: { // 注意在這里需要的是 `getUrl、getCity` 函數本身而不是它的執行結果 'getUrl(),getCity()' baseUrl:getUrl, city:getCity }, }, data(){ return{ toplist:[], alllist:[], } }, route:{ data({to}){ return Promise.all([ this.$http.get(this.baseUrl+'knowledge/list',{'websiteId':this.city.id,'pageSize':5,'pageNo':1,'isTop':1}), this.$http.get(this.baseUrl+'knowledge/list',{'websiteId':this.city.id,'pageSize':20,'pageNo':1,'isTop':0}), ]).then(function(data){ return{ toplist:data[0].data.knowledgeList, alllist:data[1].data.knowledgeList } },function(error){ //error }) } }, ready(){ } } </script>
但是這時候請求不到,查看瀏覽器NetWork會發現地址前綴是自己本機的ip和端口,因為
要在根組件注入store,此時我們修改app.vue(源代碼在文章vue-router中:http://www.cnblogs.com/jyichen/p/5660865.html)
app.vue
<template> <div class='container'> <router-view class="view" keep-alive transition="slide"></router-view> </router-view> </div> </template> <script> //在根組件加入 store,讓它的子組件和 store 連接 import store from './vuex/store' export default { store: store //也可以這樣寫:store } </script>
此時它應該能正常工作了。
例:使用action
需求:默認count的值為0,點“+”的時候count的值+1,點“-”的時候,count的值-1。如圖
圖:
修改vuex/store.js,添加一個count的初始值,
import Vue from 'vue' import Vuex from 'vuex' //使用vuex Vue.use(Vuex) //創建一個對象來保存應用啟動時的初始狀態 const state = { serviceUrl:"http://192.168.20.166:8989/rest/", city:{'city':'成都','id':'2'}, count:0 } // 創建一個對象存儲一系列我們接下來要寫的 mutation 函數 const mutations = { } // 整合初始狀態和變更函數,我們就得到了我們所需的 store // 至此,這個 store 就可以連接到我們的應用中 export default new Vuex.Store({ state, mutations })
創建action
action 是一種專門用來被 component 調用的函數。action 函數能夠通過分發相應的 mutation 函數,來觸發對 store 的更新。action 也可以先從 HTTP 后端或 store 中讀取其他數據之后再分發更新事件。
創建一個新文件 vuex/actions.js,然后寫入兩個函數 incrementCounter和decrementCounter:
// action 會收到 store 作為它的第一個參數 export function incrementCounter(store,val){ store.dispatch('INCREMENT',1) } export function decrementCounter(store,val){ store.dispatch('DECREMENT',1) }
創建mutation
在我們的 vuex/actions.js 文件里我們 dispatch了兩個mutation,分別叫INCREMENT和DECREMENT,但是我們還沒有寫它所對應的具體操作。我們現在就來做這個事。
修改vuex/store.js
import Vue from 'vue' import Vuex from 'vuex' //使用vuex Vue.use(Vuex) //創建一個對象來保存應用啟動時的初始狀態 const state = { serviceUrl:"http://121.42.159.121:9080/rest/", city:{'city':'成都','id':'2'}, count:0 } // 創建一個對象存儲一系列我們接下來要寫的 mutation 函數 const mutations = { // mutation 的第一個參數是當前的 state // 可以在函數里修改 state INCREMENT (state,amount){//增量 state.count = state.count + amount }, DECREMENT (state,val){//減量 state.count = state.count - val } } // 整合初始狀態和變更函數,我們就得到了我們所需的 store // 至此,這個 store 就可以連接到我們的應用中 export default new Vuex.Store({ state, mutations })
獲取值
修改vuex/actions.js 加入getCount
//這個getter函數會返回store.js里state中的值 export function getUrl (state) { return state.serviceUrl//返回serviceUrl的值 } export function getCity (state) { return state.city//返回city對象 } export function getCount(state){ if(state.count <= 0){ return state.count=0 }else{ return state.count } }
使用
<template> <div class='box-content'> <p>測試vuex</p> <h3>Count is {{counterValue}}</h3> <button @click='increment'>Increment +1</button> <button @click='decrement'>Increment -1</button> <p> </p> </div> </template> <script> import { getCount } from '../vuex/getter.js' import { incrementCounter,decrementCounter } from '../vuex/action.js' export default{ vuex:{ getters:{ counterValue:getCount }, actions:{ increment:incrementCounter, decrement:decrementCounter } } } </script>
例:從HTTP后端讀入數據后分發更新事件
token身份驗證
vuex/store.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { token: ' ' } const mutations = { SETTOKEN(state,val){ state.token = val; if(window.localStorage){//如果支持localStorage就存到localStorage var storage = window.localStorage; storage.setItem('TOKEN',val) } } } export default new Vuex.Store({ state, mutations })
vuex/actions.js
export function setTokenAction (store,val) { store.dispatch('SETTOKEN', val); }
vuex/getters.js
export function getToken(state){ if(state.token == ''){ return window.localStorage.getItem('TOKEN'); }else{ return state.token; } }
頁面上使用
<template> <div> <input type="text" placeholder='請輸入用戶名' v-model="username"> <input type="text" placeholder='請輸入密碼' v-model="userpass"> <a v-on:click="sendLogin()" class='greenBtn'>登陸</a> </div> </template> <script> import { setTokenAction } from '../vuex/action.js' export default{ vuex:{ actions:{ setTokenAction:setTokenAction } }, data(){ return{ username:'', userpass:'' } }, methods:{ sendLogin(){ var that = this ; that.$http.post('http:192.168.20.166:8989/user/login',{'account':telephones,'pwd':pwd}).then(function(data){ //登錄成功 if(data.data.code == '0'){ //data.data.token 服務端返回的token, 存到localStorage //setTokenAction 觸發actions中的setTokenAction dispatch //setTokenAction dispatch觸發mutations中的SETTOKEN //SETTOKEN修改state中的值 setTokenAction(that.$store,data.data.token); } }) } } } </script>
import { getToken } from '../vuex/getter.js'
vuex:{
getters:{
token:getToken
},
actions:{
setTokenAction:setTokenAction
}
}