1、Vuex介绍
VueX是适用于在Vue项目开发时使用的状态管理工具,在之前vue中传参都是通过父子来传参的,对于同级别组件之间的通讯是不好实现的,vuex就是为了实现各个大小组件之间的传参而设定的,在具有VueX的Vue项目中,我们只需要把这些值定义在VueX中,即可在整个Vue项目的组件中使用。
2、VueX的工作流程
??
图来自于官方文档(Vuex (vuejs.org))?
Vue组件如果调用某个VueX的方法过程中需要向后端请求时或者说出现异步操作时,需要调用异步请求函数,也就是dispatch分发VueX中actions的方法,以保证数据的同步。可以说,actions的存在就是为了让mutations中的方法能在异步操作中起作用。如果没有异步操作,那么我们就可以直接在组件内提交(commit)Mutations中自己编写的方法来达成对state成员的静态操作。最终被修改后的state成员会被渲染到组件的原位置当中去。
3、安装
使用cdn在线导入:
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.2.0/vuex.min.js"></script>
npm命令行安装:
npm install vuex --save
4、vuex的五个核心属性
- state:数据模型(用来存放静态属性)
- getters:计算属性,主要是对state里面的数据进行计算
- mutations:通过提交突变来改变静态数据,有两个形参,一个是state(state是当前VueX对象中的state),一个是payload(payload是该方法在被调用时传递参数使用的)
- actions:异步请求,有两个默认参数,一个是context(上下文对象),这个对象里面有提交突变和分发对象一系列方法(context.commit('突变的方法名字',提交突变实参);),一个是payload(挂载参数)
- modules:模块化状态管理
?5、vuex基本使用
先获取一个store实例对象,然后将该对象注入到Vue实例中:
//状态机声明
let store=new Vuex.Store({
// 数据模型(存放静态数据)
state:{
msg:'vuex msg',
tableData:[]
},
// 计算属性
getters:{
reMsg(state){
//返回msg的大写
return state.msg.toUpperCase()
}
},
// 突变 这里指修改state里面的tableData变量
mutations:{
SET_TABLEDATA(state,payload){
//调用此方法时只需要传递payload实参
state.tableData=payload;
}
},
// 动作
actions:{
findAllCategory(context) {
//payload的实参
let res = [
{ name: '校园新闻', description: '最新的校园信息' },
{ name: '娱乐新闻', description: '最新的娱乐信息' },
{ name: '体育新闻', description: '最新的体育信息' },
]
// 提交突变
context.commit('SET_TABLEDATA', res)
}
}
})
let vm=new Vue({
el:"#app",
data:{msg: 'hello vue'},
//从vue实例的计算属性里面获取状态机的数据
computed: {
data1() {
//返回state里面的静态数据msg
return this.$store.state.msg
},
data2() {
//返回getters里面的reMsg方法
return this.$store.getters.reMsg
},
categories() {
return this.$store.state.tableData
}
},
methods:{},
created(){
// 分发动作(调用异步请求函数)
this.$store.dispatch('findAllCategory');
},
// 状态机注册 es6里面可以简写成store,
store:store
})
渲染到页面使用文本插值?
<div id="app">
{{msg}} <br>
state: {{data1}} <br>
getters: {{data2}} <br>
<ul>
//遍历数组
<li v-for="(item, index) in categories" :key="index">{{item.name}}</li>
</ul>
</div>
?结果如下:
6、vuex的辅助函数?
?vuex的辅助函数:mapState 、apGetters、mapMutations 、apActions。
// 1.状态机的声明
let store = new Vuex.Store({
// 数据模型(存放静态数据)
state: {
msg: 'vuex msg',
tableData: []
},
// 计算属性
getters: {
reMsg(state) {
return state.msg.toUpperCase()
}
},
// 突变
mutations: {
SET_TABLEDATA(state, payload) {
state.tableData = payload
}
},
// 动作
actions: {
findAllCategory(context) {
let res = [
{ name: '校园新闻', description: '最新的校园信息' },
{ name: '娱乐新闻', description: '最新的娱乐信息' },
{ name: '体育新闻', description: '最新的体育信息' },
]
// 提交突变
context.commit('SET_TABLEDATA', res)
// 分发动作
context.dispatch('deleteById')
},
deleteById() {}
}
})
// 解构辅助函数
let { mapState, mapGetters, mapMutations, mapActions } = Vuex
let vm = new Vue({
el: "#app",
data: {
msg: 'hello vue'
},
computed: {
//使用对象展开运算符将state getter 混入 computed 对象中
...mapState({
vuexMsg: 'msg',
tableData: 'tableData'
}),
...mapGetters(['reMsg']),
},
methods: {
// 使用辅助函数来映射动作/突变
...mapActions(['findAllCategory']),
...mapMutations(['SET_TABLEDATA']),
},
created() {
this.findAllCategory();
//修改载荷payload实参 前提条件要使用辅助函数来映射突变
this.SET_TABLEDATA([1, 2, 3]);
},
// 2.状态机的注册
store
})
<div id="app">
{{msg}} <br>
state: {{msg}} <br>
getters: {{reMsg}} <br>
<ul>
<li v-for="(item, index) in tableData" :key="index">{{item}}</li>
</ul>
</div>
??
?7、vuex模块化
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。namespaced表示设置命名空间。
// 1.声明模块化的状态
let moduleA = {
namespaced: true, // 通过名称访问moduleA模块
state() {
return {
aData: 'moduleA'
}
},
getters: {},
mutations: {
SET_ADATA(state, payload) {
state.aData = payload
}
},
actions: {
findAll(context) {
// 提交突变
context.commit('SET_ADATA', '修改moduleA')
}
}
}
let moduleB = {
namespaced: true,
state() {
return {
bData: 'moduleB'
}
},
getters: {},
mutations: {
SET_BDATA(state, payload) {
state.bData = payload
}
},
actions: {
query(context) {
context.commit('SET_BDATA', '修改moduleB')
}
}
}
// 2.初始化状态机
let store = new Vuex.Store({
modules: {
// 可以重命名vuex模块
a: moduleA,
b: moduleB
}
})
// 解构辅助函数
let { mapState, mapGetters, mapMutations, mapActions } = Vuex
let vm = new Vue({
el: '#app',
data: {},
computed: {
...mapState('a', ['aData']),
...mapState('b', ['bData']),
},
methods: {
...mapActions('a', ['findAll']),
...mapActions('b', ['query'])
},
cerated() {},
//注册状态机
store,
})
<div id="app">
<div>
//调用findAll和query两个方法提交突变
<button @click="findAll">修改A数据</button>
<button @click="query">修改B数据</button>
</div>
模块A的state:{{aData}} <br>
模块B的state:{{bData}} <br>
</div>
?Vuex构造函数内部提供了快捷映射数据/方法的方法,可以使用对象的解构,将内部的辅助函数解构出来:let { mapState, mapGetters, mapMutations, mapActions } = Vuex。在不用辅助函数的情况下可以通过this.$store.对象.参数来访问内部的一些常量、变量以及方法等。
|