Vuex概述
组件之间共享数据的方式
- 父传子:v-bind 属性绑定
- 子传父:v-on 事件绑定
- 兄弟传值:EventBus
- $on :接受数据的组件
-
Vuex是什么
Vuex 是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
使用 Vuex 统一管理状态的好处
能够在 Vuex 中集中管理共享的数据,易于开发和后期维护
- 能够高效地实现组件之间的数据共享,提高开发效率
存储在 Vuex 中的数据都是响应式的,能够实时保持数据与页面的同步
什么数据适合存储到 Vuex 中
一般情况下,只有组件之间共享的数据,才有必要存储到 Vuex 中
- 对于组件中的私有数据,依旧存储在组件自身的 data 中即可
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 实例中
new Vue({el: '#app',render: h => h(app),router,// 将创建的共享数据对象,挂在到 Vue 实例中// 所有的组件,就可以直接从 store 中获取全局的数据了store})
创建 vuex 项目
找到需要创建项目的文件夹目录,在该目录下打开 cmd 命令窗口,输入 vue ui 命令

- 点击创建项目按钮,然后输入依照以下内容进行填写

- 安装预设选择 手动配置, 功能如下:
- Choose Vue version
- Babel
- Vuex
- Router
- Linter / Formatter
- Use config files
- 配置文件选择
State
在 Vue 组件中获得 Vuex 状态
从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:
// 创建一个 State.vue 组件<template><div><h1>名字:{{ name }}</h1><h2>年龄:{{ age }}</h2><h3>数量:{{ num }}</h3><input type="text" v-model="num"></div></template><script>// state 在组件中的应用export default {computed: {name () {return this.$store.state.name},age () {return this.$store.state.age},num: {get () {return this.$store.state.num},set (val) {this.$store.commit('setNumber', val)}}}}</script>
// router/index.js// 导入 State.vue 组件import State from '../view/State.vue'// 将 State.vue 组件挂在到 router/index.js 文件夹下{ path: '/state', component: 'State' }
// store/index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)// 创建整个项目的数据仓库对象,将多组件共用的数据对象放置到此对象里export default new Vuex.Store({// datastate: {name: 'JiangChen',age: 18,num: 0},// methods, 在 mutation 里处理状态mutations: {addNumber (state) {state.num += 2},setNumber (state, value) {state.num = value}}})
mapState 辅助函数
当一个组件需要获取多个状态时,将这些状态声明为计算属性会有些重复和冗余。
// 导入 mapStateimport { mapState } from 'vuex'
mapState 映射方法1(数组)
<input type="text" :value="num" @input="changeValue">
export default {computed: mapState(['name', 'age', 'num']),methods: {changeValue (e) {this.$store.commit('setNumber', e.target.value)}}}
mapState 映射方法2
<input type="text" :value="num" @input="changeValue">
export default {computed: mapState({// 对象方式name: 'name',// 箭头函数方式age: (state)=>state.age,num: 'num'})}
mapState 映射方法3 ```javascript let mapStateObj = mapState({ // 对象方式 name: ‘name’, // 箭头函数方式 age: (state)=>state.age, num: ‘num’ })
export default { computed: { reverse () { return this.name.split(‘ ‘).reverse().join(‘’) }, …mapStateObj } }
<a name="HDDjB"></a># Getter<a name="ppZHB"></a>## 在Vuex中通过方法访问Getters状态从 **store** 实例中读取状态最简单的方法就是在**计算属性**中返回某个状态:```vue// 创建一个 Getter.vue 组件<template><div><h1>{{ $store.getters.reverseName }}</h1><h2>{{ reverseName }}</h2></div></template><script>export default {mounted () {console.log(this);},computed: {reverseName () {return this.$store.getters.reverseName}}}</script>
// router/index.js// 导入 Getter.vue 组件import Getter from '../view/Getter.vue'// 将 Getter.vue 组件挂在到 router/index.js 文件夹下{ path: '/getter', component: 'Getter' }
// store/index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)// 创建整个项目的数据仓库对象,将多组件共用的数据对象放置到此对象里export default new Vuex.Store({// 状态getters: {reverseName (state) {return state.name.split('').reverse().join('')},minin (state) {return '123' + state.name}}})
mapGetters 辅助函数
// 导入 mapGettersimport { mapGetter } from 'vuex'
mapGetters 方法1:
export default {computed: mapGetters(['reverseName', 'mixinName'])}
mapGetter 方法2: ```javascript import {mapGetters, mapState} from ‘vuex’ let mapGetData = mapGetters([‘reverseName’, ‘mixinName’]); let mapStateData = mapState([‘name’, ‘age’, ‘num’])
export default { computed: { …mapGetData, …mapStateData } }
- mapGetter 方法3:```html<!-- Getter.vue --><h3>{{ mixinName1 }}</h3>
// Getter.vuecomputed: {...mapGetData,...mapStateData,mixinName1() {return this.$store.getters.mixinName('666')}}
// store/index.js// 状态getters: {mixinName (state) {return (val) => {return state.name + val}}}
Mutation
-
提交载荷(Payload)
载荷当作参数传入
向 mutation 中的方法提交第二个参数
// Home.vue<button @click="setAction">setAction</button>
// store/index.jsmutations: {setNumber (state, value) {state.num += value}}
在 Home.vue 组件中添加 setAction 方法,在方法内部调用 mutations 对象中的 setNumber 方法,并传入对应的参数
setAction 可以改成任意名字
// Home.vuemethods: {setAction () {this.$store.commit('setNumber', 5)}}
载荷当作对象使用
<button @click="autoAction">autoAction</button>
// store/index.jsmutations: {autoNumber (state, payload) {state.num += payload.amount}}
- 在 Home.vue 组件中添加 autoAction 方法,在方法内部调用 mutations 对象中的 autoNumber 方法,并传入对应的参数
autoAction 可以改成任意名字
methods: {autoAction () {this.$store.commit('autoNumber', {amount: 3})}}
将方法当作对象传入
<button @click="typeAction">typeAction</button>
// store/index.jsmutations: {typeNumber (state, payload) {state.num += payload.amount}}
- 在 Home.vue 组件中添加 typeAction 方法,在方法内部调用 mutations 对象中的 typeNumber 方法,并传入对应的参数
typeAction 可以改成任意名字
methods: {typeAction () {this.$store.commit('autoNumber', {amount: 8})}}
在组件中提交 Mutation(mapMutations 辅助函数)
<h1>{{ num }}</h1><button @click="autoNumber({amount: 5})">autoNumber</button>
// About.vue 组件中导入 mapMutations, mapStateimport { mapMutations, mapState } from 'vuex'let mapStateObj = mapState(['name', 'age', 'num', 'duanzi'])let mapMutationsObj = mapMutations(['addNumber', 'setNumber','autoNumber', 'typeNumber'])export default {computed: {...mapStateObj},methods: {...mapMutationsObj}}
// store/index.jsexport default new Vuex.Store({// datastate: {name: 'JiangChen',age: 18,num: 0,duanzi: null},// 异步方法actions: {setDz (content) {let httpUrl = 'https://api.apiopen.top/getJoke?page=1&count=10&type=text';fetch(httpUrl).then(res => res.json()).then(res => {console.log(res)console.log(content);// 通过 muation 来设置 statecontent.commit('setDuanzi', res.result)})}}})
Action
- {{ item.text }}
```javascript// Action.vue 组件中export default {methods: {getDuanzi () {this.$store.dispatch('setDz')}}}
// store/index.jsexport default new Vuex.Store({actions: {setDz (content) {let httpUrl = 'https://api.apiopen.top/getJoke?page=1&count=10&type=text';fetch(httpUrl).then(res => res.json()).then(res => {console.log(res)console.log(content);// 通过 muation 来设置 statecontent.commit('setDuanzi', res.result)})}}})
mapActions 辅助函数
<button @click="setDz">setDz</button><ul style="text-align: left;"><li v-for="(item, index) in duanzi" :key="index">{{ item.text }}</li></ul>
// Action.vue 组件中import { mapState, mapActions } from 'vuex'let mapStateObj = mapState(['duanzi'])let mapActionsObj = mapActions(['setDz'])export default {computed: {...mapStateObj},methods: {...mapActionsObj}}
// store/index.jsexport default new Vuex.Store({// datastate: {name: 'JiangChen',age: 18,num: 0,duanzi: null},// 异步方法actions: {setDz (content) {let httpUrl = 'https://api.apiopen.top/getJoke?page=1&count=10&type=text';fetch(httpUrl).then(res => res.json()).then(res => {console.log(res)console.log(content);// 通过 muation 来设置 statecontent.commit('setDuanzi', res.result)})}}})
Modules
将 store/index.js 文件中的所有模块全部使用模块化的方式导入
// store/index.jsimport state from './state'import getters from './getters'import mutations from './mutations'import actions from './actions'import buyCar from './buyCar'export default new Vuex.Store({// datastate,// 状态getters,// methods, 在 mutation 里处理状态mutations,// 异步方法actions,// 模块modules: {buyCar}
使用模块化
// BuyCar.vue<h2 style="color: aqua;">{{ $store.state.buyCar.productNum }}</h2><h3>{{ buyCar.productNum }}</h3><h4>{{ brief }}</h4><button @click="addProNum">addProNum</button><br><br><button @click="changeProNum">changeProNum</button>
// BuyCar.vueimport { mapState, mapGetters, mapMutations, mapActions } from 'vuex'let mapStateObj = mapState(['buyCar'])let mapGettersObj = mapGetters(['brief'])let mapMutationsObj = mapMutations(['addProNum'])let mapActionsObj = mapActions(['changeProNum'])export default {mounted () {console.log(this);},computed: {...mapStateObj,...mapGettersObj},methods: {...mapMutationsObj,...mapActionsObj}}
