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
}
}