Vuex

Vuex 状态管理

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

Vuex 主要解决的问题

  • 多个视图依赖同一个状态
  • 来自不同视图的行为需要变更同一个状态

使用 Vuex 的好处

  • 能够在 vuex 中集中管理共享的数据,易于开发和后期维护
  • 能够高效地实现组件之间的数据共享,提高开发效率
  • 在 vuex 中的数据都是响应式的

Vuex 基础使用

  • 安装 vuex 依赖包
    • npm install vuex --save
  • 导入 vuex 包
    • import Vuex from 'vuex'
    • Vue.use(Vuex)

  • 创建 store 对象
    • const store = new Vuex.Store({
      // state 中存放的就是全局共享的数据 state: { count: 0 }
      })

  • 将 store 对象挂载到 vue 实例中

store/index.js文件(外部import./store时会自动访问此目录下的index.js文件):

/* src/store/index.js */

// 导入 Vue
import Vue from 'vue'
// 导入 Vuex 插件
import Vuex from 'vuex'

// 把 Vuex 注册到Vue 上
Vue.use(Vuex)

export default new Vuex.Store({
  // 在开发环境开启严格模式 这样修改数据 就必须通过 mutation 来处理
  strict:products.env.NODE_ENV !== 'production',
  // 状态
  state: {
  },
  // 用来处理状态
  mutations: {
  },
  // 用于异步处理
  actions: {
  },
  // 用来挂载模块
  modules: {
  }
})

要使用 store 就在把 store 挂载到 Vue 中
把 store 挂载到 Vue 之后 ,所有的组件就可以直接从 store 中获取全局数据

import Vue from 'vue'
import App from './App.vue'
import store from './store'//默认访问此文件中的index.js文件


Vue.config.productionTip = false

new Vue({
  // 挂载到vue 中
  store,
  render: (h) => h(App),
}).$mount('#app')

Vuex的5大属性

1.state

在 state 中添加数据

我们需要共享的状态都放在写在 state 对象里面

/* src/store/index.js */

// 导入 Vue
import Vue from 'vue'
// 导入 Vuex 插件
import Vuex from 'vuex'

// 把 Vuex 注册到Vue 上
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    name: '张三',
    age: 21,
  },
  mutations: {},
  actions: {},
  modules: {},
})

获取到 state 有两种方式

1.直接使用 this.$store.state[属性] ,(this 可以省略)

2.使用 mapState

通过 mapState把 store 映射到 组件的计算属性,就相当于组件内部有了 state 里的属性

//法1:
<template>
  <div id="app">
    {{ this.$store.state.name }}
    {{ this.$store.state.age }}
  </div>
</template>

//法2
<template>
  <div id="app">
    {{ name }}
    {{ age }}
  </div>
</template>

<script>

// 从 Vuex 中导入 mapState
import { mapState } from 'vuex'
export default {
  name: 'App',
  computed: {
    // 将 store 映射到当前组件的计算属性
    ...mapState(['name', 'age'])
  }
}
</script>

<style  scoped>
</style>


2.Mutation

Store 中的状态不能直接对其进行操作,我们得使用 Mutation 来对 Store 中的状态进行修改,虽然看起来有些繁琐,但是方便集中监控数据的变化

如果想要定义的方法能够修改 Store 中的状态,需要参数就是 state

state 的更新必须是 Mutation 来处理

/* src/store/index.js */

// 导入 Vue
import Vue from 'vue'
// 导入 Vuex 插件
import Vuex from 'vuex'

// 把 Vuex 注册到Vue 上
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    name: '张三',
    age: 21,
  },
  mutations: {
    // 在这里定义 方法
    /**
     *
     * @param {*} state 第一个参数是 Store 中的状态(必须传递)
     * @param {*} newName 传入的参数 后面是多个
     */
    changeName(state, newName) {
      // 这里简单举个例子 修改个名字
      state.name = newName
    },
  },
  actions: {},
  modules: {},
})

在组件中使用 mutations 中的方法,同样有两种方法在组件触发 mutations 中的方法

1.this.$store.commit() 触发

在 methods 中定义一个方法,在这个方法里面通过this.$store.commit触发 mutations 中的方法

<template>
  <div id="app">
    <button @click="handleClick">方式1 按钮使用 mutation 中方法</button>
    {{ name }}
  </div>
</template>

<script>

// 从 Vuex 中导入 mapState
import { mapState } from 'vuex'
export default {
  name: 'App',
  computed: {
    // 将 store 映射到当前组件的计算属性
    ...mapState(['name', 'age'])
  },
  methods: {
    handleClick() {
      // 触发 mutations 中的 changeName
      this.$store.commit('changeName', '小浪')
    }
  },
}
</script>

<style  scoped>
</style>

2.使用 mapMutations

<template>
  <div id="app">
    <button @click="changeName('小浪')">方式2 按钮使用 mutation 中方法</button>
    {{ name }}
  </div>
</template>

<script>

// 从 Vuex 中导入 mapState
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'App',
  computed: {
    // 将 store 映射到当前组件的计算属性
    ...mapState(['name', 'age'])
  },
  methods: {
	// 将 mutations 中的 changeName 方法映射到 methods 中,就能直接使用了 changeName 了
    ...mapMutations(['changeName'])
  },
}
</script>

<style  scoped>
</style>

3.Action

Action 和 Mutation 区别

Action 同样也是用来处理任务,不过它处理的是异步任务,异步任务必须要使用 Action

如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是要通过触发 Mutation 的方式间接变更数据。

/* src/store/index.js */

// 导入 Vue
import Vue from 'vue'
// 导入 Vuex 插件
import Vuex from 'vuex'

// 把 Vuex 注册到Vue 上
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    name: '张三',
    age: 21,
  },
  mutations: {
    // 在这里定义 方法
    /**
     *
     * @param {*} state 第一个参数是 Store 中的状态(必须传递)
     * @param {*} newName 传入的参数 后面是多个
     */
    changeName(state, newName) {
      // 这里简单举个例子 修改个名字
      state.name = newName
    },
  },
  actions: {
    /**
     *
     * @param {*} context 上下文默认传递的参数
     * @param {*} newName 自己传递的参数
     */
    // 定义一个异步的方法 context是 store
    changeNameAsync(context, newName) {
      // 这里用 setTimeout 模拟异步
      setTimeout(() => {
        // 在这里调用 mutations 中的处理方法
        context.commit('changeName', newName)
      }, 2000)
    },
  },
  modules: {},
})

在组件中是 Action 中的异步方法也是有两种方式

1.this.$store.dispatch()

// 定义 Action
 const store = new Vuex.Store({

// ...省略其他代码 
   mutations: {

		addN(state, step) { 
      state.count += step
		} 
   },

actions: { 
  addNAsync(context, step) {
		setTimeout(() => { 
      context.commit('addN', step)
		}, 1000) }
} })

// 触发 Action methods: {

handle() {
 // 在调用 dispatch 函数,
 // 触发 actions 时携带参数 
  this.$store.dispatch('addNAsync', 5)

} }

//this.$store.dispatch() 是触发 actions 的第一种方式
//触发 actions 的第二种方式:
 
// 1. 从 vuex 中按需导入 mapActions 函数 
import { mapActions } from 'vuex'
//通过刚才导入的 mapActions 函数,将需要的 actions 函数,映射为当前组件的 methods 方法:
// 2. 将指定的 actions 函数,映射为当前组件的 methods 函数 
methods: {
	...mapActions(['addASync', 'addNASync']) }

4.Getter

  • Getter 类似于计算属性,但是我们的数据来源是 Vuex 中的 state ,所以就使用 Vuex 中的 Getter 来完成
  • Getter 用于对 Store 中的数据进行加工处理形成新的数据
  • Store 中数据发生变化,Getter 的数据也会跟着变化。

Getter 也有两种方式导入

1.this.$store.getters[名称]

2.使用 mapGetters

// 定义 Getter
 const store = new Vuex.Store({

 	state: {
    count: 0
 	}, 
 	getters: {
		showNum: state => {
 			return '当前最新的数量是【'+ state.count +'】'
    } 
 	}
})
 
//使用 getters 的第一种方式:
this.$store.getters.名称
//使用 getters 的第二种方式:
import { mapGetters } from 'vuex'
computed: { 
  ...mapGetters(['showNum'])
}

5.Module

为了避免在一个复杂的项目 state 中的数据变得臃肿,Vuex 允许将 Store 分成不同的模块,每个模块都有属于自己的 stategetteractionmutation

Vuex的严格模式是什么,有什么作用,怎么开启?

在严格模式下,无论何时发生了状态变更且不是由 mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

在Vuex.Store 构造器选项中开启

const store = new Vuex.Store({
strict:true,
})

怎么引用Vuex?

  • 先安装依赖nnpm install vuex --save
  • 在项目目录src中建立store文件夹
  • 在store文件夹下新建index.js文件,写入
导入 vuex 包 
 import Vuex from 'vuex'

Vue.use(Vuex)

创建 store 对象

const store = new Vuex.Store({ // state 中存放的就是全局共享的数据 state: { count: 0 } })

将 store 对象挂载到 vue 实例中
阅读剩余
THE END