Vuex概念
什么是Vuex:
vuex 是一个 vue 的状态管理工具也是全局的状态管理的仓库, 状态就是数据,状态管理就是集中管理vue中 通用的 一些数据
Vuex的优点:
- vuex的作用是解决 多组件状态共享 的问题
- 它是独立于组件而单独存在的,所有的组件都可以把它当做一座桥梁来进行通信
特点:
- 它是响应式的,只要仓库一有变化,其他地方就会更新
- 操作更简洁
Vuex基本配置
- 下包
yarn add vuex@3.4.0
- 模块化Vuex(在 store/index.js 里面写代码)
# store/index.js 里面引入 vue 和 定义vuex
import Vue from 'vue'
import Vuex from 'vuex'
#在main.js里面挂载使用
import store from '@/store'
- 导入 Vue 和 Vuex, 安装Vuex插件
Vue.sue(Vuex)
4.创建 Vuex.Store 实例对象
const store = new Vuex.Store({})
5.导出 store 对象,到main.js里面
export default store
6.在main.js 中导入并注入到vue 实例上
new Vue({
render: h => h(App),
store
}).$mount('#app')
State核心概念
作用: State是唯一唯一定义全局数据的,所有的数据都统一放在State中存储
state的数据, 类似于vue组件中的data,区别在于 data 是组件自己的数据, 而 state 中的数据整个vue项目的组件都能访问到
const store = new Vuex.Store({
state: {
count: 101
}
})
在组件获取count
1.插值表达式—{{$store.state.count}}
# <h1>state的数据 - {{ $store.state.count }}</h1>
2.计算属性----{{count}}
computed: {
count () {
return this.$store.state.count
}
}
<h1>state的数据 - {{ count }}</h1>
3.辅助函数—mapState
# 导入mapState
import { mapState } from 'vuex'
# 采用数组形式引入state属性
mapState(['count'])
# 在计算属性中利用展开运算符导出
computed: {
...mapState(['count'])
}
# state是个数据所以要在写在计算属性里面
Mutations核心概念
state数据的修改只能通过mutations,并且mutations必须是同步的
mutations是一个对象,对象中存放修改state的方法
const store = new Vuex.Store({
state: {
count: 0
},
// 定义mutations
// 方法里参数 第一个参数是当前store的state属性
mutations: {
addCount (state) {
state.count += 1
}
}
})
mutation带参数
# 1.在store中定义mutations方法
mutations: {
// 第一个参数永远都是state
// 参数2,就是组件调用时传入的参数,
//只能传一个参数,如果要传多个参数,可将数据放到数组或对象的容器中在传参
addCount (state, num) {
//不传参的写法
//state.count++
// 传参
state.count += num
}
}
# 2.在组件中methods使用 this.$store.commit('addCount')
methods:{
//点击事件
add(){
// 不传参写法
// this.$store.commit('addCount')
this.$store.commit('addCount', 20)
}
}
辅助函数----- mapMutations
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['addCount'])
}
上面代码含义是将mutations的方法导入了methods中
this.$store.commit('addCount')
直接通过this.addCount调用
methods:{
add(){
// 这一步一定要写
this.addCount
}
}
actions核心概念
state是存放数据的,mutations是同步更新数据 (便于监测数据的变化, 更新视图等, 方便于调试工具查看变化),actions则负责进行异步操作
# 定义actions
//第二步
actions: {
//第一个参数永远是context对象
//第二个参数可以接受组件传递过来的数据参数
setAsyncCount (context, num) {
// 一秒后, 给一个数, 去修改 num
// actions不能直接修改state,只能将数据交给mutations来修改
setTimeout(() => {
//context.commit()来调用mutations方法的
context.commit('inputCount', num)
}, 1000)
}
},
#调用actions的方法
methods:{
// 第一步
setAsyncCount(){
//第三步
this.$store.dispatch('setAsyncCount',20)
}
}
自我理解
- state的数据渲染到组件中
# <h1>state的数据 - {{ $store.state.count }}</h1>
- 用户点击触发事件
点击事件
<button @click="add">值+1</button>
methods:{
add(){
this.$store.dispatch('setAsyncCount',20)
}
}
- 触发actions函数执行异步任务
actions: {
//第一个参数永远是context对象
//第二个参数可以接受组件传递过来的数据参数
setAsyncCount (context, num) {
// 一秒后, 给一个数, 去修改 num
// actions不能直接修改state,只能将数据交给mutations来修改
setTimeout(() => {
//context.commit()来调用mutations方法的
context.commit('inputCount', num)
}, 1000)
}
},
- 一秒后触发mutations函数
mutations: {
addCount (state, num) {
state.count += num
}
}
- 然后mutations修改state中的数据
state: {
count: 101
}
})
- 最后state再把更新的数据返回到组件中
- 形成闭环
辅助函数------mapActions
将action导入到组件中
import { mapActions } from 'vuex'
methods: {
...mapActions(['setAsyncCount'])
}
通过 this.方法 就可以调用
methods:{
add(){
this.setAsyncCount
}
}
getters核心概念
除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters
例如,state中定义了list,为1-10的数组,
state: {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
在组件里循环
# 方法一 (了解不推荐使用)
<li v-for="item in $store.state.list" :key="item">{{item}}</li>
# 方法二 (了解不推荐使用)
<li v-for="item in showLIst" :key="item">{{item}}</li>
# 定义一个计算属性
computed:{
showList(){
// 必须有返回值
return this.$store.state.list.filter(item => item > 5)
}
}
getters是Vuex里面的计算属性.可以将state中的数据进行处理后返回
# 方法三 (可以跨组件使用)
<li v-for="item in #store.getters.showList" :key="item">{{item}}</li>
getters:{
//里面的第一个函数永远都是state
showList(state){
return state.list.filter(item => item > 5)
}
}
辅助函数------ mapGetters
<li v-for="item in showLIst" :key="item">{{item}}</li>
import { mapGetters } from 'vuex'
计算属性
computed: {
...mapGetters(['showList'])
}
模块 module 核心概念
模块定义- 准备 state
定义两个模块 user 和 setting
# 定义模块
export default{
state:{
userInfo:{
name:'阿田',
hobby:'吃锅盔',
age:18
}
},
mutations:{},
actions:{},
getters:{}
}
注册模块 在store/index.js里面注册子模块
# 导入子模块
import user from './modules/user'
const store = new Vuex.Store({
//注册子模块
modules:{
//模块名:模块对象,模块名与变量名一样可以简写
//user:user
user
}
})
使用模块里面的数据
# 看定义模块
$store.state.user.userInfo.name
// $store.state.模块名.定义的对象里面的数据
也可以通过 mapState 映射简写
import { mapState } from 'vuex'
computed: {
...mapState(['count'])
}
插值表达式
命名空间 namespaced
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的
想保证内部模块的高封闭性,可以采用namespaced来进行设置
export default {
# namespaced: true,
state:{},
mutations:{
test(){
console.log('我是user下面的test')
}
},
actions:{},
getters:{}
}
调用模块中的mutation
全局的: this.$store.commit('test') //('mutation函数名')
模块中的: this.$store.commit('user/test') //('模块名/mutation函数名')
辅助函数:
import {mapMutations}from 'vuex'
methods:{
add()
...mapMutations('user',['test']) //('模块名',['mutation函数名'])
}
# actions调用跟上面同理一样
使用辅助函数导入子模块的数据 (插值表达式太长不推荐)
- 引入辅助函数
- 在compted里面写
# 导入
import { mapState } from 'vuex'
computed: {
...mapState('user',['userInfo']) ('模块名',['mutation函数名'])
}
子模块总结:
开启 namespaced, 在子模块中设置 namespaced: true
访问 mutations 和 actions, 推荐直接调用:
调用 mutations
this.$store.commit(‘模块名/函数名’)
调用 actions
this.$store.dispatch(‘模块名/函数名’)
访问 state 和 getters, 强烈推荐使用辅助函数:
其中 getters 必须使用辅助函数
-
导入辅助函数
-
在 computed 中调用并展开
…mapState(‘模块名’, [‘数据’])
…mapGetters(‘模块名’, [‘数据’])