解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。一般用来方便非关系组件传值。
下载安装:
1. 安装vuex依赖包:npm install vuex@3.5.1
2. 导入vuex包:
import Vuex from 'vuex'
Vue.use(Vuex)
3. 创建store对象:
const store = new Vuex.Store({
state: { count: 0}
})
4. 将store对象挂载到vue实例中:
new Vue({
store,
render: h => h(App)
}).$mount('#app')
优点和特点:
优点
1. 集中式实现组件全局状态管理,组件之间数据共享;
2. 共享的数据要存储到vuex中,私有数据依旧存储在组件自身的data中;
3. 集中管理共享的数据,易于开发和后期维护;
4. 组件之间数据共享,提高开发效率;
5. 响应式的存储数据,能够实时数据与页面的同步;
特点
1. 修改state状态必须通过mutations
2. mutations只能执行同步代码,ajax,定时器之类执行
3. actions执行异步代码,数据提交给Mutation间接变更数据
4. state的状态即共享数据可以在组件中引用
5. 组件中调用action
6. 每个模块有自己单独的state、mutations、actions、getters
属性:
state:定义State 公共数据源,放所有共享数据进行存储
方法一:原始形式获取state状态
<div>{{ $store.state.count }}</div>
方法二:辅助函数写法,映射为计算属性 (常用)
<div> {{ count }}</div>
import { mapState } from 'vuex'
computed: { ...mapState(['count']) }
方法三:计算属性写法
<div> {{ count }}</div>
computed: {
count () { return this.$store.state.count }}
mutations:用于修改state中的同步数据
1.只能通过mutation变更Store数据,不可以直接操作
2.这种方式操作稍微繁琐,但可以集中监控所有数据的变化
main.js 定义mutation方法调用mutaiions时修改state:
参数一是当前state属性;参数二是payload 载荷
mutations: {
addCount (state,payload) {
state.count += payload
}
}
触发mutation方法:
第一种方式:原始形式调用
1. <button @click="test">+1</button>
2. test () {
this.$store.commit('addN', payload1)
}
第二种方式:辅助函数映射为函数(常用)
1. <button @click="addCount(10)">+10</button>
2. import { mapMutations } from 'vuex'
3. methods: { ...mapMutations(['addCount']), }
actions:用于处理异步任务,数据commit提交给Mutation间接变更数据
触发action方法的两种方式:
第一种方式:
方法一:原始异步调用,数也可以放到action方法内
1. <button @click="test1">+1</button>
2. test1 () { this.$store.dispatch('getAsynCount') }
方法二:传参调用 params
test1 () { this.$store.dispatch('getAsynCount',123)
3. main.js 定义action方法异步数据请求:
actions: {
getAsynCount (context) {
setTimeout(() => {
context.commit('addCount', 1)
}, 1000);
}}
第二种方式:辅助函数异步,映射为函数(推荐)
1. <button @click="getAsynCount">+1</button>
2. import { mapActions } from 'vuex'
3. methods : { ...mapActions(['getAsynCount']) }
getters:用于对Store中的数据进行加工处理形成新的数据
1.类似于Vue的计算属性
2.Store中数据发生变化,Getter的数据也会跟着变化
使用getters的两种方式:
第一种方式:原始形式展示
1. <div> {{ $store.getters.filterList }} </div>
2. main.js 定义getter方法:
getters: {
showNum(state) {
return '当前最新的数量是:' + state.count
}}
例子:
state: { list:[1,2,3,4,5,6,7,8,9,10] }
getters:{
filterList: state => state.list.filter(item => item > 5)
},
第二种方式:辅助函数展示, 映射为计算属性(推荐)
1. <div>{{ filterList }}</div>
2. import { mapGetters } from 'vuex'
3. computed: {
...mapGetters(['filterList'])
}
modules:模块化
如果把所有的状态都放在state中,当项目变得越来越大的时候,Vuex会变得越来越难以维护,Vuex的模块化:每个模块有自己单独的state、mutations、actions、getters。
定义modules:
modules: {
namespaced: true,
user: {
state: {
token: '12345'
}
},
setting: {
state: {
name: 'Vuex实例'
}}
访问modules:获取子模块的状态
this.$store.state.子模块名称.属性名
1. main.js 根节点创建getters
getters: {
token: state => state.user.token,
name: state => state.setting.name
}
2. 组件引入main.js定义的计算属性,...mapGetters使用
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['token','name'])
}
3. 通过辅助函数的形式,映射为计算属性
<div> {{ token }} {{ name }} </div>
命名空间:打开命名空间:namespaced: true,
模块内部的actions、mutations、getters默认都是注册到全局命名空间的,可以使用命名空间进行区分。
如何访问带有命名空间的模块?
方案1:直接调用-带上模块的属性名路径user
this.$store.dispatch('user/updateToken')
方案2:辅助函数-带上模块的属性名路径
methods: {
...mapMutations(['user/updateToken']),
test () {
this['user/updateToken']()
}
}
方案3:createNamespacedHelpers 创建基于某个命名空间辅助函数(推荐)
import { mapGetters, createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('user')
methods: {
...mapMutations(['updateToken'])
}