飞道的博客

Vuex状态管理

297人阅读  评论(0)

1.项目的创建

 

需要安装node.js和vuecli3

相关路径:

https://blog.csdn.net/weixin_43328816/article/details/116497631

 

使用ui界面的方式创建新的文件:

 

使用Vue脚手架新建项目的时候,可以直接使用命令行的方式,也可以使用图形界面的方式。

在命令行输入:vue ui就可以自动跳转到相应的页面:

可以在这个页面中创建自己的项目:

点击下一步,在点击创建项目即可。

可以在上面添加相应的插件和依赖,还可以启动相应的项目。

 

使用命令行方式进行项目创建

 

Vuecli3:使用的是vue create vuetest2

接下来的选择N即可。

就可以成功创建一个项目。

创建完成之后就可以进入目录:cd vuetest2

启动项目:npm run serve

打开项目:配置npm run serve

 

启动的时候点击旁边的按钮即可:

 

 

2.Vuex的介绍

在Vue中组件之间共享数据的方式:

Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。

使用Vuex统一状态管理的好处:

什么样的数据适合存储到Vuex中:

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

3.Vuex的基本使用

在VueCli项目中安装vuex:npm install vuex --save

在store/index.js中导入vuex的包:

创建store对象:


  
  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export default new Vuex.Store({
  5. state: {
  6. },
  7. mutations: {
  8. },
  9. actions: {
  10. },
  11. modules: {
  12. }
  13. })

将store对象挂载到Vue实例中:main.js


  
  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import router from './router'
  4. import store from './store'
  5. Vue.config.productionTip = false
  6. new Vue({
  7. router,
  8. store,
  9. render: h => h(App)
  10. }).$mount( '#app')

4.Vuex的核心概念

①State

State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State进行存储。


  
  1. const store = new Vuex.Store({
  2. state:{ count: 0 }
  3. })

组件访问State中数据的两种方式:

  1. 方式一:this.$store.state.全局变量的名称 例如:this.$store.state.count
  2. 方式二:

在vuex中按需导入mapState函数:

import { mapState }  from 'vuex'

 然后数据映射为计算属性: computed:{ ...mapState(['全局数据名称']) }


  
  1. export default {
  2. data() {
  3. return {}
  4. },
  5. computed: {
  6. ...mapState([ 'count']),
  7. }
  8. }

 就可以直接使用count或者是this.count,不需要this.$store.state.count

②Mutation

Mutation用于修改变更$store中的数据State,不可以直接操作State中的数据

这种方法可以几种监控所有数据的变化

注意的是:

  • 
        
    1. 在mutations中定义的函数的第一个形参一般都是state
    2. 后面的参数就是在调用该方法的时候需要传递的参数
    3. 需要注意的是:在mutations定义的函数中,不能执行异步操作,也就是定时器,事件,Ajax,axios请求等
    4. 同步函数就是按照顺序执行的函数,异步函数中存在着不同步的情况

  
  1. export default new Vuex.Store({
  2. state: {
  3. count: 0
  4. },
  5. // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  6. mutations: {
  7. add(state) {
  8. // 不要在 mutations 函数中,执行异步操作
  9. // setTimeout(() => {
  10. // state.count++
  11. // }, 1000)
  12. state.count++
  13. },
  14. addN(state, step) {
  15. state.count += step
  16. },
  17. sub(state) {
  18. state.count--
  19. },
  20. subN(state, step) {
  21. state.count -= step
  22. }
  23. },
  24. })

触发mutation的两种方式:

① 方式一:

  •  mutation中的方法没有参数的时候,在需要用到mutation中方法的组件中使用 this.$store.commit('add')
  •  mutation中的方法有参数的时候,在需要用到mutation中方法的组件中使用 this.$store.commit('add',3).直接在后面写上需要传入的参数。

②方式二:

在需要触发mutation的组件中引入 mapMutations

import { mapMutations } from 'vuex'

在methods中进行调用即可:


  
  1. methods:{
  2.  ...mapMutations([ 'sub', 'subN']),
  3. }

  
  1. <!--可以直接在click事件中写入相应的函数-->
  2. <button @click="sub">-1</button>
  3. <button @click="subN(3)">-N</button>


另外一种如下:


  
  1. <template>
  2. <div>
  3. <h3>当前最新的count值为:{{count}} </h3>
  4. <h3>{{showNum}} </h3>
  5. <button @click="btnHandler1">-1 </button>
  6. <button @click="btnHandler2">-N </button>
  7. </div>
  8. </template>
  9. <script>
  10. import { mapState, mapMutations } from 'vuex'
  11. export default {
  12. data() {
  13. return {}
  14. },
  15. computed: {
  16. ...mapState([ 'count']),
  17. },
  18. methods: {
  19. ...mapMutations([ 'sub', 'subN']),
  20. btnHandler1() {
  21. this.sub()
  22. },
  23. btnHandler2() {
  24. this.subN( 3)
  25. },
  26. }
  27. }
  28. </script>

 

③Action

在mutations中不能编写异步的代码,会导致vue调试器的显示出错。
在vuex中我们可以使用Action来执行异步操作。

但是在Action中还是要通过触发Mutation的方式间接变更数据。


  
  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export default new Vuex.Store({
  5. state: {
  6. count: 0
  7. },
  8. // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  9. mutations: {
  10. add(state) {
  11. // 不要在 mutations 函数中,执行异步操作
  12. // setTimeout(() => {
  13. // state.count++
  14. // }, 1000)
  15. state.count++
  16. },
  17. addN(state, step) {
  18. state.count += step
  19. },
  20. sub(state) {
  21. state.count--
  22. },
  23. subN(state, step) {
  24. state.count -= step
  25. }
  26. },
  27. actions: {
  28. addAsync(context) {
  29. setTimeout( () => {
  30. // 在 actions 中,不能直接修改 state 中的数据;
  31. // 必须通过 context.commit() 触发某个 mutation 才行
  32. context.commit( 'add')
  33. }, 1000)
  34. },
  35. addNAsync(context, step) {
  36. setTimeout( () => {
  37. context.commit( 'addN', step)
  38. }, 1000)
  39. },
  40. subAsync(context) {
  41. setTimeout( () => {
  42. context.commit( 'sub')
  43. }, 1000)
  44. },
  45. subNAsync(context, step) {
  46. setTimeout( () => {
  47. context.commit( 'subN', step)
  48. }, 1000)
  49. }
  50. }
  51. })

触发Action的两种方式:

 ①方式一:

  •  actions中的方法没有参数的时候,在需要用到mutation中方法的组件中使用 this.$store.dispatch('addAsync')
  •  actions中的方法有参数的时候,在需要用到mutation中方法的组件中使用 this.$store.dispatch('add',3).直接在后面写上需要传入的参数。

②方式二:与上面的Mutation中的触发方式类似

在需要触发Action的组件中引入 mapActions

import { mapActions } from 'vuex'

在methods中进行调用即可:


  
  1. import { mapState,mapMutations,mapActions } from 'vuex'
  2. export default {
  3. data() {
  4. return {}
  5. },
  6. methods:{
  7. //获得mapMutations映射的sub函数
  8. ...mapMutations([ 'sub']),
  9. //当点击按钮时触发Sub函数
  10. Sub(){
  11. //调用sub函数完成对数据的操作
  12. this.sub( 10);
  13. },
  14. //获得mapActions映射的addAsync函数
  15. ...mapActions([ 'subAsync']),
  16. asyncSub(){
  17. this.subAsync( 5);
  18. }
  19. },
  20. computed:{
  21. ...mapState([ 'count'])
  22. }
  23. }

④Getter

Getter用于对Store中的数据进行加工处理形成新的数据,类似于Vue的计算属性。
它只会包装Store中保存的数据,并不会修改Store中保存的数据,当Store中的数据发生变化时,Getter生成的内容也会随之变化


  
  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export default new Vuex.Store({
  5. state: {
  6. count: 0
  7. },
  8. // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  9. mutations: {
  10. add(state) {
  11. // 不要在 mutations 函数中,执行异步操作
  12. // setTimeout(() => {
  13. // state.count++
  14. // }, 1000)
  15. state.count++
  16. },
  17. addN(state, step) {
  18. state.count += step
  19. },
  20. sub(state) {
  21. state.count--
  22. },
  23. subN(state, step) {
  24. state.count -= step
  25. }
  26. },
  27. actions: {
  28. addAsync(context) {
  29. setTimeout( () => {
  30. // 在 actions 中,不能直接修改 state 中的数据;
  31. // 必须通过 context.commit() 触发某个 mutation 才行
  32. context.commit( 'add')
  33. }, 1000)
  34. },
  35. addNAsync(context, step) {
  36. setTimeout( () => {
  37. context.commit( 'addN', step)
  38. }, 1000)
  39. },
  40. subAsync(context) {
  41. setTimeout( () => {
  42. context.commit( 'sub')
  43. }, 1000)
  44. },
  45. subNAsync(context, step) {
  46. setTimeout( () => {
  47. context.commit( 'subN', step)
  48. }, 1000)
  49. }
  50. },
  51. getters: {
  52. showNum(state) {
  53. return '当前最新的数量是【' + state.count + '】'
  54. }
  55. }
  56. })

使用Getter的两种方式:

①方式一:this.$store.getters.showNum

可以直接在组件中进行使用:


  
  1. <template>
  2. <div>
  3. <!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
  4. <h3>{{$store.getters.showNum}} </h3>
  5. <button @click="btnHandler1">+1 </button>
  6. <button @click="btnHandler2">+N </button>
  7. <button @click="btnHandler3">+1 Async </button>
  8. <button @click="btnHandler4">+N Async </button>
  9. </div>
  10. </template>

② 方式二:

在组件中引入import {mapGetter} from 'vuex'

映射为计算属性:

  computed: {
    ...mapState(['count']),
    ...mapGetters(['showNum'])
  },

直接使用即可:

 <h3>{ {showNum}}</h3>


  
  1. <template>
  2. <div>
  3. <!-- <h3>当前最新的count值为:{{count}}</h3> -->
  4. <h3>{{showNum}} </h3>
  5. <button @click="btnHandler1">-1 </button>
  6. <button @click="subN(3)">-N </button>
  7. <button @click="subAsync">-1 Async </button>
  8. <button @click="subNAsync(5)">-N Async </button>
  9. </div>
  10. </template>
  11. <script>
  12. import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
  13. export default {
  14. data() {
  15. return {}
  16. },
  17. computed: {
  18. ...mapState([ 'count']),
  19. ...mapGetters([ 'showNum'])
  20. },
  21. methods: {
  22. ...mapMutations([ 'sub', 'subN']),
  23. ...mapActions([ 'subAsync', 'subNAsync']),
  24. btnHandler1() {
  25. this.sub()
  26. }
  27. }
  28. }
  29. </script>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


转载:https://blog.csdn.net/weixin_43328816/article/details/116485010
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场