九、Vuex

一、Vuex简介

官方上介绍:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具devtools extension,提供了诸如零配置的time-travel调试、状态快照导入导出等高级调试功能。

经过短暂接触,个人感觉Vuex有点像一个中转站,你可以将一些数据存到Vuex中,然后项目中的各个地方可以从Vuex中共享这些数据。

在做项目的过程中,当你需要跨组件共享数据,或者缓存一些数据的时候,可以通过Vuex来实现,当然组件之间的数据传递也可以通过bus、传参等方法,但是在多层嵌套的组件中去使用这些方法会变得很繁杂,不利于维护。因此Vuex是一个更好的选择。

当然如果应用足够简单,那就不需要使用Vuex,一个简单的store模式就足够使用了,这里不在描述store模式,可在官网上自行阅读

以下是Vuex的说明图,从图中可以看出,Vuex主要有三个部分组成,分别为State、Actions、Mutations,可以将其看为一个store,其中所有的公用数据都存储在State区域中。
vuex说明图
如果需要修改State区域中的数据,必须要经过特定的流程:如果有一些异步操作或者一些比较复杂的、批量的同步操作可以在组件中通过dispatch方法去调用Actions,然后Actions通过commit方法去调用Mutations,Mutations在通过mutate方法去修改State中的数据;当然如果只是一些简单的操作,可以跳过Actions,让组件通过commit方法直接去调用Mutations去修改State的数据

二、简单使用

这里的使用是在以vue-cli脚手架工具搭建的条件下的

1.项目结构

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

如果你的store文件太大,只需将actionmutationgetter分割到单独的文件。

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

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块
2.安装引入

(1).如果是直接在html文件中引用,可以直接在引入Vue之后引入vuex会进行自动安装

<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

(2).npm可以通过以下命令进行安装

npm install vuex --save

(3).创建store并引入
在一个模块化的打包系统中,必须显式地通过Vue.use()来安装Vuex,根据Vue推荐的项目结构,我们可以在项目src目录下创建store文件夹并在新建index.js文件,写入以下代码来创建一个store

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

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        city: '北京'
    }
})

然后在main.js中通过以下代码引入

……
import store from './store'

new Vue({
    ……
    store,
    ……
})
3.获取数据

在上文中我们已经成功的安装Vuex,创建了一个store并引入到vue实例当中,此时在其他任何需要使用到vuex数据的组件中都可以通过this.$store.state.city来获取数据

4.修改数据

在项目中修改store中的共享数据city具体需要经过以下步骤:

(1).首相让组件通过调用store实例的dispatch函数去调用store中的actions属性中的方法,dispatch函数的第一个参数是actions中的方法名称,第二个参数是传递的值;

(2).然后actions的对应方法会接收到两个参数,分别为上下文对象和传递的值,在方法中通过调用上下文对象的commit函数来调用store中的mutations属性中的方法,commit函数也需要传递两个参数,与dispatch一样;

(3).最后,mutations中的对应方法会接收到两个参数,一个是store中的state对象即存放数据的对象,第二是传递过来的值,在方法对state对象中的目标数据进行修改即可

当然,如果只是简单的修改数据,不涉及异步、批量等操作的时候,可以跳过actions,直接让组件通过commit方法调用mutations即可

而在修改数据时候因为要用到actionsmutations所以在src/store/index.js创建store时应该为其定义这些属性

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    city: '北京'
  },
  actions: {
    funcNameA (cxt, city) {
      cxt.commit('changeCity', city)
    }
  },
  mutations: {
    changeCity (state, city) {
      state.city = city
    }
  }
})

再在App.vue文件中编写以下内容

<template>
  <div id="app">
    <div>{{this.$store.state.city}}</div>
    <button @click="handleClick('上海')">上海</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods: {
    handleClick (city) {
      alert(city)
      this.$store.commit('changeCity', city)
    }
  }
}
</script>

<style>
</style>

至此,Vuex简单的数据获取以及数据修改操作就完成了

三、代码拆分

在上述代码中,我们把actionsmutationsstate的相关代码都放在了index.js中,按照官方推荐的目录结构,应该分别拆分为三个js文件,这样有利于项目代码的维护,层次也更加分明

首先我们在src/store目录下创建state.js文件,并将目前src/store/index.js中与state.js相关的部分抽取出来

export default {
  city: '北京'
}

mutationsactions也如法炮制,当然如果项目中只用到了mutations,name actions可以省去,之后再在index.js中引入使用即可

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state.js'
import mutations from './mutations.js'
import actions from './actions.js'

Vue.use(Vuex)

export default new Vuex.Store({
  state,
  actions,
  mutations
})

四、Getters

Vuex中提供了getters属性,作用与用法类似与vue实例中的computed属性,区别在于getters中定义的方法默认会接收到state对象作为入参,当我们需要根据state数据来处理或计算数据的时候,可以通过getters来定义方法得到计算值,避免冗余

export default new Vuex.Store({
  state,
  actions,
  mutations,
  getters: {
      cityNo (state) {
          return state.city + ' 01'
      }
  }
})

五、高级用法

1.引入Vuex中的映射方法

Vuex中提供了一些用于映射的方法,如:mapStatemapMutationsmapActinosmapGetters等,可以在需要使用Vuex的组件中通过

import { mapState, mapMutations, mapActions, mapGetters } from 'vuex' 

来引入

2.展开映射

引入了vuex提供的映射方法之后,可以通过...mapState(……)store对应的属性进行展开并映射到vue实例当中,具体做法如下:
- mapStatemapGetters一般是映射在computed属性中的

(1).数组形式展开映射

storestatecity映射到computed属性的city

computed: {
    ...mapState(['city'])    
}

(2).对象形式展开映射

storestatecity映射到computed属性的currentCity

computed: {
    ...mapState{
        currentCity: 'city'
    }
}
  • mapMutationsmapActions等一般都映射在methods属性中,用法与mapState一样,之后通过this.reflectName来调用方法即可

六、Module

唔。。后续再更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值