Vuex状态管理

Posted love the future

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuex状态管理相关的知识,希望对你有一定的参考价值。

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对象:

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

Vue.use(Vuex)

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

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

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

4.Vuex的核心概念

①State

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

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

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

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

在vuex中按需导入mapState函数:

import { mapState }  from 'vuex'

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

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
   
  }
}

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

②Mutation

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

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

注意的是:

  • 在mutations中定义的函数的第一个形参一般都是state
    后面的参数就是在调用该方法的时候需要传递的参数
    需要注意的是:在mutations定义的函数中,不能执行异步操作,也就是定时器,事件,Ajax,axios请求等
    同步函数就是按照顺序执行的函数,异步函数中存在着不同步的情况
export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  mutations: {
    add(state) {
      // 不要在 mutations 函数中,执行异步操作
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
 
})

触发mutation的两种方式:

① 方式一:

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

②方式二:

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

import { mapMutations } from 'vuex'

在methods中进行调用即可:

methods:{
 ...mapMutations(['sub', 'subN']),
}
<!--可以直接在click事件中写入相应的函数-->

<button @click="sub">-1</button>
    
<button @click="subN(3)">-N</button>


另外一种如下:

<template>
  <div>
    <h3>当前最新的count值为:{{count}}</h3>
    <h3>{{showNum}}</h3>
    <button @click="btnHandler1">-1</button>
    <button @click="btnHandler2">-N</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    btnHandler1() {
      this.sub()
    },
    btnHandler2() {
      this.subN(3)
    },
  }
}
</script>

 

③Action

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

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

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  mutations: {
    add(state) {
      // 不要在 mutations 函数中,执行异步操作
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 actions 中,不能直接修改 state 中的数据;
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    },
    subAsync(context) {
      setTimeout(() => {
        context.commit('sub')
      }, 1000)
    },
    subNAsync(context, step) {
      setTimeout(() => {
        context.commit('subN', step)
      }, 1000)
    }
  }
})

触发Action的两种方式:

 ①方式一:

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

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

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

import { mapActions } from 'vuex'

在methods中进行调用即可:

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

export default {
  data() {
    return {}
  },
  methods:{
      //获得mapMutations映射的sub函数
      ...mapMutations(['sub']),
      //当点击按钮时触发Sub函数
      Sub(){
          //调用sub函数完成对数据的操作
          this.sub(10);
      },
      //获得mapActions映射的addAsync函数
      ...mapActions(['subAsync']),
      asyncSub(){
          this.subAsync(5);
      }
  },
  computed:{
      ...mapState(['count'])
      
  }
}

④Getter

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

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  mutations: {
    add(state) {
      // 不要在 mutations 函数中,执行异步操作
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 actions 中,不能直接修改 state 中的数据;
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    },
    subAsync(context) {
      setTimeout(() => {
        context.commit('sub')
      }, 1000)
    },
    subNAsync(context, step) {
      setTimeout(() => {
        context.commit('subN', step)
      }, 1000)
    }
  },
  getters: {
    showNum(state) {
      return '当前最新的数量是【' + state.count + '】'
    }
  }
})

使用Getter的两种方式:

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

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

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

② 方式二:

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

映射为计算属性:

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

直接使用即可:

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

<template>
  <div>
    <!-- <h3>当前最新的count值为:{{count}}</h3> -->
    <h3>{{showNum}}</h3>
    <button @click="btnHandler1">-1</button>
    <button @click="subN(3)">-N</button>
    <button @click="subAsync">-1 Async</button>
    <button @click="subNAsync(5)">-N Async</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
    ...mapGetters(['showNum'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    ...mapActions(['subAsync', 'subNAsync']),
    btnHandler1() {
      this.sub()
    }
  }
}
</script>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于Vuex状态管理的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段13——Vue的状态大管家

手把手教你学vue-4(vuex)

vue状态管理(vuex)

vuex是什么,以及用vuex的好处,和单界面状态管理

一文让你看懂什么是vuex

详解vuex