chencl1986/Blog

Vue教程20:Vuex入门

chencl1986 opened this issue · 0 comments

阅读更多系列文章请访问我的GitHub博客,示例代码请访问这里

该节教程代码可通过npm start运行devServer,在http://localhost:8080/查看效果

Vuex简介

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex具有以下特点:

  1. 全局
    Vuex类似于一个全局变量,它在整个Vue应用中生效。
  2. 统一
    只要状态修改,都会自动通知到所有相关组件,不需要使用者主动推送。
  3. 单一
    在全局中只需要保存一份,即可在全局中使用。

Vuex解决了哪些问题:

  1. 数据跨组件共享,数据的传输不再受到父子级限制,可以在各级组件中任意获取。
  2. 防止数据被意外篡改,Vuex会记录数据被修改的详细信息,如修改状态的组件、时间、代码位置等,便于定位和追踪错误,同时也方便了调试和测试。

Vuex的状态管理示意图详解

Vuex的使用

代码示例:/lesson20/src/main.js

先使用vue-cli创建一个项目,之后使用npm install vuex --save安装Vuex,就可以在/src/main.js中配置Vuex:

// 1. vuex-引入
import Vuex from 'vuex'

// vue-cli自带的编译配置
Vue.config.productionTip = false

// 1. vuex-在Vue中使用Vuex,让Vuex中的操作挂载到Vue中。
Vue.use(Vuex)

// 3. vuex-声明store对象
const store = new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production', // 严格模式:防止直接修改state,只能用Mutations操作,由于strict模式是通过对象深度匹配进行,生产模式打开会严重影响性能。
  state: {a: 12, b: 5}, // 核心:数据
  mutations: { // 定义Mutations
    
  },
  actions: { // 定义actions
    
  },
  getters: {}, // 类似于computed
  modules: {} // 将store拆分成多个命名空间,分开使用。
})

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store, // 将store挂载到Vue实例中。
  components: { App },
  template: '<App/>'
})

读取state的值

代码示例:/src/components/Index.vue

在Index.vue中可以通过$store.state.a读取到已定义的a的值。

<template>
  <div>
    <!-- 读取Vuex的state -->
    a: {{$store.state.a}}
    <Cmp1/>
    <Table :fields="fields" :datas="datas" :parent="this"/>
  </div>
</template>

修改state的值

接下来实现在Cmp1.vue组件中,点击按钮后修改state中的a的值。

代码示例:/src/components/Cmp1.vue

<template lang="html">
  <div class="">
    <input type="button" value="+5" @click="fn()">
  </div>
</template>

<script>
export default {
  name: 'cmp1',
  methods: {
    fn(){
      // this.$store.state.a+=5; // 在严格模式下,直接修改state可以成功,但会报错
      // this.$store.commit('add', 5);  // 直接触发一个Mutation其实也可行,且不会报错,但这其实违背了Vuex设计的初衷。
      this.$store.dispatch('add', 5);  // 触发一个action,实现数据修改。
    }
  }
}
</script>

<style lang="css" scoped>
</style>

在main.js中定义Actions和Mutations。

代码示例:/lesson20/src/main.js

const store = new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production', // 严格模式:防止直接修改state,只能用Mutations操作,由于strict模式是通过对象深度匹配进行,生产模式打开会严重影响性能。
  state: {a: 12, b: 5}, // 核心:数据
  mutations: { // 定义Mutations,通过action触发并更新state,Vue Devtool可以监听到数据的修改情况。
    add (state, n) { // 第一个参数为旧state,第二个参数为action中commit传入的参数。
      state.a += n
    }
  },
  actions: { // 定义actions,actions被触发后,将数据提交给Mutations进行处理并更新state。
    add ({ commit }, n) { // 第一个参数为context对象,它不是store本身,可以通过context.commit提交一个Mutation。第二个参数为用于更新state的参数。
      commit('add', n)
    }
  },
  getters: {}, // 类似于computed
  modules: {} // 将store拆分成多个命名空间,分开使用。
})