每周三集前端免费视频
每年帮助超100万前端爱好者学习

技术胖的vuex视频教程

前言:

公司项目中大量的使用了vue,感觉对vue知识的掌握也越来越熟练了,录制视频教程也让我受益匪浅,自己成长的同时,我更希望帮助其他前端小伙伴一起成长。这篇文章我们主要讲解vuex。

vuex是一个专门为vue.js设计的集中式状态管理架构。状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。比如:我们有几个页面要显示用户名称和用户等级,或者显示用户的地理位置。如果我们不把这些属性设置为状态,那每个页面遇到后,都会到服务器进行查找计算,返回后再显示。在中大型项目中会有很多共用的数据,所以尤大神给我们提供了vuex。

第1节:初出茅庐 来个小Demo

我们还是利用vue-cli 的webpack生成我们的项目结构,如果你对vue-cli的知识不了解,可以花二三十分钟去看一下这个视频教程:http://jspang.com/2017/04/10/vue-cli/  。项目目录生成后,引入我们的Vuex插件。

引入vuex

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

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

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

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

通过这三步的操作,vuex就算引用成功了,接下来我们就可以尽情的玩耍了。

入门小Demo(推荐视频观看):

我们这个小案例先声明一个state的count状态,在页面中使用显示这个count,然后可以利用按钮进行加减,如果你看过我的文章,你一定知道,在我们学基础知识 的时候经常编写这个程序。我们来张图片帮大家回忆一下。

就是这个程序,不过我们这次要用的是vuex来进行制作,并实现数据的共享。

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

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

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

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

这里的mutations是固定的写法,意思是改变的,我们到时候会用一节课专门讲这个mutations,所以你先不用着急,只知道我们要改变state的数值的方法,必须写在mutations里就可以了。

5.在count.vue模板中加入两个按钮,并调用mutations中的方法。

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


第2节:state访问状态对象

在第1节我们已经写了一个 const state ,这个就是我们说的访问状态对象,它就是我们SPA(单页应用程序)中的共享值。今天我们主要学习状态对象赋值给内部对象,也就是把stroe.js中的值,赋值给我们模板里data中的值。我们有三种赋值方式,我们一个一个来学习一下。

一、通过computed的计算属性直接赋值

computed属性可以在输出前,对data中的值进行改变,我们就利用这种特性把store.js中的state值赋值给我们模板中的data值。

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

二、通过mapState的对象来赋值

我们首先要用import引入mapState。

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

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

三、通过mapState的数组来赋值

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

这就是三种赋值方式,是不是很简单,虽然简单,但是在实际项目中经常使用,一定要自己动手练习两遍啊。


第3节:Mutations修改状态

上节课我们学习了怎么样读取state,那今天我们学习一下怎么样修改状态。这个常量我们在第一节课的时候也碰到过,并且进行了加减的操作。那这节课我们就具体学习一下,如何操作Mutations。

$store.commit( )

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

store.js文件:

传值:

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

现在store.js文件里给add方法加上一个参数n。添加的地方我已经标黄了。

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

这样两个简单的修改我们就完成了传值,我们可以在浏览器中实验一下了。

模板获取Mutations方法

实际开发中我们也不喜欢看到$store.commit( )这样的方法出现,我们希望跟调用模板里的方法一样调用。

例如:@click=”reduce”   就和没引用vuex插件一样。

要达到这种写法,只需要简单的两部就可以了:

  1. 在模板count.vue里用import 引入我们的mapMutations:

     
  2. 在模板的<script>标签里添加methods属性,并加入mapMutations

     

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

 


第4节:getters计算过滤操作

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

getters基本用法:

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

我们首先要在store.js里用const声明我们的getters属性。

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

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

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

用mapGetters简化模板写法:

我们都知道state和mutations都有map的引用方法把我们模板中的编码进行简化,我们的getters也是有的,我们来看一下代码。

首先用import引入我们的mapGetters

在computed属性中加入mapGetters

相信大家已经会了getters的用法,那我们下节课见了。


第5节:actions异步修改状态

actions和之前讲的Mutations功能基本一样,不同点是,actions是异步的改变state状态,而Mutations是同步改变状态。至于什么是异步什么是同步这里我就不做太多解释了,如果你不懂自己去百度查一下吧。(视频中有讲解)

在store.js中声明actions

actions是可以调用Mutations里的方法的,我们还是继续在上节课的代码基础上进行学习,在actions里调用add和reduce两个方法。

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

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

模板中的使用

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

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

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

增加异步检验

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

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

第6节:module模块组

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

声明模块组:

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

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

在模板中使用

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

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

 

 

未经允许不得转载:技术胖-胜洪宇关注web前端技术 » 技术胖的vuex视频教程
分享到: 更多 (0)

评论 85

  1. #53

    2
    setTimeOut(()=>{context.commit(reduce)},3000);
    console.log(‘我比reduce提前执行’); 应该是setTimeout

    匿名1个月前 (04-15)回复
  2. #52

    支持

    匿名2个月前 (04-03)回复
  3. #51

    https://github.com/angentle/vuex 按照视频写的案例 可供参考 commit记录按章节提交

    匿名2个月前 (03-26)回复
  4. #50

    棒棒哒

    匿名2个月前 (03-19)回复
  5. #49

    感谢胖哥

    匿名2个月前 (03-16)回复
  6. #48

    感谢~敬礼

    匿名2个月前 (03-12)回复
  7. #47

    感谢胖哥~

    匿名3个月前 (03-01)回复
  8. #46

    课件课件

    匿名3个月前 (02-27)回复
  9. #45

    {{$store.state.count}}
    我把这些加在.vue里页面显示不出来,连{{message}}的内容都没有了
    所有配置代码都已经按照您写的,
    想知道是什么原因

    匿名3个月前 (02-26)回复
  10. #44

    非常感谢 胖哥为国内前端发展做出的贡献,让小弟收益良多,谢谢您 🙂

    匿名3个月前 (02-17)回复
  11. #43

    我是去年7月多才开始从事前端工作的,一到公司就用vue,所有东西都是自己边做项目边摸索的,很多东西我用过但是似懂非懂的状态,虽然写了几个vue的项目,我感觉还是很茫然,好像还是啥都不懂,啥也不会。前不久才看到有这样的学习视频,一直一知半解的东西,在看着视频在从头到尾又重新了一遍之后,感觉获益良多,非常感谢胖哥,胖哥以后会讲讲nuxt吗

    匿名3个月前 (02-07)回复
    • 首先你能学到东西我非常高兴,Nuxt.js会讲的,我会更努力的出课,帮助更多的小伙伴学习。

      技术胖3个月前 (02-07)回复
  12. #42

    朋友们!大家好。我在使用npm run dev的时候,出现以下的错误
    This dependency was not found:
    * vuex/store in ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/components/add.vue
    To install it, you can run: npm install –save vuex/store

    匿名4个月前 (02-02)回复
    • 看下不是没有安装 vuex
      输入cnpm/npm i vuex –save 后再试试

      匿名3个月前 (02-28)回复
  13. #41

    – 这种写法,如果想一次减10,怎么写

    匿名4个月前 (01-30)回复
  14. #40

    computed: mapState([“count”])和methods: mapMutations([“add”, “reduce”]) 这是针对vuex的写法,如果页面里面还要写其他的方法,比如获取api,想写在methods里,应该怎么写

    匿名4个月前 (01-29)回复
    • methods:{
      …mapMutations([‘add’,’reduce’])
      }

      匿名4个月前 (01-30)回复
      • 666

        匿名2周前 (05-07)回复
  15. #39

    谢谢博主,但是这一块学完之后还是有点模糊,加上实践的demo没有vuex包含在内,不知道哪个给女神写的订餐系统能不能加上vuex实践0 0

    匿名4个月前 (01-26)回复
  16. #38

    胖哥vuex里面的mapMutations 在method里面调用 :mapMutations([‘add’])怎么给add方法传参数

    匿名4个月前 (01-23)回复
    • 减这样写了之后可以自动把10传递过去,在store.js中接收一下就可以了 reduce(state,x){
      state.count-=x
      }

      匿名4个月前 (01-30)回复
  17. #37

    非常感谢宇哥儿, 最近跟着把Vue的基础部分(Vue四季 + Webpack + Vue Cli + Vue Router + VueX), 听课的同时代码跟着敲了一遍, 受益匪浅, 接下来会继续学习更多Vue实战视频, 已经扫码打赏30元, 聊表谢意 🙂

    匿名4个月前 (01-07)回复
  18. #36

    methods:mapMutations([
    ‘add’,’reduce’
    ]),这样写的话 methods里面的其他方法怎么写

    匿名4个月前 (01-07)回复
  19. #35

    胖哥,第一节这一段引用你没有讲,
    然后我们需要在main.js导入这段内容。

    import store from ‘./store/store’
    再然后我们vue实例中添加store属性,即可在全局的所有子组件中使用这个了。

    new Vue({
    el: ‘#app’,
    store,
    router,
    template: ”,
    components: { App }
    })
    一直报$store undefined 害的我调了好几天,还以为我vuex没安装好

    匿名5个月前 (01-04)回复
  20. #34

    是多少

    匿名5个月前 (12-22)回复
  21. #33

    宇哥:根据你的讲解,我把下面的代码写在Mutations中,
    add2(state, n) {
    setTimeout(() => {
    state.count += 9
    }, 5000);
    console.log(‘我等上面的先执行’);
    state.count += n;
    },
    我的理解是console.log(‘我等上面的先执行’);state.count += n;部分代码应等setTimeout(() => {state.count += 9}, 5000);执行了才执行,但实际是console.log(‘我等上面的先执行’);state.count += n;会先执行,不知道是不是我的理解不对。

    匿名5个月前 (12-20)回复
    • setTimeout是执行了,但是它的回调函数还没有执行。所以是console.log state.count+=n 先执行,才到回调函数执行。

      匿名4个月前 (01-09)回复
  22. #32

    胖哥,第一节第二部分 少贴了一句代码
    export default new Vuex.Store({
    state,
    mutations
    })

    匿名5个月前 (12-18)回复
  23. #31

    第一二节课里面 unknown mutation type: add 加减法一直报错这种错

    匿名5个月前 (12-16)回复
    • store.js里面代码执行顺序不要写错了,
      export default new Vuex.Store({
      state,
      mutations
      })

      写到最后面。不然会一直报 unknown mutation type: add 这种错。

      匿名5个月前 (12-29)回复
  24. #30

    npm run dev 错误
    * ansi-html in ./node_modules/_webpack-dev-server@2.9.7@webpack-dev-server/client/overlay.js
    * loglevel in ./node_modules/_webpack-dev-server@2.9.7@webpack-dev-server/client?http://localhost:8080
    * sockjs-client/dist/sockjs in ./node_modules/_webpack-dev-server@2.9.7@webpack-dev-server/client/socket.js
    求大神

    匿名5个月前 (12-14)回复
  25. #29

    methods:mapMutations([
    ‘add’,’reduce’
    ]),这样写的话 methods里面的其他方法怎么写

    匿名5个月前 (12-08)回复
    • 用扩展运算符。

      匿名4个月前 (01-09)回复
    • methods:{ …mapMutations([
      ‘add’,’reduce’
      ]),
      }

      匿名4个月前 (01-25)回复
  26. #28

    胖哥 能不能将个vuex案例,感觉这个虽然简单 ,但是不会系统的在项目中什么时候用,怎么用

    匿名5个月前 (12-08)回复
  27. #27

    这个vuex 用法都看不懂

    匿名6个月前 (12-02)回复
  28. #26

    好模糊啊,看不清。 而且chrome不能放大呀

    匿名6个月前 (11-29)回复
    • 是的,由于视频流量费用非常高昂,所以托管到腾讯视频上了。你可以去点击进腾讯视频看高清版。

      技术胖6个月前 (11-29)回复
  29. #25

    getters基本用法:
    已经引入了state盒mutations (错别字)

    zz7个月前 (10-17)回复
  30. #24

    胖哥,什么时候应该用扩展运算符,什么时候不用,搞不清楚情况

    路人甲8个月前 (10-06)回复
  31. #23

    谢谢博主 在博主的详细讲解下 我理解的很透彻

    男二号8个月前 (09-20)回复
  32. #22

    博主您好,有空的话能不能录制一下讲解vuex官网购物车实例的视频,看了你录制的所有关于vuex视频之后,自己也动手编码了一遍,但去看购物车那个实例代码还是不懂,很多代码不知道为什么要这么写?这么写有什么作用?

    yuqingyun8个月前 (09-09)回复
  33. #21

    博主您好,看了你的教程,学到很多,太谢谢了,官方有个pi示例代码,很多人推荐看,不是很明白,用了如服务器端渲染等好多技术,能不能给我们讲讲呢,自己看难度较大:https://github.com/vuejs/vue-hackernews-2.0口

    aa10个月前 (08-07)回复
  34. #20

    你好,你说到异步同步时说道mutation是同步action是异步。我把你测试代码settimeout代码放置到mutation时,也是先console.log出来结果,然后在改变的state,请问这是什么问题,我并没办法从settimeout这个测试就能看出mutation,action同步异步与否

    vinci10个月前 (07-28)回复
    • 是的,这算是讲课的一个小失误,setTimeout并不能看出异步。谢谢你的指出。

      技术胖10个月前 (07-29)回复
  35. #19

    第一个视频中$store是怎么来的?不是引入的是store? 并且在{{}} 中写store.state.count无限报错?

    akira10个月前 (07-24)回复
  36. #18

    胖哥你好 我想要页面跳转到一个全新的页面 该怎么设置路由(新的页面完全没有上个页面的内容)

    zheng10个月前 (07-16)回复
    • Vue适合的是单页面应用,你说是多页面吧,但多页面就没办法共享状态了。你可以去查一下vue多页面制作,可以得到你想要的结果。

      技术胖10个月前 (07-16)回复
  37. #17

    第一节按照你的写法,怎么报错
    ERROR Failed to compile with 1 errors 10:35:11

    This dependency was not found:

    * @/vuex/store in ./~/babel-loader/lib!./~/vue-loader/lib/selector.js?type=scrip
    t&index=0!./src/components/Count.vue

    To install it, you can run: npm install –save @/vuex/store

    rainbox11个月前 (06-21)回复
    • 这个应该是你没有安装vuex吧

      自由自在10个月前 (07-13)回复
  38. #16

    你好,请问大神,为什么我的项目,通过cnpm install vuex –dev 安装了vuex,paxkage里依赖也有vuex,但是在组件里有vuex,打包仍然报错找不到这个依赖

    11个月前 (06-20)回复
  39. #15

    您好在看您的代码时候发现在第五小节最后代码出现错误:
    增加异步检验
    setTimeOut(()=>{context.commit(reduce)},3000);==>setTimeout(()=>{context.commit(‘reduce’)},3000);

    zhoushaobo11个月前 (06-12)回复
  40. #14

    拿setTimeout来测试异步也真是没谁了,哈哈,不过没关系,还是挺牛的,一天让我搞懂了一星期都没搞懂的vuex。希望下次能出个axios的教程,听你讲学的快哈

    Gavin11个月前 (06-10)回复
    • 谢谢指出文章中的错误,视频教程的目的就是要比自己看书快3-10倍,我努力做到3倍,目标是让大家10倍学习。希望加入Q群一起学习进步啊。

      技术胖11个月前 (06-11)回复
  41. #13

    证明actions的是异步的例子我感觉不妥,真真异步的是setTimeout,感觉不到actions的异步

    roc.lee12个月前 (06-05)回复
    • 感谢你提出的问题,我会慎重对待,如果可能,我会重新录制视频。

      技术胖12个月前 (06-05)回复
    • 异步这块可以这么写:
      先手工实现一个sleep函数
      function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms))
      }
      然后把reduce改一下
      async reduce(state) {
      await sleep(3000);
      state.count–;
      }
      对应的action这可以不用改
      reduceAction({commit}) {
      commit(‘reduce’);
      console.log(‘我比reduce函数先执行’);
      }

      sjq59711个月前 (06-25)回复
      • 受教受教,谢谢指正。

        技术胖11个月前 (06-25)回复
        • 胖哥,刚刚看了官方的文档,mutation和actions都只是vuex提供的方法,只是官方规定mutation方法内不能进行异步操作,而actions方法可以进行异步操作。这应该vuex设计的问题。

          匿名3个月前 (02-05)回复
  42. #12

    受益匪浅,感谢博主分享!

    筱陌1年前 (2017-05-25)回复
  43. #11

    感觉还是一头雾水,越来越复杂了

    lyskey1年前 (2017-05-16)回复
  44. #10

    使用webpack-simple模板时,如何解决扩展运算符的错误,就是…mapState([‘count’]) 这步报错 babelrc如何配置和需要什么插件呢,我尝试了两种方法都出错了,谢谢胖哥

    pguHxb1年前 (2017-05-16)回复
  45. #9

    Resource HTTP 那些还讲吗 还是比较期待有个具体的小案例能结合前面所学的知识的

    Coding Man1年前 (2017-05-10)回复
  46. #8

    谢谢胖哥谢谢胖哥

    vincent1年前 (2017-05-09)回复
  47. #7

    谢谢胖神

    marven1年前 (2017-05-09)回复
  48. #6

    methods:mapMutations([
    ‘add’,’reduce’
    ]),
    调用的时候add方法里+=n 的参数n怎么传递呢!

    海博1年前 (2017-05-08)回复
    • 这种形式不能传递参数,如果要传递参数不能简写。

      技术胖1年前 (2017-05-08)回复
      • 这个传入的参数一般是以对象的形式传入的吧

        jungege1年前 (2017-05-08)回复
      • 简写可以传参+
        methods:mapMutations([‘reduce’, ‘add’])

        wesley.W10个月前 (07-27)回复
      • 我今天试了+可以成功呀

        匿名3个月前 (02-07)回复
  49. #5

    宇哥 后续可以出一个Vue.js axios的讲解的吗?

    小钟1年前 (2017-05-08)回复
    • 有需要就出吧,不过axios没什么可讲的,出个短的也行。

      技术胖1年前 (2017-05-08)回复
  50. #4

    讲解的很透彻,赞(•̀ᴗ•́)و ̑̑

    webhj1年前 (2017-05-07)回复
    • 谢谢你的支持,我会继续努力的。

      技术胖1年前 (2017-05-07)回复
  51. #3

    厉害了胖哥!更新的这么快,加油!!

    prach1年前 (2017-05-05)回复
    • 嗯,有你们的支持,我会加油的。

      技术胖1年前 (2017-05-05)回复
      • jspang你好,vuex视频中这个$store.state.count 用来插值的“$store” 是怎么来的固定写这个嘛,还是可以可以其他的名字

        Lee12个月前 (05-26)回复
  52. #2

    爱你

    小蜜蜂1年前 (2017-05-05)回复
    • 我都不好意思了。希望你能加群,里边有很多vue高手,我们也可以继续发展。哈哈。

      技术胖1年前 (2017-05-05)回复
  53. #1

    及时雨啊,胖哥!

    adam1年前 (2017-05-04)回复
    • 呵呵,共同进步。

      技术胖1年前 (2017-05-04)回复
      • …mapState([‘count’,’count1′]) 这样的写法为什么一定要导入 import store from ‘../vuex/store’,我看别人写的直接导入一个import { mapState } from ‘vuex’就行了,但是这样写说state是undefined

        jungege1年前 (2017-05-05)回复
        • 直接导入的是已经在main.js页面导入过了,我在main.js页面没有导入,所以需要在用到的页面进行导入。希望可以帮到你。

          技术胖1年前 (2017-05-05)回复
          • 是这样的,谢谢胖哥啊,我们都爱你哟

            jungege1年前 (2017-05-08)