总体实现:分4块
1. 下载vuex插件:npm i vuex -S
2.引入vuex插件: import vuex from 'vuex'
3. 安装vuex插件:Vue.use(vuex) 然后实例化一个store实例, let store = new Vuex.Store(配置对象)
4.(在main.js中)注册到根:new Vue({store}) ,然后配置store里面的角色(这4个角色其实都是对象):actions 、mutations 和 、state 和getters这4个角色都是对象。
具体实现(7步):
(1)建立actions.js文件:
import axios from "axios"
let actions={
// actions其实就是1个对象,包含键值对;
// 类型:处理函数(处理请求)
// actions的类型函数会接收1个对象(该对象里面有commit函数, state数据和dispatch方法)和1个
数据负载
jia:({commit,state},payload)=>{
// commit("新的请求类型名",处理后的数据负载)
commit("increment",payload); // 提交给mutations时,请求类型需要换个说法称呼。
},
jian:({commit,state},payload)=>{
// ...业务逻辑处理完后,然后交给mutations对象.
commit("decrement",payload);
},
odd:({commit,state},payload)=>{
// 参考一定的条件才做修改
if(state.count % 2===0){
commit("increment",payload);
}
},
async:({commit,state},payload)=>{
// actions即可以处理同步业务也可以处理异步任务。
axios({
url:"/data/count.json" //在vue中第1个单斜杠是绝对路径,指的是public目录
}).then(res=>commit("increment",res.data.count))
}
};
export default actions;
(2)建立mutations.js文件。
let mutations={
// 请求类型:函数
// 注意:mutations不做任何业务逻辑(不管是同步还是异步,它都不做,它只负责对数据state做突变!),mutaions里面的函数只负责对state里面的数据做突变!
// mutations可直接拿到state对象和传过来的payload。
increment:(state,payload)=>{
state.count+=payload; //对state进行突变。
},
decrement:(state,payload)=>{
state.count-=payload;
},
// 不需要做业务逻辑(即此时不需要actions),直接是让mutaions对state做突变。
view_state:(state,payload)=>{
state.view=payload;
}
}
export default mutations;
(3)建立state.js文件(公共数据仓库)。
// 公共仓库state存储了2条数据
let state={
count:100,
view:false
}
export default state;
(4)建立getters.js文件。
let getters={
// 类型(组件要的数据,类似计算属性名):函数
// getters可以直接拿到state里面的数据,getters角色一般是将原始数据state进行一些处理。
gtcount:(state)=>{
return "处理后的"+state.count;
}
}
export default getters;
(5)建立vuex.js文件(专门配置vuex插件的,打造store实例,由实例来控制各个角色之间的通信)。
// 对vuex插件做一些配置。
import Vue from "vue"
import Vuex from "vuex" //引入的vuex是对象。
import actions from "../store/actions"
import mutations from "../store/mutations"
import state from "../store/state"
import getters from "../store/getters"
Vue.use(Vuex);// Vue中安装插件方法:Vue.use(插件变量名)
// 使用Vuex实例对象的Store类来:实例化store实例(打造实例),配置参数是1个对象,里面都是键值对.
// let store=new Vuex.Store({配置对象})
let store=new Vuex.Store({
// 这4个角色都是对象
actions, // actions:对象(引入的actions对象),键值对相等可简写。
mutations,
state,
getters
});
export default store;
(6)在main.js文件中(将store对象注册到根实例上):
// 在main.js文件中:
import Vue from 'vue'
import App from './App.vue'
import store from "./plugin/vuex"
new Vue({
// 将store注册到根实例上(即new Vue里面),则组件内部可以直接使用this.$store访问到根实例的store属性(store实际就是1个对象)
render: h => h(App),
store, // 注册到根实例上了,扩展了Vue的实例属性(原先vue上也自带了一些系统属性)
}).$mount('#app') //渲染虚拟DOM(map组件)挂载到真实的DOM元素(public下的index.html页面上的div元素
(7)在App根组件中(使用状态管理,mapActions和mapMutations函数,需要在模板中传参(传数据负载参数)!):
<template>
<div>
<h3>我是APP.vue页面</h3>
<h2>状态管理</h2>
<!-- mapActions、mapMutations传参是在模板中传参。 -->
<input type="button" value="+" @click="jia(5)">
<input type="button" value="-" @click="jian(3)">
<!-- 需要做一些业务的,需放在methods里面。 -->
<input type="button" value="odd" @click="odd(5)">
<input type="button" value="aysc" @click="async">
<!-- {{this.$store.state.count}} -->
<!--这里可直接使用数据类型gtcount-->
state的原始数据:{{$store.state.count}}
mapState抓取的state数据:{{count}}
经过getters处理后的数据:{{gtcount}}
<hr/>
<input type="button" value="盒子显示和隐藏" @click="view_state(true)">
<div v-if="$store.state.view">
我是盒子
</div>
</div>
</template>
<script>
import {mapGetters,mapActions,mapMutations,mapState} from "vuex"; // 解构vuex对象
// computed计算属性选项:由mapGetters、mapState函数接管(返回的都是对象)。
// methods方法选项:由mapActions、mapMutations函数接管(返回的都是对象)。
export default {
data(){
return{
// count:0 //当这个数据不止一个组件使用时,旧的方式是传递,新方式:状态管理(数据的集中式管理)
// 组件内部也可有自己的私有数据,即不是共享的数据,放在组件内部即可,然后操作的话,也不用交给action,直接在组件内部直接操作即可。
card:'10000'
}
},
name:"ji",
// mapGetters函数可以发送1个或多个请求(可以用数组)(将类型发给getters的,然后getters会把你
想要的数据返回过来)
// mapGetters接管computed选项,mapGetters发出的数据类型可在模板中直接使用。
// computed:mapGetters(["gtcount",gtcount2,gtcount3]),
computed:{
// 使用mapGetters和mapState接管computed
...mapGetters(["gtcount"]),
...mapState(["count"]) //扩展,不需要经过getters处理,想直接拿到数据的.
},
// methods:{
// jia(){
// this.count++;
// }
// jia(){
// 使用状态管理后,组件内部一般都不做业务了(把业务抽出来给了actions了),需要发送请求。
// this.$store.dispatch("请求类型",数据|负载)
// this.$store.dispatch("jia",100); //发出请求类型,发给了actions,actions要接收这个请
求。
// },
// jian(){
// // 发出请求
// this.$store.dispatch("jian",55)
// }
// },
// 这个东西是交给函数的,为什么外面还要再套个函数呢,麻烦。-解法:直接使用mapActions函数
// methods:mapActions(["jia","jian","odd","async"]), // mapActions可接收多个要发出去的
actions,返回的是1个对象,对象里面的key都是函数。
methods:{
// mapActions和mapMutations来收纳actions和mutaions,共同接管methods选项.
...mapActions(["jia","jian","odd","async"]), //扩展,然后下面就可以写自己的私有方法了
...mapMutations(["view_state"]) //返回的也是1个对象。
// changeBoxView(){
// this.$store.commit("view_state",true); //(因为没有任何业务)组件直接发送请求给mutations.
// }
},
mounted(){
// 返回的是1个对象,VueComponent对象。
// console.log(this);
}
}
</script>