看到这里是不是有些开心,终于要结束了,看到vuex说明对Vue已经有了一些了解。vuex是Vue官方的一款状态管理工具。采用集中式存储管理应用的所有组件的状态,很是强大。
文章结构:

  • 1.Vuex使用场景
  • 2.Vuex状态管理模式
  • 3.vuex一站式应用(state,getters,muattions,actions)
  • 4.Module
  • 5.严格模式
  • 6.项目结构

1.Vuex使用场景

为什么要使用vuex呢,可以考虑一下,一个整站有很多的网页,很多的数据,也是由很多的组件拼成的。每个组件之间会共享一些状态。比如说用户的登录状态或者购物车。这个购物车在头部会用到,在页面会用到,在页面其他部分也会用到。

如果在头部对购物车部分进行增删改查,页面也要进行同步更新,直接的做法就是通过事件,当购物车组件的列表更新时,不论是侦听属性watch还是计算属性computed触发了更新,就可以通过事件或者eventbus传到另外一个组件。

这样做的缺点就是当组件很长复杂时,调用组件非常多,要挨个依次去通知所有的组件去更新,这样就很复杂耗时。

状态管理的模型就是有一个统一的数据管理中心,就是数据仓库store,store用于维护状态数据,它包含着应用中大部分的状态 (state)。流程图如下:

Vuex一站式学习与应用
如上面模式图,每个组件进行更新的时候就会通知数据中心store,数据中心再将共享状态给每一个调用它的组件进行更新。

2.状态管理模式

Vuex一站式学习与应用
上面这个模式对于足够复杂的大型应用十分高效,如果你的项目不是大型的单页面应用,是比较简单的应用,建议最好不要使用 Vuex。一个简单的 store 模式就可以了。
如果构建的是一个中大型单页应用,可能要考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

对于Vuex 背后的基本思想官方文档中介绍如下:
Vuex一站式学习与应用

3.vuex一站式实例

  1. 安装
    与vue-router相同,可以直接使用npm install vuex --save保存依赖,或者使用淘宝镜像。如下图:
    Vuex一站式学习与应用

  2. 引入与注册
    安装完vuex以后就可以跟vue-router一样引入和注册vuex。方法如下:

    <main.js文件>

    //引入
    import Vuex from 'vuex'
    
    //注册
    Vue.use(Vuex)
    
  3. 实例化——>全局使用
    一个最简单的方式就是实例化store。store是通过vuex的store方法Vuex.store()实例化的,需要提供一个初始 state 对象和一些 mutation。实例化代码如下:
    <main.js文件>

    let store = new Vuex.Store({
    	//Vuex使用单一状态树state,用一个对象就包含了全部的应用层级状态.
    	//单一状态树让我们能够直接地定位任一特定的状态片段.
    	//在调试的过程中也能轻易地取得整个当前应用状态的快照。
    	state: {
    		totalPrice: 0
    	},
    	//getter 的返回值会根据它的依赖被缓存起来,
    	//且只有当它的依赖值发生了改变才会被重新计算
    	//有了getter就不必每次从数据集中拿原始数据
    	getters: {
    		getTotal(state){
    			return state.totalPrice
    		}
    	},
    	//动作参数
    	mutations: {
    		//通过state参数改变price
    		increment (state, price){
    			state.totalPrice += price
    		},
    		decrement (state, price){
    			state.totalPrice -= price
    		}
    	},
    	//Action 类似于 mutation,不同在于:
    	//Action 提交的是 mutation,而不是直接变更状态。
    	//Action 可以包含任意异步操作。
    	actions: {
    		increase (context, price){
    			context.commit('increment',price)
    		}
    	}
    })
    

    实例化store之后,就要在全局使用store ,

    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      //router: router
      router,
      //全局使用store
      store,
      components: { App },
      template: '<App/>'
    })
    
    

    到这里主页面使用结束,下面看看各个子组件怎么变化的。

  4. 子组件状态管理实现

    • App.vue组件
      首先导入两个子组件animal和fruit,
      通过 store.state 来获取状态对象,
      由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。
      代码如下:

      <template>
        <div id="app">
          <img src="./assets/logo.png">
          {{ totalPrice }}
          <!-- //使用组件 -->
          <Animal></Animal>
          <Fruit></Fruit>
        </div>
      </template>
      
      <script>
        import Animal from './components/animal'
        import Fruit from './components/fruit'
        export default {
          // name: 'App',
          components: {Animal,Fruit},
          //由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可
          computed: {
            totalPrice(){
              //通过 store.state 来获取状态对象
              //return this.$store.state.totalPrice
              return this.$store.getters.getTotal
            }
          }
        }
      </script>
      <style>
        #app {
          text-align: center;
        }
      </style>
      
    • animal.vue组件
      子组件animal有两个加一和减一的按钮。
      使用commit方法调用一个mutation。
      触发变化是在组件的 methods 中提交 mutation。
      通过 store.commit 方法触发状态变更。
      通过提交 mutation 的方式,而不是直接改变 store.state.price,是因为我们想要更明确地追踪到状态的变化。
      代码如下:

      <template lang="html">
      	<div class="animal">
      		<h1>{{msg}}</h1>
      		<button v-on:click="addOne">add one</button>
      		<button @click="minusOne">minus one</button>
      	</div>
      </template>
      
      <script>
          export default {
          	data() {
          		return {
          			msg: 'i like the animal!',
          			//当前价格设置
          			price: 5
          		}
          	},
          	//触发变化也仅仅是在组件的 methods 中提交 mutation。
          	methods: {
          		//通过提交 mutation 的方式,而不是直接改变 store.state.price,是因为我们想要更明确地追踪到状态的变化
          		//使用commit方法调用一个mutation
          		addOne(){
          			//通过 store.commit 方法触发状态变更
          			this.$store.commit('increment',this.price)
          			/*this.$store.dispatch('increase',this.price)*/
          		},
          		minusOne(){
          			this.$store.commit('decrement',this.price)
          		}
          	}
        }
      </script>
      
      
    • fruit.vue组件
      fruit.vue组件同animal.vue组件,代码如下:

      <template lang="html">
      	<div class="fruit">
      		<h1>{{msg}}</h1>
      		<button v-on:click="addOne">add one</button>
      		<button @click="minusOne">minus one</button>
      		<!-- <button v-on:click="getParam">get route Param</button> -->
      	</div>
      </template>
      
      <script>
          export default {
          	data() {
          		return {
          			msg: 'i like the fruit!',
          			price: 15
          		}
          	},
          	methods: {
          		//使用commit方法调用一个mutation
          		addOne(){
          			console.log(this.$store)
          			this.$store.commit('increment',this.price)
          		},
          		minusOne(){
          			this.$store.commit('decrement',this.price)
          		}
          	}
        }
      </script>
      

    综上几部分,发现不需要发送其他杂乱的东西,只需要调用对应的mutation就可以实现组件间共享状态的功能。
    实现的效果如下:
    Vuex一站式学习与应用
    store的值及其常用方法贴出来帮助理解。
    Vuex一站式学习与应用

4.Module

  • 由于使用单一状态树state,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

  • 为了解决以上问题,Vuex 允许将 store 分割成模块(module)。每个模块拥有并维护一套自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割,最后每个状态集即模块(module)都会合成到一个总的store对外接口上。

    如下示例:
    Vuex一站式学习与应用

5.严格模式

  • ES6的严格模式与vuex的严格模式
  1. JavaScript 严格模式(strict mode)即在严格的条件下运行。ES6的严格模式通过在脚本或函数的头部添加 “use strict”; 表达式来声明。

  2. vuex开启严格模式,仅需在创建 store 的时候传入 strict: true。如下:

    const store = new Vuex.Store({
      // 在创建vuex的store实例时开启严格模式
      strict: true
    })
    
  • vuex在严格模式下,不管什么时候发生了状态变更,而且变更不是由 mutation 函数引起的,都将会抛出错误。这样做能保证所有的状态变更都能被调试工具跟踪到。
  • 一定不能在发布环境下启用严格模式!!一定要在发布环境下关闭严格模式,以避免性能损失。因为严格模式会深度监测状态树来检测不合规的状态变更。

6.项目结构

此部分来自vuex官方文档。

  • Vuex 不限制你的代码结构。但是,它规定了一些需要遵守的规则:
  1. 应用层级的状态应该集中到单个 store 对象中。
  2. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
  3. 异步逻辑都应该封装到 action 里面。
  • 只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:
Vuex一站式学习与应用

每天进步一点点、充实一点点、快乐一点点、一起加油!

相关文章:

  • 2019-11-26
  • 2021-11-28
  • 2021-10-01
  • 2021-12-05
  • 2021-03-01
  • 2021-11-08
  • 2021-08-30
  • 2021-12-03
猜你喜欢
  • 2017-12-13
  • 2021-11-03
  • 2021-10-21
  • 2021-11-08
  • 2018-04-07
  • 2019-06-03
  • 2021-08-15
  • 2019-01-18
相关资源
相似解决方案