Vue的仓库vuex

Vue.js是一个渐进式的框架,是一个分层的设计模式。一共分为五层,核心库为基础,在这基础上添加组件系统、客户端路由、大规模状态管理和开发环境。

其中大数据状态管理对应的技术就是vuex,它是由Vue框架开发团队提供的一个插件。

仓库vuex的作用:

能够在vuex中集中管理共享的数据,易于开发和后期维护;

能够高效地实现组件之间的数据共享, 提高开发效率;

存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步。

学习使用这个功能之前,我们先看一下它的结构:

 可以看到vuex在图中由Actions、Mutaitions、State组成,与组件实例化构成一个循环。

其中State为状态其实就是存放的数据;actions直译为行为,就是一个会对数据修改的一个异步行为,可以理解为是一个中转站;Mutaitions中是对数据真正的操作。

引入vuex

第一种方式:通过CDN引入

第二种方式:npm i vuex -save下载包再进行配置

在main.js中配置:

//导入:

import Vuex from "vuex"

Vue.use(Vuex)

//创建仓库
const store=new Vuex.Store({

      //配置state、actions、mutaitions等

})
//挂载到vm对象
new Vue({

     render(h){return h(app)},

     router,

     store//挂载以后  所有的组件就可以直接从store中获取全局数据

}).$mount( "#app")

第三种方式:vue cli脚手架自己配置,在vue create "项目名"时,选择上vuex,脚手架会自动帮我们创建成功。

具体来学习vuex的配置项

1、state状态 

就是我们共享数据的存放位置,就与data书写形式一样,如:

var store=new Vuex.Store({
  state: {
	  msg:"仓库中的数据",
	  arr:[{id:001,name:"zs"},{id:002,name:"ls"}],
      obj:{a:1}
  },

在组件中获取数据时,如获取msg为例,通过this.$store.state.msg。

这里的this.$store,是在引入时通过Vue.use(Vuex)时给Vue对象原型上绑定了的对象,所有组件中都可以使用。

2、getter

它就好比我们学过的计算属性,每个方法内都会传入state,可以操作state内的数据。

例如:返回state中两个数的和

var store=new Vuex.Store({
  state: {
	  a:1,
      b:2
  },
  getters:{
      sum(state){
            return state.a+state.b
        }
    }
})

 获取sum:this.$store.getters.sum

3、Mutaitions

这个配置用于修改state中的数据,官方文档中它是在同步代码中实现,但是我们自己测试的时候在里面写异步代码也能实现。

还有,官方文档中说它是更改 Vuex 的 store 中的状态(数据)的唯一方法,不要用赋值表达式直接在组件中给store设置新数据,但是直接赋值效果也能够实现。

组件中修改state的数据,需要用到$store一个方法commit(),它的作用是传递参数并触发mutaition里对应的方法(专业说法为提交负荷)。

commit()的传参

1、普通形式:commit("name",d),这里的name为mutaitions中配置的方法名,d为我们传递的参数,可以是数字、数组、对象等。

2、以对象形式传入:commit({type:"name",d:dd}),把整个对象作为了第二个参数传入mutations,type对应的就是mutaitions中配置的方法名。

mutaitions里面的配置:

mutations: {
	  name(state,arg){
		  //业务
	  },

name为方法名,第一个参数是传入的state,第二个参数就是commit传来的参数。

完整实现一下:在box组件中修改state中的值

box.vue:

mounted(){

    this.$store.commit("change",11)
}

store下的index.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)//让组件的原型链中 有仓库的工具代码

export default new Vuex.Store({
  state: {
	 num:1
  },
  mutations: {
	  change(state,arg){
		  state.num=arg
	  }
  },
})

程序一运行,state中的num由1就变成了11.

4、Action

Action 可以包含任意异步操作,它的作用就像一个中转站,当修改的state的代码不是异步的或者是没有什么逻辑判断,我们直接在组件中commit操作Mutaitions;但是当存在异步操作或者很多逻辑判断时,我们一般就要加上Action这一步,组件中先将数据传递给Action,Action处理后再传给Mutaitions。

组件中传递信息给Action需要用到$store上的dispacth方法,它的传参跟commit传参形式是一样的,一种是普通形式,一种是对象形式。

actions中的配置是方法传来的两个参数,第一个不再是state,而是一个上下文对象,是一个简化了的store对象;第二个参数为组件中传递的数据。

流程非常简单,就是:组件——>Action——>Mutaition

代码展示:

组件中:

mounted(){
    this.$store.dispatch("change",11)
}

actions和mutaitions中:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)//让组件的原型链中 有仓库的工具代码

export default new Vuex.Store({
  state: {
	 num:1
  },
  actions:{
    change(context,arg1){
        //异步处理
        setTimeout(()=>{
           context.commit("change1",arg1)
        })
    }
        
},
  mutations: {
	  change1(state,arg2){
		  state.num=arg2
	  }
  },
})
​

5、Module

可用于业务分块开发: 由于使用单一状态树,应用的所有状态(数据)会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter

具体使用:

分块做业务时,一个对应一个store这样不容易混乱,而且模块化开发更容易维护。

一个人对应一个js文件,在里面配置自己的 state、mutation、action、getter,然后导入导出到index.js文件中,放到modules配置项中。

如:自己的js文件

export default {
	namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
	state: {
		msg:"张三的公共数据"
	},
	getters: {	
		...
	},
	mutations: {
		....
	},
	actions: {	
		...
	}
}

index.js中引入:

import Vue from 'vue'
import Vuex from 'vuex'
import  Model1 from "./Model1.js"

Vue.use(Vuex) //让组件的原型链中 有仓库的工具代码

export default new Vuex.Store({
	state: {
	},
	getters: {				
	},
	mutations: {	
	},
	actions: {	
	},
	modules: {
		Model1,
	}
})

使用时,某个组件要使用Model1中的公共数据:this.$store.state.Model1.msg;

要使用Model1中motaitions配置的方法:this.$store.commit("Model1/change",num);

使用getters:this.$store.getters["Model1/x"];

使用dispatch:this.$store.dispatch("Model1/change",num)

mapState,mapGetters,mapMutation,mapAction的使用

mapState

最后介绍一种编写代码的优化,在组件使用state数据时,我们需要this.$store.state.n才能取到数据,当要取大量数据时,this.$store.state都是重复的操作,因此官方给我们了一个mapState方法来优化,借助它来生成计算属性。

要使用首先在组件中,引入这个mapState,如:import {mapState} from 'vuex'

mapState()方法可以传入数组或者对象。

传入对象时:mapState({a:"aa",b:"bb"}),其中a,b为生成的属性名,"aa"和"bb"就是this.$store.state.aa和this.$store.state.bb。

等同于:

computed:{

        a(){

                return this.$store.state.aa

        }

}

这样就可以看出,框架利用mapState将state中数据帮我们生成了计算属性。这个时候我们要使用this.$store.state.aa时,直接使用a就行了,是不是极大的减少了代码量。

传入数组时,更为简洁:mapState(["aa","bb"]),这样的意思就是让计算属性名与state中的属性名相同。等同于对象写法:mapState({aa:"aa",bb:"bb"})。

注意:属性值加引号

mapState(["aa","bb"])运行后,aa就可以取出this.$store.state.aa。

写出代码:

  import {mapState} from "vuex"
  export default{
    computed:{
      ...mapState(["aa","bb"]),
      ...mapState({a:"aa",b:"bb"}),//不想计算属性与state数据同名时用
    }
  }

注意这里mapState前面要加...,这是拓展运算符。因为mapState的返回值是一个对象,需要把它拆开成每一项,形成键值对的形式,否则会报错。

mapGetters

用法与mapState相同,通过mapGetters将它的数据转换为组件的计算属性。两个方法只是名字不同,用法全都相同,故不在详细说明。

mapMutations

前面两个方法是转换为计算属性,优化简写this.$store.state和this.$store.getters

很明显看到mapMutations,我们应该就已经猜到了它的用法。即,优化简写this.$store.commit()

同样它传入的参数也有两种形式:对象和数组

对象写法:mapMutations({a:"a1",b:"b1"}),

等同于:

  methods: {

      a(value){

        this.$store.commit("a1",value)

      },

       b(value){

        this.$store.commit("b1",value)

      },

    },

细心的同学可以看到,这里的生成的方法需要传参。这里已经生成了a和b方法,在实际使用的时候我们手动给它传一个参数,

如:当点击按钮时,将10传到mutaitons配置的a1方法中

<template>
 <div id="app">
      <button @click="a(10)"></button>
  </div>
</template>
<script>
  import {mapMutations} from "vuex"
  export default{
    methods: {
      ...mapState({a:"a1",b:"b1"}),
    },
}

 数组写法:mapMutations(["a1","b1"]),这个的意思就是生成的方法名与mutaitions配置的方法名相同。

注意:加引号

mapActions

用法与mapMutations相同不再叙述。

猜你喜欢

转载自blog.csdn.net/m0_59345890/article/details/126840436
今日推荐