vuex状态管理
1概念:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生
集中管理状态 每次被分组件提交方法就触发到 总仓库得数据
就是共享的状态用state来存放,用mutations来操作state,但是需要用store.commit来主动式的操作mutations。
vuex大概就是根据需求定义一些全局变量,但是我们必须通过store去访问和修改它。
我们可以把vuex分为state,getter,mutation,action四个模块,通俗的讲一下四个模块的作用:
state:定义变量;
getters:获取变量;
mutations:同步执行对变量进行的操作;
actions:异步执行对变量进行的操作;
2 使用
1安装
npm install vuex --save
2引用:import Vuex from 'vuex'
3注册 Vue.use(Vuex)
4实例化const store = new Vuex.Store({
state:{//数据源 totalPrice:0 }, mutations:{//1更改 Vuex 的 store 中的状态的唯一方法是提交 mutation 2必须是同步函数 increment(state,price){ state.totalPrice+=price }, decrement(state,price){ state.totalPrice-=price } }, actions:{
// 存放组件需要调用的异步操作。若组件想要改变State
中的数据,必须先通过Dispatch方法调用Actions(有时可以忽略调用Actions,直接调用Mutations),
执行一些异步或同步操作 increase (context,price){//context可以随意,price就是传递的参数 context.commit('increment',price) }, decrease (context,price){ context.commit('decrement',price) } },
//有时候我们需要从 store 中的 state 中派生出一些状态,getter 会暴露为 store.getters 对象在组件中使用。 getters:{ discount(state){ return state.totalPrice *0.8; } }
})
new Vue({ el: '#app', //5.把store放在全局的实例化对象里,可以在全局的所有地方用 store, components: { App}, template: '<App/>' })
<template> <div id="app"> <Apple></Apple> <Banana></Banana> <p> 总价{{totalPrice}}</p> <p> 折后价:{{discountPrice}}</p> </div> </template> <script> import HelloWorld from './components/HelloWorld' import Apple from './components/Apple' import Banana from './components/Banana' export default { name: 'App', components: { HelloWorld, Apple, Banana }, computed:{ totalPrice(){ //由于vuex的状态存储是响应式的,所以从store实例中读取状态的最简单方法就是使用计算属性来返回某个状态: return this.$store.state.totalPrice }, discountPrice(){ //getter 会暴露为 store.getters 对象 return this.$store.getters.discount } } } </script>
子组件
<template> <div> <p>{{msg}} 单价{{price}}</p> <button @click="addOne">add one</button> <button @click="minusOne">minus one</button> </div> </template> <script> export default{ data(){ return{ msg:'banana', price:15 } }, methods:{ addOne(){ //直接commit一个mutation
// 2个参数解释 increment 是mutation的事件名称,this.price是需要传递的参数 this.$store.commit('increment',this.price) }, minusOne(){ this.$store.commit('decrement',this.price) } } } </script>
<template> <div> <p> {{msg}}单价:{{price}} </p> <button @click="addOne">add one</button> <button @click="minusOne">minus one</button> </div> </template> <script> export default{ data(){ return{ msg:'apple', price:5 } }, methods:{ addOne(){ //dispatch一个action,以action作为一个中介再去commit一个mutation
// 2个参数解释 increase是action的事件名称 this.price是传递的参数 this.$store.dispatch('increase',this.price) }, minusOne(){ this.$store.dispatch('decrease',this.price) } } } </script>
3总结
如果是vue-cli创建项目的时候已经安装过vuex,state/index.js里面已经有了部分代码 ,不需要自己引用注册实例化,直接使用即可
1 mutation 改变state ->触发视图更新
2 action 通过dispatch触发 -》 提交mutation ,间接改变state ->触发视图更新
mutations和actions的区别与联系:
action只能调用mutation不能直接更改state,执行 action 来分发 (dispatch) 事件通知 store 去改变。
action里可以进行一些异步的操作,再去触发mutation 。
mutation里必须是同步的触发操作state。