vuex知识点总结

165 阅读2分钟

vuex简介

vuex是一个vue自带的状态管理工具,可以实现对数据的储存和管理,方便在项目中各个组建中进行应用

1 起步

1.1 项目中安装vuex:

执行:npm install vuex --save

1.2 创建store文件夹生成index.js文件用于创建vuex实例

1.3 在index中执行如下代码创建vuex实例

APP.vue
// 引入vue模块
import Vue from 'vue'
// 引入vuex模块
import Vuex from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
  state: {
   user: 'admin',
    count: "100"
  },
  mutations: {
   increment(state, payload) {
      state.count += payload
    },
    decrement(state) {
      state.count -= 10
    }
  },
  actions: {
  },
  modules: {
  }
})

1.4 将创建好vue实例的index.js引入到main.js,并且在vue实例中注册store

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')
 
现在就可以在全局中使用 vuex

2 创建和使用store里面的数据(存放和修改)

2.1 在store里存放数据和在其他组件中使用数据(state)

在home.vue里面使用
template>
  <div class="home">
    <h1>我是首页</h1>
    <button @click="demo">点击显示des</button>
    <button @click="demo1">点击显示dadcount</button>
    <h1>
      <!-- 方式一: -->
      显示store里信息1 :{{ $store.state.user }}
      点击显示des :{{ des }}

    </h1>
    <h1>
      <!-- 方式二:辅助函数 -->
      显示store里信息2 :{{ user }}
    </h1>
    <h1>
      <!-- 方式二:辅助函数 -->
      显示store里信息3 :{{ count }}
      点击显示dadcount :{{ dadcount }}
    </h1>
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  computed: {
    ...mapState(['user', 'count'])
  },
  data() {
    return {
      des: '',
      dadcount: ''
    }
  },
  methods: {
    demo() {
      this.des = this.$store.state.user
    },
    demo1() {
      this.dadcount = this.count
    }
  }
}
</script>

总结 :储存和获取数据
方式一:通过this.$store.state.数据
方式二 : mapState辅助函数获取属性步骤如下:
       (1import { mapState } from "vuex";  
       (2) computed中通过  ...mapState(['数据1', '数据2'])引入
       (3) {{ 数据1 }}

2.2 在store里存放数据和修改state数据(Mutations)

template>
  <div>
  // 方式一 :通过commit路径去触发store里Mutations里的方法
    <h1>我是关于页</h1>
    <button @click="add">+</button>
    <button @click="dec">-</button>
    {{ count }}
  // 方式二 :引入辅助函数mapMutations
    <button @click="add2">辅助函数+</button>
    <button @click="dec2">辅助函数-</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from "vuex";
export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations(['increment', 'decrement']),
    add() {
      this.$store.commit('increment', 5)
    },
    dec() {
      this.$store.commit('decrement')
    },
    add2() {
      this.increment(5)
    },
    dec2() {
      this.decrement()
    },
  }
}
</script>
总结 :修改state数据
唯一方式 :只要是储存在state数据必须通过 mutations里的方法修改,这是必须的
但是在其他组件中使用的 mutations方法的时候有两种方法。
方法一:直接 this.$store.commit("increment")即通过commit路径
方法二 :使用mapMutations辅助函数
 Mutation 需遵守 Vue 的响应规则
    a:最好提前在你的 store 中初始化好所有所需属性。
    b:当需要在对象上添加新属性时,你应该使用 Vue.set(obj, 'newProp', 123), 或者以新对象替换老对象
    注意:在Vue中,对象属性的增加或减少,必须通过Vue.set去改变!!!
使用常量替代 Mutation 事件类型 Mutation 必须是同步函数

2.3 vuex里的异步处理(actions)


actions: {
    //actions不仅可以做异步操作,也可以做同步操作
    actionsincrement(context, payload) {
      context.commit('increment', payload)
    },
    actionsDecrement(context) {
      context.commit('decrement')
    }
  },
<template>
  <div>
    <h1>我是关于页</h1>
    <h1>直接修改</h1>
    <button @click="add">+</button>
    <button @click="dec">-</button>
    {{ count }}
    <h1>Mutation修改</h1>
    <button @click="add2">辅助函数+</button>
    <button @click="dec2">辅助函数-</button>
    <h1>actions修改</h1>
    <button @click="add3">actions直接修改+</button>
    <button @click="dec3">actions辅助函数-</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations(['increment', 'decrement']),
    ...mapActions(['actionsDecrement']),
    add() {
      this.$store.commit('increment', 5)
    },
    dec() {
      this.$store.commit('decrement')
    },
    add2() {
      this.increment(5)
    },
    dec2() {
      this.decrement()
    },
    add3() {
      this.$store.dispatch('actionsincrement', 8)
    },
    dec3() {
      this.actionsDecrement()
    },
  }
}
</script>
总结:actions里面可以做异步操作也可以同步
但是在改变state里面的值得时候还是通过mutation来修改的通过context里面的commit先进入mutation,再修改数据

2.3 vuex数据在加工(actions)

 getters: {
    userName: state => {
      return state.user + '--vip用户'
    }
  },
<template>
  <div>
    <h1>我是关于页</h1>
    <h1>直接修改</h1>
    <button @click="add">+</button>
    <button @click="dec">-</button>
    {{ count }}
    <h1>Mutation修改</h1>
    <button @click="add2">辅助函数+</button>
    <button @click="dec2">辅助函数-</button>
    <h1>actions修改</h1>
    <button @click="add3">actions直接修改+</button>
    <button @click="dec3">actions辅助函数-</button>
    <h1>getters操作</h1>
    {{ $store.getters.userName }}
    {{ userName }}
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['userName'])
  },
  methods: {
    ...mapMutations(['increment', 'decrement']),
    ...mapActions(['actionsDecrement']),
    add() {
      this.$store.commit('increment', 5)
    },
    dec() {
      this.$store.commit('decrement')
    },
    add2() {
      this.increment(5)
    },
    dec2() {
      this.decrement()
    },
    add3() {
      this.$store.dispatch('actionsincrement', 8)
    },
    dec3() {
      this.actionsDecrement()
    },
  }
}
</script>
总结:有时候我们需要从 store 中的 state 中派生出一些状态,或者对state里面的数据过滤在加工,可以使用getters,其实相当于vuex里面的一个计算属性

3 vuex的模块化

modules: {
    cityMoudle: {
      namespaced: true,
      state: {
        city: '上海'
      }
    },
    loginMoudle: {
      namespaced: true,
      state: {
        name: 'zhangsan'
      },
      mutations: {
        changeName(state, payload) {
          state.name = payload
        }
      }
    }
  }
<template>
    <div>
        <button @click="btnclick">点击打印</button>
        <h1>城市模块化使用</h1>
        <!-- 直接使用 -->
        <p>直接使用当前城市:{{ $store.state.cityMoudle.city }}</p>
        <!-- 辅助函数使用 -->
        <p>辅助函数使用当前城市:{{ city }}</p>
        <hr>
        <h1>登录模块化使用</h1>
        <!-- 直接使用 -->
        <p>直接使用当前登录用户名:{{ $store.state.loginMoudle.name }}</p>
        <!-- 辅助函数使用 -->
        <p>辅助函数使用当前登录用户名:{{ $store.state.loginMoudle.name }}</p>
    </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
    computed: {
        ...mapState('cityMoudle', ['city']),
        ...mapState('loginMoudle', ['name'])
    },
    methods: {
        btnclick() {
            console.log(this);
        },

    }
}
</script>
总结 :由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
1. 命名空间
2. 模块的局部状态
3. 快捷读取方案
读取和改变模式都和根组件一样,只不过要加上具体的模块名

最后各个模块和根模块之间的数据传输可以看官网有详细教程