vuex讲解
一、vuex基本使用
1. 安装
npm i vuex -S
2. 导入 并 使用到项目中
import Vuex from 'vuex'
vue.use(Vuex)
3. 创建 store 对象
const store = new Vuex.Store({
state:{ count = 0 } // state 对象里面的就是全局共享数据,如这里的 count
})
4. 将 store 对象挂载到 vue 实例当中
new Vue({
el: '#app'
render: h => h(app)
router
store // 此时,所有 vue 项目中的组件均可共享 store 中的数据
})
二、在 vue-cli 创建的 vue 项目中讲解 vuex 的使用
1. 创建后的项目目录简述
store 文件夹里的 index.js 文件如下(相当于自己创建的 store.js 文件):
main.js 文件如下:
2. 核心概念讲解
讲解要素:vuex 中主要核心概念:
- State
- Mutations
- Actions
- Getters
另外: 有个 modules 节点
讲解准备:在项目中先创建 Add.vue 和 Sub.vue 组件,并在 App.vue 中导入使用:
- Add.vue :
<template>
<div>
<h3>count =</h3>
<button>+1</button>
</div>
</template>
<script>
export default {
data() {
return {}
}
}
</script>
- Sub.vue :
<template>
<div>
<h3>count =</h3>
<button>-1</button>
</div>
</template>
<script>
export default {
data() {
return {}
}
}
</script>
- App.vue :
<template>
<div>
<my-add></my-add>
<p>---------------------</p>
<my-sub></my-sub>
</div>
</template>
<script>
// 1. 导入子组件
import Add from '@/components/Add.vue'
import Sub from '@/components/Sub.vue'
export default {
data() {
return {}
},
components: {
// 注册私有组件,并重新命名
'my-add': Add,
'my-sub': Sub
}
}
</script>
2.1 State 讲解
State 是唯一的公共数据源。所有共享数据都放在 Store/index.js 的 State 中进行存储。
- Store/index.js :
import Vue from 'vue'
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
// 存储数据仓库
const state = {
count: 0 // 共享数据 count
}
// 唯一能对state数据进行修改的地方
const mutations = {}
// 业务逻辑和异步操作
const actions = {}
// 简化仓库数据,相当于计算属性,使得组件获取仓库数据更加方便
const getters = {}
// 对外暴露实例
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
Add.vue 和 Sub.vue 组件中使用共享数据 count。
- 1. 通过
this.$store.state.全局数据名称
方式使用
Add.vue :
注:template 中 this 可以省略
<template>
<div>
<h3>count = {{ $store.state.count }}</h3>
<button>+1</button>
</div>
</template>
- 2. 通过
mapState
映射函数方式使用
Sub.vue :
<template>
<div>
<!-- 3. 使用全局共享数据 -->
<h3>count = {{ count }}</h3>
<button>-1</button>
</div>
</template>
<script>
// 1. 导入 mapState 函数
import { mapState } from 'vuex'
export default {
data() {
return {}
},
// 2. 在计算属性节点映射全局共享数据,并用展开运算符展开
computed: {
...mapState(['count'])
}
}
</script>
2.2 Mutations 讲解
任何时候都不要直接去修改 State 里面的数据,否则可能会造成不必要的意外,也不利于后期维护。例如:
<template>
<div>
<h3>count = {{ $store.state.count }}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
add() {
this.$store.state.count++ // 切记不要这样
}
}
}
</script>
因此,Mutation 出现了,它用于变更 Store 中的数据。
Store/index.js :
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0 // 共享数据 count
},
getters: {},
mutations: {
// 定义 add() 方法
add(state) {
// 变更状态
state.count++
}
},
actions: {},
modules: {}
})
Mutations 里的函数也可以传参:
mutations: {
// 第一个参数永远是 state ,第二个参数是传进来的参数
addN(state,step) {
state.count += step
}
},
- 1. 使用
this.$store.commit()
方式调用方法
App.vue :
<template>
<div>
<h3>count = {{ $store.state.count }}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
add() {
this.$store.commit('add') // commit() 作用就是调用 Store 中的函数
}
}
}
</script>
使用时候传参:
methods: {
add() {
this.$store.commit('addN',5) // 5 是传参
}
}
- 2. 使用 mapMutations 映射方式调用方法
Sub.vue :
<template>
<div>
<h3>count = {{ count }}</h3>
<button @click="subclick">-1</button>
</div>
</template>
<script>
// 1. 导入 mapMutations 函数
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState(['count'])
},
// 2. 在 methods 节点映射全局共享数据,并用展开运算符展开。然后调用。
methods: {
...mapMutations(['sub']),
subclick() {
this.sub()
}
}
}
</script>
2.3 Actions 讲解
看看下面,我们在 Store/index.js 里的 mutations 里进行异步操作。其实这样是不行的!!
export default new Vuex.Store({
state: {
count: 0 // 共享数据 count
},
getters: {},
mutations: {
addN(state, step) {
// 不要在 mutations 进行异步操作
// setTimeout(function () {
// state.count += step
// }, 1000)
},
sub(state) {
state.count--
}
},
actions: {},
modules: {}
})
在 vuex 中,如果要通过异步操作变更数据,必须通过 Actions,在 Actions 中触发 Mutations 的方式间接变更数据。
Store/index.js :
export default new Vuex.Store({
state: {
count: 0 // 共享数据 count
},
mutations: {
add(state) {
state.count++
},
addN(state,step) {
state.count += step
}
},
actions: {
addAsync(context) {
setTimeout(() => {
context.commit('add') // 触发 mutations 中的函数
}, 1000)
}
},
})
接收参数:
actions: {
addAsync(context,step) { // step 接收组件中传过来的参数
setTimeout(() => {
context.commit('addN',step) // step 是将上面的参数传到 mutations 中的函数中
}, 1000)
}
}
- 1. 使用
this.$store.dispatch()
触发 actions 中的函数
App.vue :
<template>
<div>
<h3>count = {{ $store.state.count }}</h3>
<button @click="addAsc">+5</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
addAsc() {
this.$store.dispatch('addAsync') // 使用 dispatch 触发 actions 中的函数
}
}
}
</script>
传参:
methods: {
addAsc() {
this.$store.dispatch('addAsync',5) // 使用 dispatch 触发 actions 中的函数
}
}
- 2. 使用
mapActions
映射方式触发 actions 中的函数
<template>
<div>
<h3>count = {{ $store.state.count }}</h3>
<button @click="addAsync()">+5</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {}
},
methods: {
...mapActions(['addAsync']),
}
}
</script>
2.4 Getters 讲解
Getters 用于对 Store 中的数据进行加工,形成新的数据,类似于 vue 中的计算属性。
Store 中的数据发生变化,Getter 的数据也会跟着变化。
Store/index.js :
getters: {
showNum(state) {
return '当前的值为:' + state.count
}
}
- 1. 通过
$store.getters.方法名称
方式使用
Add.vue :
<template>
<div>
<h3>{{ $store.getters.showNum }}</h3>
</div>
</template>
- 2. 通过
mapGetters
映射方式使用
<template>
<div>
<!-- 3. 使用 -->
<h3>count = {{ count }}</h3>
</div>
</template>
<script>
// 1. 导入函数
import { mapGetters } from 'vuex'
export default {
data() {
return {}
},
// 2. 在计算属性节点映射全局共享数据,并用展开运算符展开
computed: {
...mapGetters(['showNum'])
}
}
</script>
2.5 modules 讲解
modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
const moduleA ={
state:{...},
mutations:{...},
actions:{...},
getters:{...}
}
const moduleB ={
state:{...},
mutations:{...},
actions:{...}
}
const store =newVuex.Store({
modules:{
a: moduleA,
b: moduleB
})
或者,每一个模块在相对应组件文件夹下建立对象的store模块(小仓库),然后在主仓库引入进来,再暴露出去。
import Vue from 'vue'
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
// 引入小仓库
import homeStore from './home/homeStore'
import searchStore from './search/searchStore'
// 对外暴露小仓库
export default new Vuex.Store({
modules: {
homeStore,
searchStore
}
})
本文来自博客园,作者:RHCHIK,转载请注明原文链接:https://www.cnblogs.com/suihung/p/16281310.html