vuex 基础
安装
直接下载 / CDN 引用
Unpkg.com 提供了基于 NPM 的 CDN 链接。以上的链接会一直指向 NPM 上发布的最新版本。您也可以通过 https://unpkg.com/vuex@2.0.0 这样的方式指定特定的版本。
在 Vue 之后引入 vuex 会进行自动安装:
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>
NPM
npm install vuex --save
Yarn
yarn add vuex
在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
当使用全局 script 标签引用 Vuex 时,不需要以上安装过程。
自己构建
如果需要使用 dev 分支下的最新版本,您可以直接从 GitHub 上克隆代码并自己构建。
git clone https://github.com/vuejs/vuex.git node_modules/vuex
cd node_modules/vuex
npm install
npm run build
Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
状态【数据】管理
由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长。
为了解决这个问题,Vue 提供 vuex:我们有受到 Elm 启发的状态管理库。
vuex 甚至集成到 vue-devtools,无需配置即可访问时光旅行。
<div id="app"></div>
<template id="tpl">
<div>
<tip :num="count"></tip>
<input type="button" value="+" @click="count++"/>
<input type="button" value="-" @click="count--"/>
</div>
</template>
<!-- 状态 【数据】管理
data -->
<script>
new Vue({
el:"#app",
//state
data () {
return {
count: 0 //状态
}
},
//view
template:"#tpl",
components:{
tip:{
props:["num"],
template:"<div>{{num}}</div>"
}
}
});
</script>
vuex有6个概念
Store 用来存储数据(状态)
安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutations:
var store = new Vuex.Store({
state:{
count:0
},
mutations:{
jia:function(state){
state.count++;
},
jian(state){
state.count--;
}
}
});
store.commit("jia");
store.commit("jia");
store.commit("jia");
console.log(store.state.count);
可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:
store.commit("jian");
store.commit("jian");
console.log(store.state.count);
我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。
// store 用来存储数据(状态)
state:{
count:1
}
// 通过 mutations 改变数据
mutations:{
jia(state){
}
}
// 读数据
store.state.count
State 数据
那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:
var store=new Vuex.Store({
state:{
count:0
},
mutations:{
jia(state){
state.count++;
},
jian(state){
state.count--
}
}
});
new Vue({
el:"#app",
template:"#tpl",
components:{
tip:{
template:"<div>{{$store.state.count}}</div>"
},
oper:{
template:`<div><input type="button" value="+" @click="$store.commit('jia')"/>
<input type="button" value="-" @click="$store.commit('jian')"/></div>`
}
},
store
});
Getters 计算属性
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
Vuex 允许我们在 store 中定义getters(可以认为是 store 的计算属性)。就像计算属性一样,getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
Mutations 改变数据
mutations 与事件类似,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。所以 mutations 上存放的一般就是我们要改变 state 的一些方法。
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment' // 映射 this.increment() 为 this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
})
}
}
Actions
在mutation 中混异步调用会导致你的程序很难调试。
Action 类似于 mutation,不同在于。
Action 提交的是 mutation ,而不是直接变更状态。
Action 可以包含任意异步操作。
注册一个简单的 action
const store = new Vuex.Store({
state: {
count:0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context){
context.commit('increment')
}
}
})