项目初始化
初始化项目,项目目录为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| │ .gitignore │ babel.config.js │ package-lock.json │ package.json │ README.md │ ├─node_modules ├─public │ favicon.ico │ index.html │ └─src │ App.vue │ main.js │ ├─assets │ logo.png │ ├─components │ HelloWorld.vue │ └─store index.js
|
初始App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div id="app"> <HelloWorld /> </div> </template>
<script> import HelloWorld from "./components/HelloWorld.vue";
export default { name: "App", components: { HelloWorld, }, }; </script>
<style> </style>
|
初始HelloWorld.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <div class="hello"> <h1>Vuex 示例</h1> </div> </template>
<script> export default { name: "HelloWorld", }; </script>
<style scoped> </style>
|
初始化的Vuex
在/src/store
目录下的index.js
:
1 2 3 4 5 6 7 8 9 10 11
| import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, modules: {} })
|
此时页面显示效果:
state
在组件中引入Vuex
中的状态
直接引入
直接修改HelloWorld.vue
的h标签
1
| <h1>{{ this.$store.state.msg }}</h1>
|
在index.js
中加入
1 2 3
| state: { msg: 'this is vuex --- Vuex' },
|
显示结果为:
计算属性引入
在HelloWorld.vue
中增加计算属性,h标签和上面保持一致
1 2 3 4 5 6 7 8
| export default { name: "HelloWorld", computed: { msg() { return this.$store.state.msg } } };
|
显示结果为:
mapState
辅助函数
修改HelloWorld.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <div class="hello"> <h1>{{ msg }}</h1> <h1>{{ msgAlias }}</h1> <h1>{{ msgAddLocation }}</h1> </div> </template>
<script> import { mapState } from 'vuex' export default { name: "HelloWorld", data(){ return{ localMsg:'local' } }, computed: mapState({ msg: state => state.msg, msgAlias: 'msg', msgAddLocation(state) { return state.msg+this.localMsg } }) }; </script>
|
显示结果为:
当映射的计算属性名称和state
的子节点名称相同,可以给mapState
传一个字符串数组
1 2 3
| computed: mapState([ 'msg' ])
|
此时显示结果为:
对象展开运算符...mapState
1 2 3 4 5 6
| computed:{ ...mapState(['msg']), ...mapState({ message:'msg' }) }
|
Getter
getter
可以视为store
的计算属性,其第一个参数为state
修改index.js
:
1 2 3 4 5 6 7 8 9 10 11
| export default new Vuex.Store({ state: { msg: 'this is vuex --- Vuex by mapState', name: 'wonderful ' }, getters: { getMsg: state => state.msg, getName: (state, getters) => state.name + getters.getMsg }, })
|
修改HelloWorld.vue
1 2 3 4 5
| computed: { msg() { return this.$store.getters.getName } }
|
显示结果为:
mapGetters
辅助函数
修改HelloWorld.vue
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <template> <div class="hello"> <h1>{{ msg }}</h1> <h1>{{ name }}</h1> </div> </template>
<script> import { mapGetters } from 'vuex' export default { name: "HelloWorld", computed: mapGetters({ msg: 'getMsg', name: 'getName' }) }; </script>
<style scoped> </style>
|
使用对象展开运算符...mapGetters
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div class="hello"> <h1>{{ getMsg }}</h1> <h1>{{ getName }}</h1> </div> </template>
<script> import { mapGetters } from 'vuex' export default { name: "HelloWorld", computed: { ...mapGetters(['getMsg', 'getName']) } }; </script>
<style scoped> </style>
|
上面两种写法的显示结果为:
Mutation
更改Vuex
的store
中状态的唯一方法是提交mutation
修改的HelloWorld.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div class="hello"> <h1 @mouseover="onmouseover">{{ count }}</h1> </div> </template>
<script> import { mapGetters } from 'vuex' export default { name: "HelloWorld", computed: mapGetters({ msg: 'getMsg', name: 'getName', count: 'getCount' }), methods:{ onmouseover(){ this.$store.commit('increment') }, } }; </script>
<style scoped> </style>
|
修改后的index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({ state: { msg: 'this is vuex --- Vuex by mapState', name: 'wonderful ', count: 1 }, getters: { getMsg: state => state.msg, getName: (state, getters) => state.name + getters.getMsg, getCount: state => state.count }, mutations: { increment(state) { state.count++ } }, actions: {}, modules: {} })
|
此时鼠标在数字上移动时,数字会递增。
在提交commit
时也可以传入额外的参数,即mutation
的载荷(payload
)
对上述例子进行少许改动:
HelloWorld.vue
:
1 2 3 4 5
| methods:{ onmouseover(){ this.$store.commit('increment',10) }, }
|
index.js
:
1 2 3 4 5
| mutations: { increment(state, payload) { state.count += payload } },
|
对于payload
,也可以使用对象风格:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <template> <div class="hello"> <h1 @mouseover="onmouseover">{{ count+' '+name }}</h1> </div> </template>
<script> import { mapGetters } from 'vuex' export default { name: "HelloWorld", computed: mapGetters({ msg: 'getMsg', name: 'getName', count: 'getCount' }), methods: { onmouseover() { this.$store.commit('increment', { count: 10, msg: 'new', name: 'thanks' }) }, } }; </script>
<style scoped> </style>
|
index.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({ state: { msg: 'msg', name: 'name ', count: 1 }, getters: { getMsg: state => state.msg, getName: (state, getters) => state.name + getters.getMsg, getCount: state => state.count }, mutations: { increment(state, payload) { state.count += payload.count state.msg += payload.msg state.name += payload.name } }, actions: {}, modules: {} })
|
mapMutations
辅助函数
修改HelloWorld.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <template> <div class="hello"> <h1 @mouseover="onmouseover">{{ count }}</h1> </div> </template>
<script> import { mapGetters, mapMutations } from 'vuex' export default { name: "HelloWorld", computed: mapGetters({ msg: 'getMsg', name: 'getName', count: 'getCount' }), methods: { onmouseover() { this.add({ count: 10 }) }, ...mapMutations(['increment']), ...mapMutations({ add:'increment'//将increment映射为add }) } }; </script>
<style scoped> </style>
|
在 Vuex
中,mutation
都是同步事务,store.commit('increment')
中,任何由increment
导致的状态变更都应该在此刻完成。
Action
Action
类似于mutation
,不同在于:
Action
提交的是mutation
,而不是直接变更状态
Action
可以包含任意异步操作
注册一个Action
:
1 2 3 4 5
| actions: { increment(context) { context.commit('increment') } }
|
上述写法等同于以下写法(ES2015 的 参数解构):
1 2 3 4 5
| actions: { increment({commit}) { commit('increment') } }
|
Action
函数接受一个与store
实例具有相同方法和属性的context
对象,因此可以调用context.commit
提交mutation
,或者通过context.state
和context.getters
来获取state
和getters
context
对象并不是store
实例本身
Action
通过store.dispatch
方法触发:
store.dispatch('increment')
修改HelloWorld.vue
中的mouseover
函数:
1 2 3
| onmouseover() { this.$store.dispatch('increment') }
|
不同于mutation
,我们可以在Action
中执行异步操作:
1 2 3 4 5
| increment(context) { setTimeout(() => { context.commit('increment') }, 1000) }
|
Actions
支持同样的载荷方式和对象方式进行分发:
1 2 3 4 5 6 7 8 9 10
| store.dispatch('increment', { amount: 10 })
store.dispatch({ type: 'increment', amount: 10 })
|
mapActions
辅助函数
修改HelloWorld.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import { mapGetters, mapMutations, mapActions } from 'vuex' export default { name: "HelloWorld", computed: mapGetters({ msg: 'getMsg', name: 'getName', count: 'getCount' }), methods: { onmouseover() { this.increment() }, ...mapActions(['increment']), ...mapActions({ add: 'increment' }) } };
|
Action
组合
Module