一 、Vuex是什么?
介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
理解:核心就是store(仓库) ,仓库是用来干什么的?你就当它用来储存东西的 。
二 、我们什么时候应该用到Vuex呢?
a.小应用不建议使用Vuex,因为小项目使用 Vuex 可能会比较繁琐冗余;
b.中大型单页应用 ,因为要考虑如何更好地在组件外部管理状态 ,Vuex 将会成为自然而然的选择;
三、对于使用Vuex的理解是什么?
由于Vue是单向数据流 ,子组件内部不能直接修改从父级传递过来的数据 ,子组件与子组件之间无法相互传递数据 。如果我们想让两个子组件之间进行通信的话 ,可以借助子组件 A 向父组件传值 ,父组件接收子组件 A 的数据后再传给 B 组件这样的方式进行通信。
但是这样会有一个问题 ,就是如果子组件 A 的父组件上面还有一层爷爷组件 ,或者还有更多祖父类型的层级,那么是不是会很麻烦 。
因此 ,我们会想到能不能我们将一个共有的数据存在一个特定的地方 ,用的时候自己去拿,这样就不需要一层层传值 ,于是乎 Vuex 就应运而生了 。
四 、vuex由五部分组成(五种状态/五种属性)
state: 数据
actions:可以包含异步操作
mutations: 唯一可以修改state数据的场所
getters: 类似于vue组件中的计算属性 ,对state数据进行计算(会被缓存)
modules:模块化管理store(仓库),每个模块拥有自己的 state 、mutation 、action 、getter
五 、安装配置
第一步:npm i vuex --save/-S
第二步: 创建store.js
第三步:挂载使用Vue.use(vuex)
第四步:const store = new Vuex.Store({...配置项})
第五步:导出 export default store
第六步:导入main.js 在根实例配置 store 选项指向 store 实例对象
具体如下
安装
npm install vuex
创建store.js
// 初始化一个vuex的实例(数据仓库) 导出即可
import Vuex from vuex
import Vue from vue
// 使用安装
Vue.use(Vuex)
// 初始化
const store = new Vuex.Store({
// 配置(state|mutations|actions)
})
export default store
把store对象挂载到Vue实例中
import store from @/store
new Vue({
// 把store对象挂载到vue实例对象中 ,这样就可以在所有的组件中获取store中的数据了
store,
render: h => h(App),
}).$mount(#app)
六 、详解五种状态
1 、state
初始化state
状态state用于存储所有组件的数据 。
管理数据
// 初始化vuex对象
const store = new vuex.Store({
state: {
// 管理数据
count: 0
}
})
在组件获取state的数据:原始用法插值表达式
<div>A组件 state的数据:{{$store.state.count}}</div>
<div>A组件 state的数据:{{count}}</div>
使用计算属性:
// 把state中数据 ,定义在组件内的计算属性中
computed: {
// 1. 最完整的写法
// count: function () {
// return this.$store.state.count
// },
// 2. 缩写
count () {
return this.$store.state.count
}
}
// 不能使用剪头函数 this指向的不是vue实例
注意:
state中的数据是自定义的 ,但是state属性名是固定的
获取数据可以通过 $store.state
可以使用计算属性优化模板中获取数据的方式
计算属性不可以使用箭头函数(箭头函数本身是没有this的 ,实际上用的是父级函数中的this)
mapState
目标:简化获取store数据的代码
把vuex中的state数据映射到组件的计算属性中 。
import { mapState } from vuex
1.使用:mapState(对象)
// 使用mapState来生成计算属性 mapState函数返回值是对象
// 使用mapState使用对象传参
// computed: mapState({
// // 1. 基础写法 (state) 代表就是vuex申明的state
// // count: function(state) {
// // return state.count
// // }
// // 2. 使用箭头函数
// // count: state => state.count
// // 3. vuex提供写法 (count是state中的字段名称)
// count: count,
// // 4. 当你的计算属性 需要依赖vuex中的数据 同时 依赖组件中data的数据
// count (state) {
// return state.count + this.num
// }
// })
2.使用:mapState(数组)
// 2 、mapState参数是一个数组
// computed: mapState([count, total])
3.如果组件自己有计算属性 ,state的字段映射成计算属性
// 3 、即在内部保留原有的计算属性 ,又要把store中的数据映射为计算属性
computed: {
// 组件自己的计算属性
calcNum () {
return this.num + 1
},
// 把mapState返回值那个对象进行展开操作(把对象的属性添加到该位置)
...mapState([count])
}
2、mutations
基本操作
目标:Vuex规定必须通过mutation修改数据 ,不可以直接通过store修改状态数据 。
为什么要用mutation方式修改数据?Vuex的规定
为什么要有这样的规定?统一管理数据 ,便于监控数据变化
定义状态修改函数
// mutations是固定的 ,用于定义修改数据的动作(函数)
mutations: {
// 定义一个mutation,用于累加count值
// increment这个名字是自定义的
increment (state, payload) {
// state表示Store中所有数据
// payload表示组件中传递过来的数据
state.count = state.count + payload
},
decrement (state, payload) {
state.count = state.count - payload
}
}
组件中调用
methods: {
handleClick1 () {
// 通过触发mutation修改state中的count的值
this.$store.commit(increment, 2)
},
handleClick2 () {
this.$store.commit(decrement, 1)
}
},
总结:
先定义(mutations) ,再出发 this.$store.commit(‘mutation的名称 ,参数’)
mutation的本质就是方法,方法名称自定义 ,mutation函数内部负责处理的变更操作 。
一种操作就是一个mutation ,不同的mutation处理不同的场景 。
mapMutations
把vuex中的mutations的函数映射到组件的methods中
通俗:通过mapMutations函数可以生成methods中函数
methods: {
// 1 、对象参数的写法
// ...mapMutations({
// // 冒号右侧的increment是mutation的名称
// // 冒号左侧的increment是事件函数的名称,可以自定义
// increment: increment
// })
// 2 、数组参数的写法(事件函数名称和mutation名称一致)
...mapMutations([increment])
// 3、这种写法和第2种等效
// increment (param) {
// // 点击触发该函数后要再次触发mutation的
// this.$store.commit(increment, param)
// }
}
总结:
mapMutations函数的作用:简化methods的定义
原始方式:通过$store.commit方法触发mutation
简写方式一:对象写法
简写方式二:数组写法
3 、action 基本使用
目标:主要用于处理异步的任务
安装axios的包
npm i axios
//导入包
import axios from axios
定义获取数据方法
// actions是固定的 ,用于定义异步操作的动作(函数)
actions: {
// 定义了一个action ,用于查询接口数据
async queryData (context, payload) {
console.log(payload)
// 调用接口获取数据
const ret = await axios.get(http://test.zjie.wang/tab)
// 必须触发mutation修改list的值
// context类似于this.$store
context.commit(updateList, ret.data.list)
}
},
mutations: {
updateList (state, payload) {
state.list = payload
}
}
组件使用:
methods: {
handleQuery () {
// 触发action(必须调用dispatch方法)
this.$store.dispatch(queryData, 111)
}
}
mapActions
mapActions辅助函数 ,把actions中的函数映射组件methods中
通俗:通过mapActions函数可以生成methods中函数
// 相当于 methods申明了一个函数fn(num){ this.$store.dispatch(queryData, num)}
// ...mapActions({
// fn: queryData
// })
// 相当于 methods申明了一个函数getData(num){ this.$store.dispatch(getData, num)}
...mapActions([queryData])
总结:
原始方式:this.$store.dispatch(‘queryData’, num)
简化方式一:对象
简化方式二:数组
4 、getters用法
目标:熟悉getters的应用场景和具体使用步骤
先定义getters
// 相当于state的计算属性(基于State处理成另外一份数据)
// getters的主要应用场景:模板中需要的数据和State中的数据不完全一样
// 需要基于state中的数据进行加工处理 ,形成一份新的的数据 ,给模板使用
getters: {
getPartList (state) {
return state.list.filter(item => {
return item.id > 1
})
}
}
再使用getters
1.基本使用
caleList () {
// 注意:获取getters的值 ,不需要加括号(当属性使用)
return this.$store.getters.getPartList
},
2.简化用法
import { mapGetters } from vuex
// mapGetters的作用:把getters映射为计算属性
computed: {
...mapGetters([getPartList]),
// ...mapGetters({
// calcList: getPartList
// }),
// calcList () {
// // 注意:获取getters的值 ,不需要加括号(当属性使用)
// return this.$store.getters.getPartList
// },
}
总结:
getters相当于在State和组件之间添加一个环节(对state中的数据进行加工处理后再提供给组件)
getters不要修改state中的数据
getters类似之前的计算属性(基于state中的数据进行计算)
5、modules
使用单一状态树 ,导致应用的所有状态集中到一个很大的对象 。但是 ,当应用变得很大时,store 对象会变得臃肿不堪 。
为了解决以上问题 ,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state 、mutation 、action 、getters 、甚至是嵌套子模块——从上至下进行类似的分割:
例如:分模块形式管理数据 ,比如user模块管理用户信息数据,cart模块管理购物车数据 ,shop模块管理商品信息数据 。
import vue from vue
import Vuex from vuex
Vue.use(vuex);
const state= ()=>{ token:}
const actions = {
set_token({commit},val){
commit("to_token",val)
}
}
const mutations = {
to_token(state,val){
state.token=val;
}
}
const getters = {}
//user模块
let user = {
namespaced: true, //一定要开始命名空间 。
state: { userid: 1234 },
actions: {
},
mutations: {
SET_USERID(state, val) {
state.userid = val;
}
},
getters: {
}
}
//购物车数据的模块
let cart = {
namespaced: true,
state: { userid: 567 },
actions: {
},
mutations: {
},
getters: {
}
}
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
modules: {
user,
cart
},
plugins: [createPersistedState({
storage: sessionStorage,
key: "token"
})]//会自动保存创建的状态。刷新还在
})
export default store
home.vue如何使用
获取user模块的`userid`
this.$store.state.user.userid
this.$store.commit("user/SET_USERID",12345)// 前面是指定模块user 中的SET_USERID 方法 ,后面是传参 可以是对象 、数组 、字符串等
七 、数据持久化
问题:存储在vuex中的状态,刷新页面 ,会丢失 。为了解决刷新页面数据丢失 ,才有了数据持久化 。最简单的做法就是利用插件 vuex-persistedState。
1 、安装
cnpm install vuex-persistedState -S
备注:
-S 是 --save的简写 ,意为:把插件安装到 dependencies(生产环境依赖)中
-D是 --save-dev的简写 ,意为:把插件安装到 devDependencies(开发环境依赖)中
2 、使用
import createPersistedState from vuex-persistedstate
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
plugins: [createPersistedState({
storage: sessionStorage,
key: "token"
})]//会自动保存创建的状态 。刷新还在
})
参数:
storage:存储方式 。(sessionStorage,localStarage) key:定义本地存储中的key
以上为个人经验 ,希望能给大家一个参考 ,也希望大家多多支持本站 。
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时,禁止复制、盗用 、采集 、发布本站内容到任何网站、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。