Appearance
基本概念
Vuex 是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
State
- 在 store/ index.js 里定义全局数据
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0 //定义全局数据
},
//mutations 用于变更 Store 中的数据
mutations: {},
actions: {},
modules: {}
})
- 在组件中使用数据
vue
<!-- 通过 $store.state 使用 -->
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}</h3>
<button>+1< /button>
</div>
</template>
- 通过 mapState 使用
vue
<template>
<div>
<h3>当前最新的count值为:{{ count }}</h3>
<button>-1</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState(['count'])
}
}
</script>
Mutation
- 在 store/ index.js 里定义 mutations 函数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
add(state) {
state.count += 1
}
},
actions: {},
modules: {}
})
- 在组件中调用修改数据
vue
<template>
<div>
<h3>当前最新的count值为:{{ $store.state.count }}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
methods: {
add() {
// this.$store.state.count+=1 这种方式会直接修改全局数据不方便后期维护,不能使用这种用法
//触发 mutations 里的 mutations 函数修改数据,commit 可以调用某个 mutations 函数
this.$store.commit('add')
}
}
}
</script>
- mutations 可以接收参数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
add(state, stap) {
state.count += stap
}
},
actions: {},
modules: {}
})
- 在组件中调用并传递参数
vue
<template>
<div>
<h3>当前最新的count值为:{{ $store.state.count }}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
methods: {
add() {
// 向 mutations 的 add 函数传递参数
// 传递的参数只能传递一个参数,有多个参数可以放到数组和对象中
this.$store.commit('add', 3)
}
}
}
</script>
- 第二种方式
- 在 store/ index.js 里定义 mutations 函数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
sub(state, stap) {
state.count -= stap
}
},
actions: {},
modules: {}
})
- 在组件中调用
vue
<template>
<div>
<h3>当前最新的count值为:{{ count }}</h3>
<button @click="mysub">-1</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapState(['count'])
},
methods: {
...mapMutations(['sub']),
mysub() {
this.sub(3)
}
}
}
</script>
不支持异步任务
- 在 mutations 中不能使用异步代码
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
mutations: {
sub(state, stap) {
//在 mutations 中不能使用异步代码
setTimeout(() => {
state.count -= stap
})
}
},
actions: {},
modules: {}
})
Action
- 在 store/ index.js 里定义 actions 函数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
add(state, stap) {
state.count += stap
},
sub(state, stap) {
state.count -= stap
}
},
actions: {
addAsync(context, n) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据
// 必须通过 context.commit() 触发某个 mutations 才行
context.commit('add', n)
}, 1000)
}
},
modules: {}
})
- 在组件中调用
vue
<template>
<div>
<h3>当前最新的count值为:{{ $store.state.count }}</h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
methods: {
add() {
// 这里的 dispatch 函数,专门用来触发 action
this.$store.dispatch('addAsync', 3)
}
}
}
</script>
actions 函数第二种使用方法
在 store/ index.js 里定义 actions 函数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
add(state, stap) {
state.count += stap
},
sub(state, stap) {
state.count -= stap
}
},
actions: {
addAsync(context, n) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据
// 必须通过 context.commit() 触发某个 mutations 才行
context.commit('add', n)
}, 1000)
}
},
modules: {}
})
- 在组件中调用
vue
<template>
<div>
<h3>当前最新的count值为:{{ $store.state.count }}</h3>
<button @click="addAsync(3)">-1</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods: {
// 通过 mapActions 可以将 addAsync 函数作为当前组件的私有方法使用
...mapActions(['addAsync'])
}
}
</script>
三者和视图的关系
Getter
- 相当于 Store 里的计算属性,能将 State 里的数据进行加工然后再返回
- 在 store/ index.js 里定义 Getter 函数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
add(state, stap) {
state.count += stap
},
sub(state, stap) {
state.count -= stap
}
},
actions: {
addAsync(context, n) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据
// 必须通过 context.commit() 触发某个 mutations 才行
context.commit('sub', n)
}, 1000)
}
},
// 定义 getters 函数
getters: {
showNum(state) {
return `当前最新的数量是${state.count}`
}
},
modules: {}
})
- 在组件中调用 $store.getters.showNum
vue
<template>
<div>
<h3>{{ $store.getters.showNum }}</h3>
</div>
</template>
- 在 store/ index.js 里定义 Getter 函数
js
export default new Vuex.Store({
// state 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 state 中进行存储
state: {
count: 0
},
//mutations 用于变更 Store 中的数据
mutations: {
add(state, stap) {
state.count += stap
},
sub(state, stap) {
state.count -= stap
}
},
actions: {
addAsync(context, n) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据
// 必须通过 context.commit() 触发某个 mutations 才行
context.commit('sub', n)
}, 1000)
}
},
// 定义 getters 函数
getters: {
showNum(state) {
return `当前最新的数量是${state.count}`
}
},
modules: {}
})
- 在组件中调用
vue
<template>
<div>
<h3>当前最新的count值为:{{ $store.state.count }}</h3>
<button @click="showNum">-1</button>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
methods: {
// 通过 mapGetters 可以将 showNum 函数作为当前组件的私有方法使用
...mapGetters(['showNum'])
}
}
</script>
modules
- 在全局状态管理 store/index.js 文件中定义
js
export default new Vuex.Store({
state: {
count: 100
},
mutations: {},
actions: {},
getters: {},
// 当项目很大时可以将 vuex 里的数据进行模块化处理,便于维护
modules: {
user: {
state: {
token: '123456'
}
},
setting: {
state: {
name: 'vuex实例'
}
}
}
})
- 在其他组件里使用子模块数据
vue
<template>
<div id="app">
<p>用户名:{{ $store.state.user.token }}</p>
<p>应用名:{{ $store.state.setting.name }}</p>
</div>
</template>
- 快捷访问方式
- 在全局状态管理 store/index.js 文件中定义
js
export default new Vuex.Store({
state: {
count: 100
},
mutations: {},
actions: {},
getters: {
// 我们可以通过之前学过的getters来改变一下,使组件访问更快捷
token: state => state.user.token,
name: state => state.setting.name
},
// 当项目很大时可以将 vuex 里的数据进行模块化处理,便于维护
modules: {
user: {
state: {
token: '123456'
}
},
setting: {
state: {
name: 'vuex实例'
}
}
}
})
- 在其他组件里使用子模块数据
vue
<template>
<div id="app">
<p>用户名:{{ $store.state.user.token }}</p>
<p>用户名快捷访问方式:{{ token }}</p>
<p>应用名:{{ $store.state.setting.name }}</p>
<p>应用名快捷访问方式:{{ name }}</p>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'app',
computed: {
...mapGetters(['token', 'name'])
}
}
</script>
调用子模块的 mutations 方法和命名空间
- 在全局状态管理 store/index.js 文件中定义
js
export default new Vuex.Store({
getters: {
token: state => state.user.token
},
// 当项目很大时可以将 vuex 里的数据进行模块化处理,便于维护
modules: {
user: {
namespaced: true, // 保证内部模块的高封闭性,添加命名空间,这样这个子模块定义的 mutations 就不是全局的了
state: {
token: '123456'
},
mutations: {
// 这里的state表示的是user的state
updateToken(state) {
state.token = '5555'
}
}
}
}
})
- 在其他组件里使用子模块数据(一)
vue
<template>
<div id="app">
<p>用户token:{{ token }}</p>
<button @click="test">改变token</button>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'app',
computed: {
...mapGetters(['token', 'name'])
},
methods: {
// 方法一
test() {
this.$store.commit('user/updateToken') // 直接调用方法
}
}
}
</script>
- 辅助函数方式调用(二)
vue
<template>
<div id="app">
<p>用户token:{{ token }}</p>
<button @click="test">改变token</button>
</div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
export default {
name: 'app',
computed: {
...mapGetters(['token', 'name'])
},
methods: {
...mapMutations(['user/updateToken']),
test() {
// 方法二
this['user/updateToken']() // 辅助函数方式
}
}
}
</script>
- 基于命名空间辅助函数(三)
vue
<template>
<div id="app">
<p>用户token:{{ token }}</p>
<button @click="test">改变token</button>
</div>
</template>
<script>
import { mapGetters, createNamespacedHelpers } from 'vuex'
const { mapMutations: userMapMutations } = createNamespacedHelpers('user')
export default {
name: 'app',
computed: {
...mapGetters(['token', 'name'])
},
methods: {
...userMapMutations(['updateToken']),
test() {
// 方法三
this.updateToken() // 基于命名空间辅助函数
}
}
}
</script>