Vuex基础知识

本文介绍了Vuex在Vue应用中的角色,包括状态仓库、单一数据流原则、安装步骤、核心概念如state、mutations、actions以及模块化管理。详细讲解了如何在项目中使用Vuex进行数据共享和状态更新。
摘要由CSDN通过智能技术生成

一、Vuex介绍 

vuex是状态管理工具,提供数据仓库,用于组件间的数据共享。当使用vuex共享数据时,应遵循单项数据流。

官网地址:Vuex 是什么? | Vuex

状态自管理应用包含以下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

以下是一个表示“单向数据流”理念的简单示意:

 二、Vuex安装

1. 安装vuex,vue2.x版本使用vuex3,vue3.x使用vuex4

npm环境执行命令 npm i vuex@3   或 npm i vuex@4

npm i vuex@3

yarm环境

yarn add vuex

2. 创建目录,及index.js文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

3. 在main.js文件中挂载store

import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

4. 验证,在项目中可以使用$store属性

三、 Vuex核心概念

store的js文件

import Vue from 'vue'
import Vuex from 'vuex'
import setting from './modules/setting.js'
import user from './modules/user.js'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    data1: 99999,
    data2: 88888
  },
  getters: {
    // 包含参数
    data1ToString: state => (v1, v2) => {
      return state.data1 + '' + v1 + v2
    },
    // 不包含参数
    data2ToString (state) {
      return state.data1 + 'string'
    },
    // 使用getters作为参数
    data12 (state, getters) {
      return getters.data1ToString('s', 'd') + getters.data2ToString
    }
  },
  mutations: {
    changeData1 (state) {
      state.data1 = 'hfdd'
    },
    changeData2 (state, v) {
      state.data2 = v
    }
  },
  actions: {
    changeData2Sync (context, v) {
      setTimeout(() => {
        context.commit('changeData2', v)
      }, 1000)
    }
  },
  modules: {
    setting,
    user
  }
})

 1. state 状态仓库,存储组件共享的所有数据。

使用:在store的js文件中设置状态数据,在组件中使用$store.state.属性名 应用数据

mapState辅助拓展函数,等价于compute中的计算

  state: {
    data1: 99999,
    data2: 88888
  },

// SonA.vue
<template>
  <div>
    <h1>我是子组件A {{ $store.state.data1 }}</h1>
    <h1>测试数据 {{ data3 }}</h1>
    <h1>测试数据 {{ data2 }}</h1>
  </div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
  computed: {
    data3 () {
      return this.$store.state.data2
    },
    ...mapState(['data2', 'data1']), // 等价于changeData2的写法
  },
}
</script>

2. mutations,store的状态的唯一提交方法

由于vuex遵循单项数据流规范,所有的状态修改操作均在mutations中执行。同步执行。mutations由type和handle组成。handle函数中state作为第一个参数变量。组件提交事件的时候,可以传递一个参数且只能传递一个参数,作为mutations的载荷(payload),实现动态修改状态功能。当参数有多个时,需要通过数据或对象的方式传送

mapMutations辅助拓展函数,作用等价于methods中的同名方法,可直接调用。且当methods中存在与...mapMutations中同名的方法时,组件优先使用mapMutations中的方法。

  mutations: {
    changeData1 (state) {
      state.data1 = 'hfdd'
    },
    changeData2 (state, v) {
      state.data2 = v
    }
  },

// SonV.vue
<template>
  <div>
    <h1>我是子组件A {{ $store.state.data1 }}</h1>
    <button @click="changeData1">修改数据1</button>
    <button @click="changeData2(56789)">修改数据2</button>
  </div>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
  methods: {
    changeData2 () {
      this.$store.commit('changeData1')
    },
    ...mapMutations(['changeData1', 'changeData2']) // 等价于changeData2的写法
  }
}
</script>

3. actions(分发),异步操作

使用方法与mutations类似,handler方法中的第一个参数是context(上下文,未分模块时默认store),通过context.commit('mutations中的方法名')修改属性值。组件中通过store.dispatch触发。其辅助函数为mapActions。

  actions: {
    changeData2Sync (context, v) {
      setTimeout(() => {
        context.commit('changeData2', v)
      }, 1000)
    }
  },

// SonV.vue
<template>
  <div>
    <h1>测试数据 {{ data2 }}</h1>
    <button @click="changeData2Sync(676576)">修改数据2-0</button>
  </div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
  methods: {
    changeData1Sync () {
      this.$store.dispatch('changeData1Sync', '000000')
    },
    ...mapActions(['changeData2Sync']) // 等价于changeData1Sync的写法的写法
  }
}
</script>

4. getters,state中派生出来的属性

类似于compute属性,设置state中派生出来的属性值,必须有返回值。在组件中通过$store.getters.属性名 获取值。其辅助函数为mapGetters。

第一个参数是state,可以把getters第二个参数。也可以通过方法的方式传送多个参数。

  getters: {
    // 包含参数
    data1ToString: state => (v1, v2) => {
      return state.data1 + '' + v1 + v2
    },
    // 不包含参数
    data2ToString (state) {
      return state.data1 + 'string'
    },
    // 使用getters作为参数
    data12 (state, getters) {
      return getters.data1ToString('s', 'd') + getters.data2ToString
    }
  },

// SonV.vue
<template>
  <div>
    <h1>测试数据 {{ data1ToString('dddddd', 'sssss') }}</h1>
    <h1>测试数据 {{ data12 }}</h1>
  </div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['data1ToString', 'data2ToString', 'data12'])
  }
}
</script>

5.mofules 模块

vuex使用单一状态树,当属性增多时,inedx.js文件会比较巨大,此时分割成多个文件,或便于管理与维护。

建议在模块js中开启命名空间,便于调用。namespaced: true

// index.js  store
import Vue from 'vue'
import Vuex from 'vuex'
import setting from './modules/setting.js'
import user from './modules/user.js'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    setting,
    user
  }
})

// user.js
const state = {
  userInfo: {
    name: 'HG',
    age: 18
  },
  group: 'HJ'
}
const mutations = {
  changeUser (state, v) {
    state.userInfo.name = v
  }
}
const actions = {
  changeUserSync (context, v) {
    setTimeout(() => {
      context.commit('changeUser', v)
    }, 1000)
  }
}
const getters = {
  groupEx (state) {
    return state.group + 'BJ'
  }
}

export default {
  namespaced: true, // 开启命名空间,便于辅助函数调用模块中的信息
  state,
  mutations,
  getters,
  actions
}

在组件中调用模块中信息方法:

  • state: $store.state.模块命名空间.属性名;...mapState('模块命名空间', ['属性名1', '属性名2'])
  • getters: $store.getters['模块命名空间/getters属性名'];...mapGetters('模块命名空间', ['getters属性名'])
  • mutations: $store.commit['模块命名空间/mutations方法名', '参数'];...mapMutations('模块命名空间', ['mutations方法名'])
  • actions: $store.dispatch['模块命名空间/actions方法名', '参数'];...mapActions('模块命名空间', ['actions方法名'])
<template>
  <div>
    <h1>子模块数据 {{ $store.state.user.userInfo }}</h1>
    <h1>子模块数据2 {{ group }}</h1>
    <h1>子模块数据groupEx {{ groupEx }}</h1>
    <button @click="changemoduleInfo(676576)">修改子模块数据</button>
    <button @click="changeUser('errr')">修改子模块数据2</button>
  </div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
  computed: {
    ...mapState('user', ['userInfo', 'group']),
    groupEx1 () {
      return this.$store.getters['user/groupEx']
    },
    ...mapGetters('user', ['groupEx'])
  },
  methods: {
    changemoduleInfo (v) {
      this.$store.commit('user/changeUser', v)
    },
    ...mapMutations('user', ['changeUser']),
    changeUserSync1 (v) {
      this.$store.dispatch('user/changeUserSync', v)
    },
    ...mapActions('user', ['changeUserSync'])
  }
}
</script>

 

  • 44
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值