【vue】vuex基础知识

文章详细介绍了Vue.js中Vuex的状态管理模式,包括Vue组件间数据共享的方法、Vuex的基础使用和核心概念(state、mutation、action、getter)。Vuex提供了一个中心化的存储来管理全局状态,提高了组件间的通信效率,便于开发和维护。同时,文章提到了Vuex中的异步操作和模块化管理,帮助开发者更好地理解和运用Vuex。
摘要由CSDN通过智能技术生成

前言

  • 作为一个内心骚动想做点小系统的后端来说,学习Vue是过不去的一个坎,毕竟香嘛~
  • 遂写一篇博文用于记录在Vue中用的比较多的,且不容易记的知识点,方便自己在需要使用时能够查找到相关知识点以及如何快速使用
  • 在基础篇中,已经介绍了关于Vuex中的一些基础知识点,下面就会陆续介绍Vuex中进阶的一些知识点,总结出来方便自己随时查阅

正文

在官网上,对于Vuex的介绍为,Vuex是一个专为Vue.js应用程序开发的状态管理模式,说白了就是为了实现组件之间数据的共享;对于Vue来说,组件之间共享数据的方式:

父组件向子组件传值:v-bind属性绑定

子组件向父组件传值:v-on时间绑定

兄弟组件之间共享数据:EventBus

  • $on 接受数据的那个组件
  • $emit 发送数据的那个组件

一般情况下,只有组件之间共享的数据,才会必要存储到vuex中,对于组件中的私有数据,依旧存储在组件自身的data中即可

  • 能够在vuex中集中管理共享的数据,易于开发和后期维护
  • 能够搞笑的实现组件之间的数据共享,提高开发效率
  • 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步

Vuex的基本使用

  • Vuex主要用于管理Vue组件中共享的数据
  • Vuex中有state、mutation、action、getter等核心概念
  • 获取state可以通过this.$store.state.xx或者是通过定义mapState来获取
  • 修改state中的变量需要通过mutation函数实现,而mutation的触发由两种方式,一种是通过this.$store.commit()函数,另外一种就是通过mapMutations来实现
  • mutation只能用于修改数据,而Actions可以实现异步操作
  • 通过Actions的异步操作+mutation的修改数据,可以实现异步修改数据。调用Actions有两种方式,第一种是通过this.$store.dispatch来调用,另外一种方式是通过mapActions来调用
  • Getters函数用于对Store中数据进行加工,不会修改原本Store中的数据;Getters中的数据会受Store中数据进行影响
1.1 安装vuex依赖包
npm install vuex --save
1.2 导入vuex包
import Vuex from 'vuex'
Vue.use(Vuex)
1.3 创建store对象
const store = new Vuex.Store({
  // state中存放的就是全局共享的数据
  state: {count: 0}
})
1.4 将store对象挂载到vue实例中
new Vue({
  el: '#app',
  render: h => h(app),
  router,
  // 将创建的共享数据对象,挂载到Vue实例中
  // 所有的组件,就可以直接从store中获取全局的数据了
  store
})

Vuex的核心概念

Vuex中的主要核心概念如下:

 State
 Mutation
 Action
 Getter
2.1 State

在Vuex中,State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储,这里的Store相当于一个用于存储数据的公共容器

const store = new Vue.Store({
  state: {
    count: 0
  }
  ...
})
  • 组件访问State中数据的第一种方式
this.$store.state.全局数据名称
// 在html元素组件之间调用,则可以省略this,即
<span>{{$store.state.全局数据名称}}</span>
  • 组件访问State中数据的第二种方式
// 通过mapState辅助函数方式,实现组件访问State中数据的第二种方式
// 1. 从vuex中按需导入mapState函数
import { mapState } from 'vuex'


通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前的computed计算属性
// 2. 将全局数据映射为当前组件的计算属性
computed: {
  // ...表示展开映射,意思就是将全局属性映射为当前组件的计算属性
  ...mapState(['count'])
// 3. 直接在调用获取组件属性
<span>{{count}}</span>

2.2 Mutation

Vuex中的Mutation是用于变更Store中的数据。

在Vuex中,只能通过mutation变更Store数据,不可以直接操作Store中的数据。虽然通过mutation的方式来操作数据,虽然繁琐了一点,但是却可以集中监控所有数据的变化

例如, 需要让全局数据自增加1,则可以通过如下的方式在Mutation中定义

const store = new Vuex.Store({
  state: {
    count: 0
  },
  
  mutations: {
    add(state) {
      // 变更状态
      state.count++;
    }
  }
})

定义完mutation之后,下面就来介绍下Vuex的触发方式

  • 触发mutation方式一

通过$store.commit()函数来触发mutation

methods: {
  handle1 () {
    // 触发mutations的第一种方式
    this.$store.commit('add')
  }
}

接着就可以通过@click方法来调用handle1,从而来触发mutation函数

另外,可以在触发mutation函数时,传入参数

const store = new Vuex.Store({
  state: {
    count: 0
  },

  mutations: {
    add(state) {
      // 变更状态
      state.count++;
    },
    
    addN(state, n) {
      state.count += n;
    }
  }
})

然后定义handler2

methods: {
  handler2: {
    this.$store.commit('addN', 5);
  }
}
  • 触发mutation方式二

通过导入mapMutations辅助函数来触发mutations

// 1. 从vuex中按需导入mapMutations函数
import { mapMutations } from 'vuex'
...
// 2. 将制定的mutations函数映射为当前组件的methods函数
methods: {
  // 将add和addN方法映射为methods中的函数,拱当前组件使用。
  ...mapMutations({'add', 'addN'}),

  handleAdd() {
    this.add();
  },
  
  handleAddN(n) {
    this.addN(n);
  }
  // 或者直接在标签元素中直接@click=add()
}

对于mutations来说,只能够实现同步操作,不可以执行异步操作的

2.3 Action

从vuex官网中可以了解到,Action类似于mutation,不同之处在于

  • Action 提交的是 mutation,而不是直接变更状态
  • Action 可以包含任意异步操作

可以得出一个结论就是,如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据

如何定义Actions呢?

const store = new Vuex.Store({
  state: {
    count: 0
  },

  mutations: {
    add(state) {
      //变更状态
      state.count++;
    },

    addN(state, n) {
      state.count += n;
    }
  },

  actions: {
    // 通过context去调用mutation
    addAsync(context) {
      setTimeout(() => {
        context.commit('add'  
      }, 1000)
    },
    
    // 调用Actions是也可以传入参数
    addNAsync(context, n) {
      setTimeout(() => {
        context.commit('addN', n);
      }, 1000);
    }
  }
})

需要再次强调的是,只有通过mutation中定义的函数,才有权利去修改state中的数据,因此actions最终还是要调用mutation

  • 触发Actions的第一种方式
methods: {
  handleAddAsync() {
    this.$store.dispatch('addAsync');
  },

  handleAddNAsync() {
    this.$store.dispatch('addNAsync', n);
  }
}
  • 触发Actions的第二种方式

    可以通过mapActions辅助函数的方式来触发Actions

// 1. 从vuex中按需导入mapActions函数
import { mapActions } from 'vuex'
...

// 2. 将指定的actions函数,映射为当前组件的methos函数
methods: {
  ...mapActions(['addAsync', 'addNAsync']),

  handleAddAsync() {
    this.addAsync();
  },

  handleAddNAsync(n) {
    this.addNAsync(n);
  }
}
2.4 Getter

在Vuex官网中,用到了派生这一词来介绍Getter,在这里可以理解为就是用于对Store中的数据进行加工处理,形成新的数据,类似Vue的计算属性。Getter的数据是基于Store中的数据的,所以当Store中数据发生变化时,Getter中的数据也会随之变化

定义Getter

例如state中存有todos计划项,其对象有一个done状态表示完成与否

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },

  getters: {
    // 这里通过getters定义的doneTodos方法来过滤已完成的todo项
    doneTodos: state => {
      return state.todos.filter(todo => todo.done);
    },

    // 这里还可以通过传入getters对象来获取其他方法
    doneTodosCount: (state, getters) => {
      return getters.doneTools.length;
    },

    // 传入参数
    getTodoById: (state) => (id) => {
      return state.todos.find(todo => [todo.id](http://todo.id) == id);
    }
  }
})
  • 触发Getter定义函数的第一种方法
this.store.getters.doneTodos // -> [{id: 1, text: '...', done: true}]
this.store.getters.doneTodosCount // -> 1

  • 触发Getter定义函数的第二种方法

    通过mapGetters来触发Getter中定义的函数

// 1. 导入mapGetters辅助函数
import { mapGetters } from 'vuex'
...

// 2. 将制定的Getters函数映射为当前组件的函数
methods: {
  ...mapGetters(['doneTodos', 'doneTodosCount']),

  handleDoneTodos() {
    this.doneTodos();
  }
}

2.5 Module

当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store。通过对Vuex中的Store分隔,分隔成一个一个的Module模块,每个Module模块都拥有自己的state、mutation、actions和getters

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

对于模块中的mutations和getters,传入的第一个参数规定为state,而actions则依旧是context参数。如下

const moduleA = {
  state: {
    count: 0
  },

  mutations: {
    increment (state) {
      // 这里的 `state` 对象是模块的局部状态
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    }
  },

  actions: {
    // context对象其实包含了 state、commit、rootState。
    incrementIfOddRootsum (context) {
    if ((context.state.count + context.rootState.count) % 2 === 1) {
      // 调用mutations
      commit('increment')
      }
    }
  }
}

在module中通过mapState、mapGetters、mapActions和mapMutations等辅助函数来绑定要触发的函数

  • 第一种方式
methods: {
  ...mapActions([
    'some/nested/module/foo',
    'some/nested/module/bar'
  ])
}

在vuex中,可以为导入的state、getters、actions以及mutations命名别名,这样可以方便调用

methods: {
  ...mapActions([
    'foo': 'some/nested/module/foo',
    'bar': 'some/nested/module/bar'
  ])
}
  • 第二种方式

对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为

methods: {
  ...mapActions('some/nested/module', [
    'foo', // -> this.foo()
    'bar' // -> this.bar()
  ])
}
  • 第三种方式

    可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

export default {
  methods: {
    // 在 `some/nested/module` 中查找
    ...mapActions([
      'foo',
      'bar'
    ])
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值