目录
Vuex是一个专门为vue应用程序开发的一个状态管理模式,可以理解为一个"前端数据库"数据仓库。
在使用Vuex进行组件传参之间,我们还有另外两种方式能够进行组件传参(子传父、父传子 Vue总线),但是这两种方法都或多或少存在一些问题,vuex应运而生,解决了这些问题,便捷了开发。
2、在项目中的src目录下导入store模块,并将state.js/index.js/actions.js/mutation.js/getters.js进行维护
3、在store/index.js文件中新建vuex的store实例,并注册上面引入的各大模块
8、在自定义组件VuexPage1和VuexPage2中分别定义设值和取值方法
1、Vuex的异步加载主要是用到了Action.js文件,其次还需要用到Mutations.js文件。异步简单点讲就是两个方法互补干涉,互不影响,两个方法同时进行。
当我点击盘它的按钮时,餐馆变为小猪汉堡店,点击幕后老板时就会变为爱放屁的小锐,
点击幕后老板按钮:两个界面都会变为爱放屁的小锐 3、具体代码:
顺便带大家回顾一下父子组件传参与Vue总线
父组件--->子组件 通过属性props传递

子组件--->父组件 通过自定义事件:this.$emit('事件名',参数1,参数2,...);
这种方式的传值是通过数据总数Bus(自定义),this.$root.Bus.$emit('事件名',参数1,参数2,...)下面这张图,是一个TopNav组件想要传值给LeftNav组件通过总线来传值的方式:
LeftNav组件通过this.$root.Bus.$on拿到这个属性


如图所示是上面两种传参方式的一个流程图, 而我们Vuex主要是出于解决第二种Vue总线传参问题而产生的。
解决以下问题:
组件变量名过多导致定义的组件事件也会过多,一旦项目庞大程序员维护便十分吃力。
而Vuex拥有一个专门管理变量的工具state(状态管理工具),具体解释在后面!
Vuex一共分为了五大核心组件,一张图解让你看懂Vuex

官方图示:
1.State:单一状态树用一个对象就包含了全部的应用层级状态;每个应用将仅仅包含一个 store 实例
2.Getters:状态获取(可以认为是store的计算属性),在组件中的computed中引入
getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
Getter 接受 state 作为其第一个参数,也可以接受其他 getter 作为第二个参数
3.Mutations:
3.1触发同步事件更改 Vuex 中 store 的状态的唯一方法是commit mutation;
3.2mutation类似于事件,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler);
3.3回调函数对状态进行更改, state 作为第一个参数
4.Actions:提交mutation,可以包含异步操作
4.1Action提交的是mutation,而不是直接变更状态
4.2.Action可以包含任意异步操作
4.3.Action的回调函数接收一个 context 上下文参数,注意,这个参数可不一般,它与 store 实例有着相同的方法和属性
5.store
每一个Vuex应用的核心就是store(仓库),store基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
前提:在进行vuex的操作时,必须要将Vuex的配置给安装好:
npm install vuex -S 注意下载最新版本,本次使用的是 npm i -S vuex@3.6.2版本

- import Vue from "vue"
- import Vuex from "vuex"
- import actions from "./actions"
- import getters from "./getters"
- import state from "./state"
- import mutations from "./mutations"
-
-
-
- Vue.use(Vuex)
-
- //引入store实例
- const store = new Vuex.store({
- state,
- getters,
- actions,
- mutations
-
- })
-
- export default store

- export default{
- resName:'小朱餐馆'
- }
- export default{
- //设置变量 state对应的是变量管理器state.js
- setResName:(state,payload)=>{
- //payload载荷 将变量管理器中的某个变量赋给载荷
- state.resName=payload.resName;
- }
- }
使用到了java8的特性箭头函数
- export default{
-
- //通过state拿到具体的变量的值
- getResName:(state)=>{
- return state.resName;
- }
- }
Vuexpage1
- <template>
- <div>
- <p>欢迎来到{{msg}}</p>
- <button @click="buy">盘它</button>
-
- </div>
- </template>
-
- <script>
- export default {
- name:'VuexPage1',
- date(){
- return{
-
- }
- },
- methods: {
- buy() {
- this.store.commit('setResName',{
- resName:'小猪の汉堡店'
- })
- },
-
- computed: {
- msg() {
- //从Vuex的state文件中取值
- return this.$store.getters.getResName;
- }
- }
- }
- </script>
-
- <style>
- </style>
注意:其中同步方法中改变初始化变量值只能通过唯一方法commit来设置,取值则是通过computed属性。
VuexPage2
- <template>
- <div>
-
- <p>欢迎来到{{msg}}</p>
- </div>
- </template>
-
- <script>
- export default {
- name: 'VuexPage2',
- date() {
- return {
-
- }
- },
- computed: {
- msg() {
- //从Vuex的state文件中取值
- return this.$store.getters.getResName;
- }
- },
- }
- </script>
-
- <style>
- </style>

当我点击页面1的盘它按钮后,页面1和页面2的变量值都由原来的小朱餐馆变为小朱汉堡店
原因:
因为我们的同步方法Mutation中是拿到了初始变量值小朱餐馆的,并且在getters中也拿到了,当我在页面1中通过commit方法改为小猪汉堡店,state中的也变为小猪汉堡店,getters中自然而然也就变为小猪汉堡店了。所以就同时改变。
Actions.js:
- export default{
- setResNameASync:(context,payload)=>{
- setTimeout(function() {
- context.commit('setResName',payload);
- }, 6000);
- )}
这个文件中的代码和同步文件中的代码不一样,这里的context等价于this.$store,也就是代表了Vuex的上下文,payload就是用来保存参数进行传参的容器
- buyASync(){
- this.store.dispatch('setResNameASync',{
- resName:'爱放屁的小锐',
- _this:this
- })
- }
- },
当我点击VuexPage1中的幕后老板方法时,我就会调用store中的dispatch(异步)方法,里面有两个参数,第一个参数是要调的方法名,第二个是要改的餐馆名字(也就是一个对象,载荷),之后进入到Action.js中,调用方法,这里调用了一个3秒的方法,之后就会跳到Mutations.js中调用同步存值的方法,这时两个界面的值就会同时改变了,从一开始讲的异步,其实是两个方法进行对比,这里是将改变和幕后老板两个方法进行对比,当你点击第一个方法时,会发生改变,点击第二个方法时,也会发生改变。互不影响,互不干涉
Vuex按常理来说是不能进行数据后台交互的,但我们可以将Vue实例作为一个变量进行传递
actions.js
- export default{
- setResNameASync:(context,payload)=>{
- setTimeout(function() {
- context.commit('setResName',payload);
- }, 6000);
-
- let _this=payload._this;
- let url = _this.axios.urls.SYSTEM_MENU_TREE;
- _this.axios.post(url,{}).then(r=>{
- consloe.log(r);
- }).catch(e=>{
-
- });
- }
-
-
-
-
- }
Vuexpage1:
- <template>
- <div>
- <p>欢迎来到{{msg}}</p>
- <button @click="buy">盘它</button>
- <button @click="buyAsync">幕后店长</button>
- </div>
- </template>
-
- <script>
- export default {
- name:'VuexPage1',
- date(){
- return{
-
- }
- },
- methods: {
- buy() {
- this.store.commit('setResName',{
- resName:'小猪の汉堡店'
- })
- },
- buyASync(){
- this.store.dispatch('setResNameASync',{
- resName:'爱放屁的小锐',
- _this:this
- })
- }
- },
- computed: {
- msg() {
- //从Vuex的state文件中取值
- return this.$store.getters.getResName;
- }
- }
- }
- </script>
-
- <style>
- </style>