Vuex是什么?
Vuex理解
- 每一个 Vuex 应用的核心就是 store(仓库)。
- “store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
- 使用 Vuex 并不意味着你需要将所有的状态放入 Vuex
- 组件仍然保有局部状态。
- 虽然将所有的状态放到 Vuex;会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。
- 如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。
vue特点
-
Vuex 的状态存储是响应式的。
-
当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
-
你不能直接改变 store 中的状态。
-
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation
创建store
import Vuex from 'vuex'
Vue.use(vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
复制代码
Vuex —— state
- Vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态
- 每个应用将仅仅包含一个 store 实例
在 Vue 组件中获得 Vuex 状态
// 创建一个 Counter 组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
复制代码
将Vuex注入到每一个子组件中(store 选项)
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
复制代码
子组件访问vuex (this.$store.state)
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
复制代码
子组件获取多个状态(mapState()辅助函数)
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
复制代码
Vuex —— getter
- 有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:
不用getter
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
复制代码
在Vuex中使用getter
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)
}
}
})
复制代码
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
复制代码
Vuex —— mutations
- Vuex 中的 mutation 非常类似于事件:
- 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
- 这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
- mutation 必须是同步函数
提交载荷(Payload)
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
})
复制代码
提交方式一:
store.commit('increment', {
amount: 10
})
复制代码
提交方式二:
store.commit({
type: 'increment',
amount: 10
})
复制代码
Vuex —— Actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
复制代码
main.js
main.js中
import Vuex from 'vuex'
Vue.use(vuex);
const store = new Vuex.store({
state: {
nickName: "",
cartCount: 0  
},
mutations: {
updateUserInfo(state,nickName) {
state.nickName = nickName;
},
updateCartCount(state,cartCount) {
state.cartCount += cartCount;
}
},
actions: {
updateUserInfo(context) {
context.commit("updateUserInfo");
},
updateCartCount(context) {
context.commit("updateCartCount");
}
}
})
new Vue({
el: "#app",
store,
router,
template: '<App/>',
components: {App}
})
复制代码
组件中
methods: {
increment(){
this.$store.dispatch("updateUserInfo", 'nick'); //this.$store.commit("increment", 'nick');
},
decrement() {
this.$store.dispatch("updateCartCount", 1); // this.$store.commit("decrement", 1);
}
}
复制代码