vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态,而更改状态的唯一方法是提交mutation
Vuex解决了什么问题?
- 多个组件依赖于同一状态时,对于多层嵌套的组件的传参将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
- 来自不同组件的行为需要变更同一状态。以往采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
什么时候用Vuex?
- 多个组件依赖于同一状态时。
- 来自不同组件的行为需要变更同一状态。
怎么使用Vuex
第一步 安装
npm i vuex -S
第二步 创建store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 不是在生产环境debug为true
const debug = process.env.NODE_ENV !== 'production'
// 创建Vuex实例对象
const store = new Vuex.store({
strict:debug,
state:{ },
getters:{ },
mutations:{ },
actions:{ }
})
export default store;
第三步 注入vuex
import Vue from 'vue'
import App from './App.vue'
import store from './store'
new Vue({
store:store,
render: h => h(App)
}).$mount('#app')
vuex的核心属性
- state:唯一数据源
- getters:可以认为是store的计算属性,就像计算属性一样,getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会重新计算。getters会暴露为store.getters对象,可以以属性的形式访问这些值。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '123', done: true },
{ id: 2, text: '456', done: false }
]
},
getters: {
getTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
store.getters.getTodos// -> [{ id: 1, text: '123', done: true }]
- mutation:更改Vuex的store中的状态的唯一方法,通过store.mutation方法触发
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
store.commit('increment')
- actions:类似mutation,不同在于action提交的是mutation,而不是直接变更状态,action可以包含任意异步操作
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
- module:由于使用单一状态树,应用的所有状态会集中到一个较大的对象。当应用变得非常复杂的时候,store对象就有可能变得相当臃肿。为了解决以上问题,vuex允许我们将store分割成模块(module)
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
Vuex的常见问题
从vuex中获取的数据能直接更改吗?
从vuex中取的数据,不能直接更改,需要浅拷贝对象之后更改,否则报错;
vuex中的数据在页面刷新后数据消失
用sessionstorage 或者 localstorage 存储数据
存储: sessionStorage.setItem( 'name', JSON.stringify(值) )
使用: sessionStorage.getItem('name')
得到的值为字符串类型,用JSON.parse()格式化
Vuex的严格模式是什么,有什么作用,怎么开启?
在严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
在Vuex.Store 构造器选项中开启,如下
const store = new Vuex.Store({
strict:true,
})
怎么在组件中批量使用Vuex的getter属性
使用mapGetters辅助函数,利用对象展开运算符将getter混入computed对象中
import {mapGetters} from 'vuex'
export default{
computed:{
...mapGetters(['total','discountTotal'])
}
}
组件中重复使用mutation
使用mapMutations辅助函数,在组件中这么使用
import { mapMutations } from 'vuex'
methods:{
...mapMutations({
setNumber:'SET_NUMBER',
})
}
然后调用this.setNumber(10)相当调用this.$store.commit('SET_NUMBER',10)
mutation和action有什么区别
- action提交的是mutation,而不是直接变更状态。mutation可以直接变更状态
- action可以包含任意异步操作。mutation只能是同步操作
- 提交方式不同
action:this.store.dispatch('ACTION_NAME',data)
mutation:this.$store.commit('SET_NUMBER',10)
- 接受参数不同,mutation第一个参数是state,而action第一个参数context,其包含了
{
state, // 等同于 `store.state`,若在模块中则为局部状态
rootState, // 等同于 `store.state`,只存在于模块中
commit, // 等同于 `store.commit`
dispatch, // 等同于 `store.dispatch`
getters, // 等同于 `store.getters`
rootGetters // 等同于 `store.getters`,只存在于模块中
}
在v-model上怎么用Vuex中state的值?
需要通过computed计算属性来转换。
<input v-model="message">
computed: {
message: {
get () {
return this.$store.state.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}