vuex学习总结

153 阅读1分钟

1.什么是vuex

一个专为 Vue.js 应用程序开发的状态管理模式

1.1什么是状态管理模式

状态自管理应用包含

  • state:驱动应用数据源
  • view:以声明的方式将state映射到视图
  • actions:响应view因用户的操作发生的状态变化

image.png

1.2 vuex过程

image.png

2.核心概念

2.1 State

定义在全局共享的数据

 state: {
    // 所有的任务列表
    list: [],
    inputVal: 'aaa',
    Tmpid: 5,
    viewKey: 'all'
  }

2.2 Mutations

不能在此函数中执行异步操作

用于变更store中的数据,只能通过mutation变更store数据,不能直接操作store的数据 可以集中监控所有数据的变化

 mutations: {
    initList(state, list) {
      // state是固定参数 给state仓库里的List赋值
      state.list = list
    }
   }

2.3 Actions

在action中 不能直接修改state中的数据 必须通过context.commit()触发某个mutation函数才可以

actions: {
    getList(context) {
      axios.get('./list.json').then(({ data }) => {
        // console.log(data);
        // 调用mutation里的方法,传给他一个参数 是获取到的列表
        context.commit('initList', data)
      })
    }
  },

2.4 Getter

不会改变state里的数据,只是包装的作用

getters: {
 unDoneNum(state) {
      return state.list.filter(x => x.done === false).length
    }
   }

要有返回值 按需导入

import { mapGetters } from 'vuex'

在computed中 将getter中的函数名添加到如下数组中

computed: {
    ...mapGetters(['unDoneNum'])
  },

2.5 Modules

解决在一个单一树中,所有的状态集中,会产生一个很大的对象。

将 store 分割成模块(module)

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 的状态

3.应用

简单的计算案例 包含源码

3.1 main.js

import Vue from 'vue'
import App from './App.vue'
// 导入store中暴露的Store
import store from './store'

Vue.config.productionTip = false

new Vue({
  // 将store挂载到实例上,这样vue中的每一个组件都能访问store里的数据
  store,
  render: h => h(App)
}).$mount('#app')

3.2 app.vue

<template>
  <div>
    <my-addition></my-addition>
    <p>-------------</p>
    <my-subtraction></my-subtraction>
  </div>
</template>

<script>
import Addition from './components/Addition.vue'
import Subtraction from './components/Subtraction.vue'
export default {
  data() {
    return {
    }
  },
  components: {
    'my-addition': Addition,
    'my-subtraction': Subtraction
  }
}
</script>

<style>
</style>

3.3 store index.js

// 初始化vuex
import Vue from 'vue'
import Vuex from 'vuex'

// 注册到项目中
Vue.use(Vuex)

// 通过new创建一个Vuex.Store实例 并暴露出去
export default new Vuex.Store({
  state: {
    // 定义在全局共享的数据
    count: 2
  },
  mutations: {
    // 不能在此函数中执行异步操作
    // 用于变更store中的数据,只能通过mutation变更store数据,不能直接操作store的数据 可以集中监控所有数据的变化
    add(state) {
      // state表示全局中的数据对象,是固定写法
      /* setTimeout(() => {
        state.count++
      }, 2000); */
      state.count++
    },
    add1(state, step) {
      // step表示参数 一次加多少
      state.count += step
    },
    // 减法
    sub(state) {
      state.count--
    },
    sub1(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在action中 不能直接修改state中的数据 必须通过context.commit()触发某个mutation函数才可以
        context.commit('add')
      }, 2000);
    },
    // 异步带参数加法
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('add1', step)
      }, 2000);
    },

    subAsync(context) {
      setTimeout(() => {
       context.commit('sub')
      }, 2000);
    },
    // 异步带参数加法
    subNAsync(context, step) {
      setTimeout(() => {
        context.commit('sub1', step)
      }, 2000);
    }
  },
  modules: {
  },
  getters: {
    // 不会改变state里的数据,只是包装的作用
    show(state) {
      return '当前最新的数量是【' + state.count + '】'
    }
  }
})

3.4 add组件

<template>
  <!-- 在template中 this可以省略 -->
  <div>
    <!-- 组件访问数据第一种方法:$store.state.count -->
    <!-- 使用getter的方法一 -->
    <h2>{{$store.getters.show}}</h2>
    <h3>当前最新的count值为:{{$store.state.count}}</h3>
    <button @click="addbtn">+1</button>
    <button @click="addbtn1">+n</button>
    <button @click="addbtn2">+1 async</button>
    <button @click="addbtn3">+n async</button>

  </div>
</template>

<script>
export default {
  data() {
    return {}
  },
  methods: {
    addbtn() {
      // this.$store.state.count++
      // commit的作用就是调用mutation中的某个函数
      this.$store.commit('add')
    },
    addbtn1() {
      // commit 触发mutation 第一种方法 第二种在减法里
      this.$store.commit('add1', 2)
    },
    // 异步
    addbtn2() {
      // 专门触发action
      this.$store.dispatch('addAsync')
    },
    // 异步带参数加法
    addbtn3() {
      this.$store.dispatch('addNAsync', 5)
    }
  }
}
</script>

3.5 sub

<template>
  <div>
    <!-- 组件访问数据第二种方法: -->
    <!-- 第三部,直接使用 -->
    <h2>{{$store.getters.show}}</h2>
    <h3>当前最新的count值为:{{count}}</h3>
    <button @click="subbtn">-1</button>
    <button @click="subbtn1">-n</button>

    <button @click="subbtn2">-1 async</button>
    <button @click="subNAsync(5)">-n async</button>

  </div>
</template>

<script>
// 第一步:先导入 从vuex中按需导入mapState函数
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
  data() {
    return {}
  },
  // 第二步,通过导入mapState函数,将当前所需的全局数据,映射为组件的computed计算属性。即在计算属性里将使用的数据放入数组中
  computed: {
    ...mapState(['count']),
    ...mapGetters(['show'])
  },
  methods: {
    ...mapMutations(['sub', 'sub1']),
    ...mapActions(['subAsync', 'subNAsync']),
    subbtn() {
      // 调用
      this.sub()
    },
    subbtn1() {
      this.sub1(3)
    },
    subbtn2() {
      this.subAsync()
    }
  }
}
</script>