# 全局数据管理

全局状态管理(也叫全局数据管理)的好处是什么?

解耦:将所有数据相关的逻辑放入 store(也就是 MVC 中的 Model,换了个名字而已)
数据读写更方便:任何组件不管在哪里,都可以直接读写数据
控制力更强:组件对数据的读写只能使用 store 提供的 API 进行(当然也不排除有猪队友直接对 tagList 和 recordList 进行 push 等操作,这是没有办法禁止的)

重新封装 recordListModel

const recordListModel = {
  data: [] as RecordItem[],
  fetch(){
    this.data = JSON.parse(window.localStorage.getItem(localStorageKeyName) || '[]') as RecordItem[];
    return this.data;
  },
  save(){
    window.localStorage.setItem(localStorageKeyName,JSON.stringify(this.data));
  }
}

封装clone

function clone(data: any) {
  return JSON.parse(JSON.stringify(data));
}
export default clone;
//引用
import clone from '@/lib/clone';
const recordListModel = {
  create(record: RecordItem){
    const record2: RecordItem = clone(record);
    record2.createdAt = new Date();
    this.data.push(record2);
  }
}

解决Labels和 Money 标签不一致bug,使用同一对象即可解决

window.tagList = tagListModel.fetch();

报错 Property taglist does not exist on window

// 解决措施: custom.d.ts 添加属性
interface Window {
  tagList: Tag[]
}

//Labels.vue
  tags = window.tagList;
//Money.vue
  tags = window.tagList;

封装 window.createTag

interface window{
  createTag:(name: string) => void
}
// main.ts
window.createTag = (name: string) => {
  const message = tagListModel.create(name);
  if (message === 'duplicated') {
    window.alert('标签名重复了');
  } else if (message === 'success') {
    window.alert('添加成功');
  }
};
//Labels.vue
createTag(){
  window.createTag(name);
}

封装 window.removeTag

interface window{
  removeTag:(id: string) => boolean;
}
// main.ts
window.removeTag = (id: string) => {
  return tagListModel.remove(id);
};
//EditLabel.vue
remove(){
  if(this.tag){
    if(window.removeTag(this.tag.id)){
      this.$router.back();
    }else{
      window.alert('删除失败');
    } 
  }
}

封装 window.updateTag

interface window{
    updateTag:(id: string,name: string) => 'success' | 'not found' | 'duplicated';
}
//main.ts
window.updateTag = (id: string, name: string) => {
  return tagListModel.update(id, name);
};
//EditLabel.vue
update(name: string){
  if(this.tag){
    window.updateTag(this.tag.id,name);
  }
}

封装 window.findTag

interface window{
  findTag:(id: string) => Tag | undefined;
}
//main.ts
window.findTag = (id: string) => {
  return window.tagList.filter(t => t.id === id)[0];
};
//EditLabel.vue
this.tag = window.findTag(this.$route.params.id);

封装 record

interface Window {
  recordList: RecordItem[];
  createRecord:(record:RecordItem) => void;
}
// main.ts
window.recordList = recordListModel.fetch();
window.createRecord = (record: RecordItem)=> recordListModel.create(record);

数据封装在 store (全局属性过多严重依赖 window)

import recordStore from '@/store/recordStore';
import tagStore from '@/store/tagStore';

const store = {
  ...recordStore,
  ...tagStore
};
console.log(store);

export default store;
//recordStore   
const localStorageKeyName = 'recordList';
const recordStore = {
  recordList: [] as RecordItem[],
  fetchRecords(){},
  saveRecords(){},
  createRecord(record: RecordItem){},
};
recordStore.fetchRecords();
export default recordStore;
//tagStore
const localStorageKeyName = 'tagList';
const tagStore ={
  tagList: [] as Tag[],
  fetchTags(){},
  findTag(id: string){},
  createTag(name: string){},
  removeTag(id: string){},
  updateTag(id: string, name: string){},
  saveTags(){}
};
tagStore.fetchTags();
export default tagStore;