[TOC]
初识Vuex
官方文档:https://vuex.vuejs.org/zh/guide/
vue-cli创建项目时,默认安装了store
在store/index.ts文件中,变量声明在state中(相当于data),方法声明在mutations中(相当于methods)
在mutations中不能传this, 得用state
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state,n){
state.count += n
}
},
actions: {
},
modules: {
}
})
在组件中使用store的数据需要用computed属性
调用mutations中的方法,需要用store.commit(‘方法名’, 参数)
@Component({
components: {Tags, FormItem, Types, NumberPad},
computed:{
count(){
return store.state.count
}
}
})
export default class Money extends Vue {
addCount(){
store.commit('increment', 5)
}
}
vue从根组件向所有组件注入了store, 在组件的任何地方都可以使用this.$store访问store
注意在template不能用this
<template>
{{count}}
<button @click="$store.commit('increment', 5)">+5</button>
</template>
<script>
@Component({
components: {Tags, FormItem, Types, NumberPad},
computed:{
count(){
return this.$store.state.count
}
}
})
</script>
在Money.vue中使用vuex
删掉store/index2
如果涉及到改动的地方太多,可以先添加注释 // TODO, 等回过头再来修改
将recordStore整合进store
import Vue from 'vue'
import Vuex from 'vuex'
import clone from '@/lib/clone';
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
recordList: [] as RecordItem[],
},
mutations: {
fetchRecords(state){
state.recordList = JSON.parse(window.localStorage.getItem('recordList') || '[]') as RecordItem[];
},
createRecord (state, record: RecordItem){
const record2: RecordItem = clone(record);
record2.createAt = new Date();
state.recordList.push(record2);
store.commit('saveRecords')
},
saveRecords(state) {
window.localStorage.setItem('recordList', JSON.stringify(state.recordList));
}
},
actions: {
},
modules: {
}
})
export default store
在TS中使用mixin
如果不同的组件中有相同的代码,可以使用mixin, mixin的本质是一个对象
参考文档:https://class-component.vuejs.org/guide/extend-and-mixins.html#mixins
新建mixins/tagHelper.ts
// mixins.js
import Vue from 'vue'
import Component from 'vue-class-component'
// You can declare mixins as the same style as components.
@Component
export class tagHelper extends Vue {
createTag(){
const name = window.prompt('请输入标签名');
if (!name) {
return window.alert('标签名不可为空')
}
this.$store.commit('createTag', name)
}
}
在组件中使用mixin只需要将extends Vue 改为 extends mixins(tagHelper)
<script lang="ts">
import Vue from 'vue';
import {Component} from 'vue-property-decorator';
import Button from '@/components/Button.vue';
import {mixins} from 'vue-class-component';
import {tagHelper} from '@/mixins/tagHelper';
@Component({
components: {Button},
computed: {
tags() {
return this.$store.state.tagList
}
}
})
export default class Labels extends mixins(tagHelper) {
created() {
this.$store.commit('fetchTags')
}
}
</script>
重构EditLabel.vue
vuex的mutations中的方法是不能有返回值的, commit的返回值类型是void
注意在对象中的对象的类型声明用as
import Vue from 'vue'
import Vuex from 'vuex'
import clone from '@/lib/clone';
import createId from '@/lib/idCreator';
Vue.use(Vuex)
type RootState = {
recordList: RecordItem[],
tagList: Tag[],
currentTag?: Tag
}
const store = new Vuex.Store({
state: {
recordList: [],
tagList: [],
currentTag: undefined
} as RootState,
mutations: {
// ...
setCurrentTag(state, id:string) {
state.currentTag = state.tagList.find(t => t.id === id)
},
},
})
export default store
TS中的computed使用getter/setter语法
如果在@Component中使用computed,发现在