1. Vuex 总结
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store (仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
(1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
(2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。
这样使得我们可以方便地跟踪每一个状态的变化。
this.$store.commit('updateBusinessobj', obj);
主要包括以下几个模块:
1. State => 基本数据,定义了应用状态的数据结构,可以在这里设置默认的初始状态。
2. Getter => 从基本数据派生的数据,允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅
是将 store 中的 getter 映射到局部计算属性, 不会改变 源数据。
3. Mutation => 是唯一更改 store 中状态的方法,且必须是同步函数。
4. Action => 像一个装饰器,包裹 mutations,使之可以异步。用于提交 mutation,而不是直接
变更状态,可以包含任意异步操作。
5. Module => 模块化Vuex,允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
created () {
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store")) {
this.$store.replaceState(Object.assign({},
this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
}
//在页面关闭刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload", () => {
sessionStorage.setItem("store", JSON.stringify(this.$store.state))
})
},
2. mutation 和 action 的详细区别
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
1、流程顺序
“相应视图—>修改State”拆分成两部分,视图触发Action,Action再触发Mutation。
2、角色定位
基于流程顺序,二者扮演不同的角色。
Mutation:专注于修改 State,理论上是修改 。
Action:业务代码、异步请求。
3、限制
角色不同,二者有不同的限制。
Mutation:必须同步执行。
Action:可以异步,但不能直接操作 State。
总结:
action 的功能和 mutation 是类似的,都是去变更 store 里的 state
action 和 mutation 有两点不同:
1、action 主要处理的是异步的操作,mutation 必须同步执行,而 action 就不受这样的限制,也就是说 action 中我们既可以处理同步,也可以处理异步的操作
2、action 改变状态,最后是通过提交 mutation
3. 使用 Vuex 统一管理状态的好处、和用处
Vuex 统一管理状态的好处:
能够在 vuex 中集中管理共享的数据,易于开发和后期维护
能够高效地实现组件之间的数据共享,提高开发效率
存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步
用处:什么样的数据适合存储到 Vuex 中:
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;
对于组件中的私有数据,依旧存储在组件自身的data中即可。
4. vuex 的安装
1.安装 vuex 依赖包
npm i vuex - save
2.在 store.js 中 导入 vuex 包
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
3.创建 store 对象
const store = new Vuex.Store({
// state 中存放的就是全局共享的数据
state: {
},
mutations: {
},
actions: {
},
getters: {
}
})
// 导出 store
export default store
4.main.js 引入 store
import store from './store/index.js'
// 4. 将 store 对象挂载到 vue 实例中
new Vue({
el: '#app',
render: h=>h(app),
router,
// 将创建的共享数据对象,挂载到 Vue 实例中
// 所有的组件,就可以直接从 store 中 获取全局的数据 了
store,
})
5. 组件访问 state 中的数据的两种方式
1.通过 this.$store.state 访问
2.mapState 函数访问
6. Mutations 用于变更 state 中的数据
Mutation 用于变更
Store中的数据。
只能通过 mutation 变更 Store 数据,不可以直接操作 Store 中的数据。
通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
1. 触发 Mutations 函数 无参数
// 定义 Mutation
const store = new vuex.store({
state: {
count: 0
},
mutations: {
add(state) {
// 变更状态
state.count++
}
}
})
methods: {
// 触发mutation
handle1() {
// 触发 mutations 的第一种方式
this.$store.commit('add')
}
}
2. 触发 Mutations 函数 有参数
// 定义 Mutation
const store = new vuex.store({
state: {
count: 0
},
mutations: {
add(state, params) {
// 变更状态
state.count += params;
}
}
})
methods: {
// 触发mutation
handle1() {
// 触发 mutations 时在第二个参数里传递要的值
// commit 的作用,专门用来触发 某个 mutation 函数
this.$store.commit('add', 3)
}
}
3. mapMutations 来调用
this.$store.commit() 是触发 mutations 的第一种方式,触发 mutations 的第二种方式:
// 1.从vuex 中按需导入 mapMutations函数
import { mapMutations } from 'vuex!
通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods 方法:
methods:{
// 将指定的 mutations 函数,映射为当前组件的 methods 函数
...mapMutations(['add', 'addn']),
addHandle() {
this.add()
}
}
4. Mutation 为什么不能使用异步函数
重点事情: 为什么必须是同步更新?
Mutation 异步函数 会 造成状态改变的不可追踪
造成状态改变的不可追踪
造成状态改变的不可追踪
可以看到在 Mutation 中使用异步和同步最终页面的总和都是正确的,也就是说在Mutation 中使用异步不会对数据造成丢失和其他影响。然而我们注意 Vue Devtools 显示结果,当我们去查看多次 Mutation 状态时,发现同步的显示 Ok,异步的 Count 显示为 0 和我们预期结果不一致,所以会造成状态改变的不可追踪,所以官方说我们Mutation 是同步的!
5.Mutation 才能修改 state 中的数据
7.actions 异步任务用于辅助 mutations 来异步执行变更 state 中的数据
1.actions 定义
Action用于处理异步任务。如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是要通过触发 Mutation 的方式间接变更数据。
// 定义 Action
const store = new Vuex.store({
//...省略其他代码
mutations: {
add(state) {
state.count++
}
},
actions: {
addAsync(context) {
setTimeout(() => {
context.commit('add')
}, 1000);
}
}
})
// 触发 Action
methods: {
handle(){
// 触发 actions 的第一种方式, dispatch 函数,专门用来触发 action
this.$store.dispatch('addAsync')
}
}
2.actions 中,不能直接更改 state 中的数据
actions: {
addAsync(context){
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据;
// 必须通过 context.commit()触发某个 mutation 才行 I
context.commit('add')
}, 1000)
}
}
3. 触发 action 异步任务 携带参数
// 定义 Action
const store = new Vuex.Store({
// ...省略其他代码
mutations: {
addNumN(state, params) {
state.count += params;
},
},
actions: {
addNAsync(context, params) {
setTimeout(() => {
context.commit('addNumN', params)
}, 1000);
},
},
})
// 触发 Aciton
methods: {
addHandle4() {
// 触发 Aciton时,第二个参数为要的 值
this.$store.dispatch('addNAsync', 3)
},
}
4. mapActions 触发 actions
this.$store.dispatch() 是触发 actions 的第一种方式,触发 actions 的第二种方式:
1.从 vuex 中按需导入 mapActions 函数
import { mapActions } from 'vuex'
2.通过刚才导入的 mapActions 函数,将需要的 actions 函数,映射为当前组件的 methods 方法: 将指定的 actions 函数,映射为当前组件的 methods 函数
methods:{
...mapActions(['addasync', 'addnAsync']),
subHandle2() {
this.addasync(3)
}
}
8. getters
Getter 用于对 Store 中的数据进行加工处理形成新的数据。
Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似 Vue 的计算属性。 Store 中数据发生变化,Getter 的数据也会跟着变化。Getter 不会影响 state 中的源数据
1.定义 getter
// 定义 Getter
const store = new vuex.store({
state: {
count: 0
},
getters: {
showNum: state => {
return `当前最新的数量是【' + state.count + '】!`
}
}
})
2.使用getters的第一种方式
this.$store.getters.名称
例如:this.$store.getters.showNum
3.使用getters的第二种方式:
import { mapgetters } from 'vuex'
computed:{
...mapGetters(['showNum'])
}