一 概念
多组见数据共享
使用场景:
1.某个状态在很多组件中使用,比如:登陆信息
2.多个组件公共维护一份数据,比如:购物车
优势:
1.对数据集中化管理
2.响应式的变化
3.操作简捷(vuex提供辅助函数)
二 创建空仓
1.安装vuex
版本选择原则:233 / 344
yarn add vuex@3
2.新建模块文件
src中新建 store/index.js 专门存放 vuex
3.创建仓库
Vue.use(Vuex) 创建仓库 new Vue.Store()
// 存放vuex的核心代码
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)
// 创建仓库
const store = new Vuec.Store()// 导出给main.js使用
export default store
4.在main.js中导入挂载到 Vue实例上
import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { },
getters: { },
mutations: { },
actions: { },
modules: { }
})
this.$store
vue实际上是一个所有组件都能访问到的通用的对象
三 核心概念
核心概念:state状态
1. 提供数据
类似于vue组件中的data
区别:data 是组件自己的数据,state 是所有组件共享的数据
State 提供唯一的公共数据,所有共享的数据都要统一放在 Store 中的 State 中存储
在 state 中可以添加要共享的数据
2.使用数据
2.1通过 store 直接访问
(1) this.$store
模版中 {{ $store.state.xxx }}
组件逻辑中 this.$store.state.xxx
(2) import 导入 store
js模块中 store.state.xxx
2.2 通过辅助函数(简化)
辅助函数 mapState
将 store 中的数据自动映射到组件的计算属性中
{{ count }}
// 将 state 中的数据,定义在组件内的计算属性中
computed: {
count () {
return this.$store.state.count
}
}
mpState 核心步骤(三步)
{{ count }}
{{ title }}
// 1.导入 mapState
import { mapState } from 'vuex'
// 2.数组方法引用
export 的fault {
computed:{
...mapState(['count','title'])
}
}
核心概念-mutations
vuex遵循单项数据流,组件内不能直接修改仓库的数据
mutations 必须是同步的,便于监测数据变化,记录调试
严格模式
(初学者监测不规范代码,上线需关闭)
// 错误代码默认不会监测,会损耗性能
// 不符合规范,在任意组件任意地方能修改代码,项目大了之后会难以维护,仓库数据变
this.$store.state.count++
script: true 开启严格模式,上线建议关闭
const store = new Vuex.Store({
// 开启严格模式
strict: true,
state: {}
})
基语法
1. 定义mutations 对象在vuex中,存放修改 state 的方法
const store = new Vuex.Store({
// 通过 state 提供数据,是所有组件共享的数据
state:{ count: 0 },
// 通过 mutations 提供修改数据的方法
mutations: {
// 所有 mutations 函数,第一个参数都是 state
addCount (state) {
state.count += 1
},
addCountFn (state, payload) {
state.count += payload
},
}
})
2.组件中提交调用 mutations,this.$store.commit()
this.$store.commit('addCount')
3.提交载荷 payload,既传参
传参语法: this.$store.commit('xxx', 参数)
注:mutation 参数有且只能有一个,如果是多个参数,可以包装成一个对象
this.$store.commit('addCountFn', 10)
案例:输入框
使用:value 渲染输入框内容 => @input,监听输入内容 => 封装 mutations 处理函数 => 调用传参
辅助函数 mapMutations
mapMutations ,是将位于 mutations 中的方法提取出来,映射到组件中的methods中
于 mapState 很像
mutations: {
subCount (state, n) {
state.count -= n
}
}
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['subCount'])
}
// 上述代码等价于
methods: {
subCount (n) {
this.$store.commit('subCount', n)
}
}
调用
// 相当于生成一个 subCount 函数,用来提交 subCount
this.subCount(10)
核心概念-actions
用于处理异步操作
mutations 必须是同步的,便于监测数据变化,记录调试
注:不能直接操作 state ,还是需要 commit mutation
语法
1.提供 action 方法
// 1秒后将 state 中的count修改为 666
mutations: {
changeCount (state, newCount) {
state.count = newCount
}
},
actions: {
setAsyncCount (context, num) {
setTimeout(() => {
context.commit('changeCount', num)
}, 1000)
}
}
2.页面调用 dispatch 调用,有且只有一个参数
this.$store.dispatch('setAsyncCount', 666)
辅助函数 mapActions
mapActions 是将 actions 中的方法提取,映射到组件 methods 中
actions: {
changeCountAction (context, num) {
setTimeout(() => {
context.commit('changeCount', num)
}, 1000)
}
}
import { mapActions } from 'vuex'
methods: {
...mapActions(['changeCountAction'])
}
// 上述代码等价于
// 原声写法
methods: {
changeCountAction (n) {
this.$store.dispatch('changeCountAction', n)
}
}
调用
this.changeCountActions(666)
核心概念-getters
类似于计算属性
有时还需要从state中派生出一些状态,这些状态依赖是state的,此时会用到getters
应用例子:state中定义list,是1-10的数据,组件中需要展示所有大于5的数据
语法
1.定义 getters
getters: {
filterList (state) {
// 注意:
// 1. getters函数的第一个参数是 state
// 2. getters函数必须有返回值
return state.lost.filter(item => item > 5)
}
}
2.访问getters
(1)通过 store 访问 getters
{{ $store.getters.filterList }}
(2)通过辅助函数 mapGetters 映射
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['filterList'])
}
{{ filterList }}
核心概念-模块 module(进阶语法)
由于 vuex 使用单一状态树,应用中的所有状态会集中到一个比较大的对象。当应用变得复杂时,store 对象就有可能变得臃肿(当项目变的越来越大的时候,Vuex会变得难以维护)
目标:掌握核心概念 module 模块创建
模块拆分:
user模块: store/modules/user.js
const state = {
userInfo: {
name: "zhangsan",
age: 18
}
}
const mutations = {}
const actions = {}
const getters = {}
export default {
state,
mutations,
actions,
getters
}
应用
import user from './modules/user'
const store = new Vuex.Store({
modules: {
user
}
})
模块访问
目标:掌握模块中 state 的访问语法
尽管已经分模块了,但子模块的状态还是会挂载到根级别的 state 中,属性名就是模块名
使用模块中的数据:
(1)直接访问(原生), $store.state.模块名.xxx
(2)通过 mapState 映射
默认根级别的映射 mapState(['xxx'])
子模块的映射 mapState('模块名', ['xxx']) - 需要开启命名空间
ecport default {
// 开启命名空间
namespaced: true,
state,
mutations,
actions,
getters
}