Vue-管理状态仓库Vuex


什么是vuex

Vuex是一个状态管理工具,采用集中式存储管理应用的所有组件的状态,并且以相应的规则保证状态可预测的方式发生改变。本质就是把组件的共享状态和触发修改状态的函数抽离出来,这样就能获得状态或者触发行为。

Vuex的特点

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

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

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

4.一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;

5.对于组件中的私有数据,依旧存储在组件自身的data中即可.

什么情形下适合使用Vuex?

如果不打算开发大型单页应用,使用Vuex就会变得很冗余,就会有“牛刀杀鸡”的感觉,因为它会附带很多概念。这种情况下使用store模式就足够了。

如果正在开发一个中大型的单页应用,Vuex是更好的选择。

引入Vuex

1.手动下载引入
安装:

npm i vuex --save

导入:

import Vuex from "vuex"

Vue.use(Vuex)

创建仓库:

const store=new Vuex.Store({

           state:{msg:"我就是所有共享的数据"}

})

把仓库挂载到vm对象:

new Vue({

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

     router,

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

}).$mount( "#app")

2.使用Vue脚手架安装

vue create app

选择配置vuex
再main.js文件夹下引入store

import store from './store'

挂载到vm对象,跟上面一样

State

创建state状态,状态就是那个存数据的对象

const store=new Vuex.store({

           state:{data:"所有共享的数据"}
})

2.组件中访问数据

this.$store.state.msg

Getter

getter就像是store的计算属性,它会传入state对象供我们操作

设计

  getters: {
    //当作计数属性使用
    mycomput(state){
      //计算总价
      return state.arr.reduce((n1,n2)=>{return n1+n2.price*n2.count},0)
    }
  },

使用

this.$store.getters.mycomput

Mutation

组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
不要用赋值表达式直接在组件中给store设置新数据
这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI

注意:一条重要的原则就是要记住 mutation 必须是同步处理
为什么必须是同步处理?
因为每一条mutation都会被devtools记录,devtools需要捕捉前一状态、后一状态。如果mutation函数中如果有异步函数,devtools无法得知异步函数什么时候执行,也就无法记录状态的变更。

设计:

mutations: {
    mychange(state,obj){
       方式一:state.arr[0].price=obj  
       方式二:state.arr[0].price=obj.n   
    }
  },

使用:

//直接触发并传值(提交载荷)
方式一:this.$store.commit("mychange",10)  
//可以以一个对象的形式传入
方式二:this.$store.commit("mychange",{n:10})  
方式二另一种写法:this.$store.commit({type:"mychange",n:10})  //type属性值是需要触发的事件名,n则为obj下面的键值对

案例:

//vuex文件中
export default new Vuex.Store({
  state: {
    msg:"所有组件共享的数据",
    arr:[{id:1,price:1,count:22},{id:2,price:2,count:25},{id:3,price:1,count:26}]
  },
  getters: {
    //当作计数属性使用
    mycomput(state){
      //计算总价
      return state.arr.reduce((n1,n2)=>{return n1+n2.price*n2.count},0)
    }
  },
  //更改状态
  mutations: {
    mychange(state,obj){
          state.arr[0].price=obj
    }
  },
  
})
//home组件中
<template>
	<div>
		 <h2>home界面----{{$store.state.msg}}---总价:{{$store.getters.mycomput}}</h2>
         <Box1></Box1>
		 <Box3></Box3>
	</div>
</template>
<script>
	export default {
		components:{
			Box1:()=>import("./views/Box1.vue"),
			Box3: () => import("./views/Box3.vue")
		}
	}
</script>
//Box1组件中
<template>
    <div id="">
        <h2>Box1界面----{{this.$store.state.msg}}</h2>
        <button @click="fn">点击修改第一个price</button>
    </div>
</template>
<script>
    export default {
       methods: {
          fn(){
            this.$store.commit("mychange",10)
          }
       },
    }
</script>
//Box3组件中
<template>
    <div id="">
        <h2>Box3界面----{{this.$store.state.msg}}</h2>
    </div>
</template>

请添加图片描述

Action

actions选项的功能和mutations选项类似,但是也有不同之处:
Actions提交的是mutation,而不是直接变更状态;
Actions里面可以包含任意的异步操作;

所有的Action函数都接受一个与store实例具有相同方法和属性的context对象,这里的context对象指向当前的仓库,也就是store。因此在函数体中可以调用context.commit提交触发状态,相当于store.commit。这里注意,context对象不是store对象本身,这里相当于复制体。

设计:

  actions: {
    mychange2(ctx,obj){
      setTimeout(()=>{
         //提交载荷
         ctx.commit("mychange",obj)
      },1000)
    }
  },

使用:

//直接分发
this.$store.dispatch("mychange2", 20)
//以对象形式
this.$store.dispatch('mychange2',{n:20})
this.$store.dispatch({type: 'mychange2',n:20})

Module

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

//分块设计:
const moduleA = {
  namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
  state: { msg:1 },
  mutations: { change(state,n){state.msg=n} },
  actions: { change(context,n){context.commit("change",n)} },
  getters: { x(state){return state.msg} }
}

const moduleB = {
   namespaced: true,//局部命名空间	
   state: {  msg:1 },
   mutations: { change(state,n){state.msg=n} },
   actions: { change(context,n){context.commit("change",n)} },
   getters: { x(state){return state.msg} }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

//组件中的使用:
this.$store.state.a.msg // -> moduleA 的状态
this.$store.state.b.msg // -> moduleB 的状态
this.$store.commit("a/change",100)-> moduleA 的mutations
this.$store.commit("b/change",200)-> moduleB 的mutations
this.$store.getters["a/x"]-> moduleA 的getters
this.$store.getters["b/x"]-> moduleB 的getters
this.$store.dispatch("a/change",100)-> moduleA 的actions
this.$store.dispatch("b/change",200)-> moduleB 的actions

总结

使用vuex步骤:

  • 引入vuex;
  • 全局注册Vuex,Vue.use(Vuex);
  • 创建一个Vuex仓库,仓库里面可以包含五个选项:state(状态)、getters(对状态的过滤)、mutations(状态修改)、actions(异步提交修-改状态信息)、modules(模块);
  • 触发mutation:通过commit触发仓库中的状态更新,store.commit(“对应的mutation”);
  • 将仓库注入到Vue对象中,也可以挂载到Vue对象原型上;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

H5_ljy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值