前段时间学习了下vue3 和ts ,就尝试下做了个项目,结果发现vuex和ts几乎无法结合,越写越别扭,开始怀疑用ts就是自己给自己挖坑,然后加了几个vue相关的群,去抱怨了几句,得到大佬指点:你可以不用vuex!

对,我可以不用vuex,然后尝试实现了一个自己的store ,本人虽然前端是个小白,但c#还是写了五六年,对泛型还是比较熟悉的,写完之后对ts大爱。不多说了 上代码:

 Store基类代码如下  :

base-store.ts  

 1 import BaseEntity from '@/entities/base-entity'
 2 import PageResult from '@/entities/page-result'
 3 import { readonly } from '@vue/reactivity'
 4
 5 export default abstract class BaseStore<T extends BaseEntity> {
 6   protected url = ''
 7   protected _all: T[] = []
 8   public get all() {
 9     return readonly(this._all)
10   }
11
12   protected _list: T[] = []
13   public get list() {
14     return readonly(this._list)
15   }
16
17   protected _editItem: T | undefined
18   public get editItem() {
19     return this._editItem
20   }
21   public set editItem(val: T | undefined) {
22     this._editItem = val
23   }
24
25   protected _currentPage = 1
26   public get currentPage() {
27     return this._currentPage
28   }
29   public set currentPage(val) {
30     this._currentPage = val
31   }
32
33   protected _pageSize = 30
34   public get pageSize() {
35     return this._pageSize
36   }
37   public set pageSize(val) {
38     this._pageSize = val
39   }
40
41   protected _totalCount = 0
42   public get totalCount() {
43     return this._totalCount
44   }
45
46   protected _loading = false
47   public get loading() {
48     return this._loading
49   }
50
51   async getAll() {
52     const response = await window.ajax.get(`/api/admin/${this.url}/getall`)
53     this._all = response.data
54   }
55   async get(query: any) {
56     this._loading = true
57     const response = await window.ajax.get(`/api/admin/${this.url}`, { params: query })
58     this._loading = false
59     const page = response.data as PageResult<T>
60     this._totalCount = page.totalCount
61     this._list = page.items
62   }
63   async getById(id: string | number) {
64     const response = await window.ajax.get(`/api/admin/${this.url}/${id}`)
65     return response.data
66   }
67   async create(payload: T) {
68     await window.ajax.post(`/api/admin/${this.url}`, payload)
69   }
70   async update(payload: T) {
71     await window.ajax.put(`/api/admin/${this.url}`, payload)
72   }
73   async delete(id: string | number) {
74     await window.ajax.delete(`/api/admin/${this.url}/${id}`)
75   }
76 }

上面代码中包含了 基本的curd操作 ,和数据的存储(字段属性),不能在外部读取的字段 只需要设置get就行了 ,可以读写的设置 get set

上面代码中用到了BaseEntity 和PageResult 两个类型 代码如下

base-entiy.ts

1 export default interface BaseEntity {
2   id: number | string
3   createTime: Date
4   createUserId: number
5   updateTime: Date
6   updateUserId: number
7 }

page-result.ts

export default class PageResult<T> {
  items: T[] = []
  totalCount: number = 0
}

作为子类 ,只需要继承基类就可以了 无需多余代码,比如下面的 UserStore

user-store.ts

import { reactive } from 'vue'
import User from '../entities/user'
import BaseStore from './base-store'
class UserStore<T> extends BaseStore<User> {
  url = 'user'
}

export default reactive(new UserStore())

上面只需要这几行代码就实现了完整的的user的curd  ,还包括分页等操作,代码量大大减少,同样的方法可以实现TeacherStore, StudentStore…… 

如果基类的方法不能满足业主需求,子类里面可以加入自己特定方法

导出store包裹一层reactive变成代理对象, 可以响应ui界面

实体类 User代码如下

user.ts

import BaseEntity from './base-entity'

export default interface User extends BaseEntity {
  id:number
  password: string
  name: string
  phone:string
  email:string
}

这样使用store的话就很简单了,就像下面的代码

import userStore from '@/store/user-store'

userStore.getAll()

const list=userStore.list

userStore.eidtItem=list[0]

这样的好处就是全部都是强类型,写代码的时候有智能提示,书写错误编译不通过!不像之前vuex,写起来太难了

像一般后台管理网站,最基本就是 一个列表页面 一个新增对话框 一个修改对话框 ,这样我们还可以进一步去抽象, 提取公共的方法、字段,进一步去减少代码量。比如实现 ListViewModel<T>  CreateViewModel<T>  EditViewModel<T>   这里就不再写了

04-27 18:48