超nice的vuex教程

文章目录

  • 什么是 vuex ?
    • 引入 vuex (前提是已经用vue脚手架工具构建好项目)
  • 来个 demo
  • state 访问状态对象
  • Mutations 修改状态($store.commit())
  • 模版获取 Mutations 方法
  • getters 计算过滤操作
    • getters 基本用法
    • 用 mapGetters 简化模版写法
    • actions 异步修改状态
    • 模版中的使用
    • 增加异步检验
    • module 模块组

什么是 vuex ?

vuex是一个专门为vue.js设计的集中式状态管理架构。状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。

引入 vuex (前提是已经用vue脚手架工具构建好项目)

1、利用npm包管理工具,进行安装 vuex。在 Terminal 中输入下边的命令就可以了。

npm install vuex --save

要注意的是这里一定要加上 --save ,因为你这个包我们在生产环境中是要使用的。

2、新建一个 store 文件夹(这个不是必须的,假设文件夹在 src 目录下),并在文件夹下新建 store.js 文件,文件中引入我们的 vue 和 vuex 。

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

3、使用我们 vuex,引入之后用 Vue.use 进行引用

Vue.use(Vuex)

4、在 main.js 中引入新建的 vuex 文件

import store from './store/store'

5、然后,在实例化 Vue 对象时加入 store 对象:

new Vue({
  el: '#app',
  router,
  store, //使用store
  template: '',
  components: { App }
})

来个 demo

1、现在我们 store.js 文件里增加一个常量对象。store.js 文件就是我们在引入 vuex 时的那个文件。

const state = {
  count: 1
}

2、用 export default 封装代码,让外部可以引用。

export default new Vue.Store({
  state
})

3、新建一个 vue 的模版,位置在 components 文件下,名字叫 count.vue。在模版中我们引入我们刚建的 store.js 文件,并在模版中用 {{$store.state.count}} 的值。



4、在 store.js 文件中加入两个改变 state 的方法。

const mutations = {
  add(state) {
    state.count += 1
  },
  reduce(state) {
    state.count += 1
  }
}

这里的 mutations 是固定的写法,意思是改变的,所以你先不用着急,只知道我们要改变 state 的数值的方法,必须写在 mutations 里就可以了。
5、在 count.vue 模版中加入两个按钮,并调用 mutations 中的方法。

这样进行预览就可以实现对 vuex 中的 count 进行加减了。

state 访问状态对象

const state,这个就是我们说的访问状态对象,他就是我们 SPA (单页应用程序)中的共享值。

学习状态对象赋值给内部对象,也就是把 store.js 中的值,赋值给我们模版里 data 中的值。有三种赋值方式

一、通过 computed 的计算属性直接赋值
computed 属性可以在输出前,对 data 中的值进行该改变,我们就利用这种特性把 store.js 中的 state 值赋值给我们模版中的 data 值。

computed: {
  count() {
    return this.$store.state.count;
  }
}

这里需要注意的是 return this.$store.state.count 这一句,一定要写 this,要不你不会赵东啊 $store 的。这种写法很好理解,但是看起来是比较麻烦的, 那我们来看看第二种写法。

二、通过 mapState 的对象来赋值
我们首先要用 import 引入 mapState

import { mapState } from 'vuex'

然后还在 computed 计算属性里写如下代码:

computed: mapState({
  count: state => state.count  //传入state,返回state.count
  // 大概就是 count = state.count
})

这里我们使用 ES6 的剪头函数来给 count 赋值

三、通过 mapState 的数组来赋值

computed: mapState(["count"])

这个算是最简单的写法了,在实际项目开发当中也经常这样使用。

Mutations 修改状态($store.commit())

Vuex 提供了 commit 方法来修改状态,我们粘帖出 Demo 示例代码内容,简单回顾一下,我们在 button 上的修改方法。



store.js 文件:

const mutations = {
  add(state) {
    state.count += 1;
  },
  reduce(state) {
    state.count -= 1;
  }
}

我们发现这个 $store.commit 传入的是 mutations 里面的一个方法名

传值:这知识一个最简单的修改状态的操作,在实际项目中我们常常需要在修改状态时传值。比如上边的例子,是我们每次只加1,而现在我们要通过所传的值进行想加。其实我们只需要在 Mutations 里再加上一个从参数,并在 commit 的时候传递就可以了。我们来看具体代码:

现在 store.js 文件里给 add 方法加上一个参数 n。

const mutation = {
  add(state, n) {
    state.count += n
  },
  reduce(state) {
    state.count -= 1
  }
}

在 Count.vue 里修改按钮的 commit() 方法传递的参数,我们传递 10,意思就是每次加 10。

模版获取 Mutations 方法

实际开发中我们也不喜欢看到 $store.commit() 这样的方法出现,我们希望跟调用模版里的方法一样调用。例如:@click="reduce" 就和没引用 vuex 插件一样。要达到这种写法,只需要简单的两步就可以了:
1、在模版 count.vue 里用 import 引入我们的 mapMutations:

import { mapState, mapMutations } from 'vuex'

2、在模版的 标签里添加 methods 属性,并加入 mapMutations

methods: mapMutaions([
  'add', 'reduce'
])

通过上边两部,我们已经可以在模版中直接使用我们的 reduce 或者 add 方法了,就像下面这样:


getters 计算过滤操作

getters 从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。你可以把它看作 store.js 的计算属性。

getters 基本用法

比如我们现在要对 store.js 文件中的 count 进行一个计算属性的操作,就是在它输出前,给它加上 100 ,我们首先要在 store.js 里用 const 声明我们的 getters 属性。

const getters = {
  count: function(state) {
    return state.count += 100
  }
}

写好了 getters 之后,我们还需要在 Vuex.Store() 里引入,由于之前我们已经引入了 state 和 mutations ,所以引入里有三个引入属性。代码如下:

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

在 store.js 里的配置算是完成了,我们需要到模版页对 computed 进行配置。在 vue 的构造器里边只能有一个 computed 属性,如果你写多个,只有最后一个 computed 属性可用,所以要对上面写的 computed 属性进行一个改造。改造时我们使用 ES6 中的展开运算符 ...

computed: {
  ...mapState(["count"]),
  count() {
    return this.$store.getters.count
  }
}

需要注意的是,你写了这个配置后,在每次 count 的值发生变化的时候,都会进行加 100 的操作。

用 mapGetters 简化模版写法

我们都知道 state 和 mutations 都有 map 的引用方法把我们模版中的编码进行简化,我们的 getters 也是有的,我们来看一下代码:
首先用 import 引入我们的 mapGetters

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

在 computed 属性中添加 mapGetters

...mapGetters(["count"])

actions 异步修改状态

actions 和之前讲的 Mutations 功能基本一样,不同点是,actions 是异步的改变 state 状态,而 Mutations 是同步改变状态。至于什么是异步什么是同步这里我就不做太多解释了。

在 store.js 中声明 actions
actions 是可以调用 Mutations 里的方法的,我们还是继续上面的代码,在 actions 里调用 add 和 reduce 两个方法

const actions = {
  addAction(context) {
    context.commit('add', 10)
  },
  reduceAction({commit}) {
    commit('reduce')
  }
}

在 actions 里写了两个方法 addAction 和 reducedAction,在方法体里,我们都用 commit 调用了 Mutations 里边的方法。细心的小伙伴会发现这两个方法传递的参数不一样。

  • context:上下文对象,这里你可以理解成 store 本身
  • {commit } :直接把 commit 对象传递过来,可以让方法体逻辑和代码更清晰明了。

模版中的使用

我们需要在 count.vue 模板中编写代码,让 actions 生效。我们先复制两个以前有的按钮,并改成我们的 actions 里的方法名,分别是:addAction 和 reduceAction 。

改造一个我们的 methods 方法,首先还是用扩展运算符把 mapMutations 和 mapActions 加入。

methods: {
  ...mapMutations([
    'add','reduce'
  ]),
  ...mapActions(['addAction','reduceAction'])
}

你还要记得用 import 把我们的 mapActions 引入才可以使用。

增加异步检验

我们现在看的效果和我们用 Mutations 做的一模一样,肯定有小伙伴会好奇,那 actions 有什么用,我们为了演示 actions 的异步功能,我们增加一个计时器(setTimeout)延迟执行。在 addAction 里使用 setTimeout 进行延迟执行。

setTimeout(() => { context.commit(reduce)}, 3000)
console.log('我比reduce提前执行')

我们可以看到在控制台先打印出了 “我比 reduce 提前执行”这句话。

module 模块组

随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。那我们就再来看一下 module:状态管理器的模块组操作。

声明模块组:
在 vuex/store.js 中声明模块组,我们还是用我们的 const 常量的方法声明模块组。代码如下:

const moduleA = {
  state,mutations,getters,actions
}

声明好后,我们需要修改原来 Vuex.Store 里的值:

export default new Vuex.Store({
  modules: { a: moduleA }
})

在模块中使用
现在我们要在模板中使用 count 状态,要用插值的形式写入。

{{ $store.state.a.count }}

如果想用简单的方法引入,还是要在我们的计算属性中 return 我们的状态:

computed: {
  count() {
    return this.$store.state.a.count
  }
}

---------------------------(正文完)------------------------------------
一个 Vue 的学习交流群,想进来面基的,可以点击这个logo,或者手动search群号:685486827


写在最后: 约定优于配置-------软件开发的简约原则.
-------------------------------- (完)--------------------------------------

我的:
个人网站: https://neveryu.github.io/neveryu/
Github: https://github.com/Neveryu
新浪微博: https://weibo.com/Neveryu

更多学习资源请关注我的新浪微博…

原文地址:http://blog.csdn.net/h5_queenstyle12/article/details/75386359

你可能感兴趣的:(前端)