1.Vuex
1.1概念由来---解决非关系型组件
vuex是采用集中式管理组件依赖的共享数据的一个工具,可以解决不同组件数据共享问题
1.2内部逻辑-使用流程--组件中可以调用action,mutation
结论:
- 修改state状态必须且只能通过mutations
- mutations只能执行同步代码,类似ajax,定时器之类的代码不能在mutations中执行
- 执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
- state的状态即共享数据可以在组件中引用
- 组件中可以调用action,mutation
1.3vuex基础-初始化功能
// 1. 安装vuex
// 2. 引入vuex
// 3. 注册vuex
// 4. 实例化 vuex 对象
// 5. 根实例配置 store 选项指向 store 实例对象
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(vuex)
const store = new Vuex.Store({})
new Vue({
el: '#app',
store
})
1.4属性介绍
1.4.1State--本质是一个对象-state是放置所有公共状态的属性
组件中如何获取state?有3种方式:(第二种是使用计算属性)
1.原始形式-在组件中可以使用 this.$store 获取到vuex中的store对象实例---插值语法{{}}内不用写this
2. 辅助函数 - mapState
第一步:导入mapState
import { mapState } from 'vuex'
computed: {
...mapState(['count', 'msg']),
// 其他的属性照常加
}
对象展开运算符juejin.cn/post/689552…
1.4.2mutations
state数据的修改只能通过mutations,并且mutations必须是同步更新,目的是形成数据快照。数据快照是指:一次mutation的执行,立刻得到一种视图状态,因为是立刻,所以必须是同步。
mutations参数:(state,payload载荷) -----state:当前vuex中的state对象 -----payload载荷:提交mutations的方法的时候传递的参数,它可以是任意形式的、任意类型的值 组件调用mutation
组件调用两种方法:
1.带参数的传递
// payload 载荷 运输参数 调用mutaiions的时候 可以传递参数 传递载荷
// payload 其实就是形参数
addCount (state, payload) {
state.count += payload
}
this.$store.commit('addCount', 10)
2.辅助函数 - mapMutations
mapMutations和mapState很像,它把位于mutations中的方法提取了出来,我们可以将它导入
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['addCount'])
}
1.4.3actions----也可以传递参数调用
actions则可以进行异步操作和同时提交多个mutation
特点 - 异步操作、同时可提交多个mutation、可以通过dispatch调用其他的action
参数 - 第一个参数:context---相当于组件中的this.$store---->store的运行实例 第二个参数是传入的参数
调用mutations---->context.commit("名称")
调用actions------>context.dispatch("名称") 也可以通过辅助函数去调用
总结:actions和mutations如果没有传递参数,vue方法中默认的第一个参数是时间参数对象
1.4.4getters----类似于计算属性----放置vuex中所有的计算属性---放置二次处理的数据
除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters
getters: {
// getters函数的第一个参数是 state
// 必须要有返回值
filterList: state => state.list.filter(item => item > 5),
count: (state, getters) => {
// Getter 也可以接受其他 getter 作为第二个参数
return state.count + getters.msg;
},
}
2.Vuex- Module
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
2.1使用
子模块的调用:
先引入,再使用
2.2命名空间----给子模块加锁namespaced: true
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
这句话的意思是 刚才的user模块还是setting模块,它的 action、mutation 和 getter 其实并没有区分,都可以直接通过全局的方式调用
使用命名空间后的调用:
方案1:直接调用-带上模块的属性名路径-------常用
test () {
this.$store.dispatch('user/updateToken') // 直接调用方法
}
方案2:辅助函数-带上模块的属性名路径
methods: {
...mapMutations(['user/updateToken']),
test () {
this['user/updateToken']()
}
}
<button @click="test">修改token</button>
方案3: createNamespacedHelpers 创建基于某个命名空间辅助函数
import { createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('user')
<button @click="updateToken">修改token2</button>
3.Vuex的缺点
vuex数据不是持久化存储的,每次应用刷新数据都会重置
- 每次获取的数据都是接口获取的(不受影响)
- 获取不是服务端数据(持久化)
可以借助 第三方库: vuex-persistedstate 解决这个问题
- 下包
npm install --save vuex-persistedstate@3.2.1
- 引包
import createPersistedState from "vuex-persistedstate";
- 配置
// import Cookies from "js-cookie";
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {
user: user
},
plugins: [createPersistedState({
key: "myVuex", // 指定名称 默认vuex
paths: ["setting"] // 只可以指定缓存的模块
// reducer(state) { // 可以指定缓存 具体到摸一个字段
// return {
// // 只储存state中的token
// user: {
// token: state.user.token,
// }
// };
// },
storage: '可以指定缓存在哪里', // 默认localStroage
// storage: window.sessionStorage,
// 缓存在cookie的话是 js-cookie 库
// storage: {
// getItem: (key) => Cookies.get(key),
// setItem: (key, value) => Cookies.set(key, value, { expires: 7 }),
// removeItem: (key) => Cookies.remove(key),
// }
})],
})
3.Vuex常见面试题
1.页面刷新后vuex的state数据丢失怎么解决?
就是放在localStorage 或者就是sessionStorage ,或者借用辅助插vuex-persistedstate