不是我想偷懒,是easy-model真的太省代码了
事情是这样的
最近用Cursor做了个后台管理系统,大概80多个页面。
同事刷了一眼我的代码:"你怎么写了这么少?是不是没写完?"
我:"写完了啊。"
同事:"不可能,之前用Redux,光状态管理代码就几百行,你这才哪到哪?"
我:"因为用了easy-model。"
以前用Redux是怎么写的
// 1. action-types.ts
export const SET_USER = "user/SET_USER";
export const SET_LOADING = "user/SET_LOADING";
export const SET_ERROR = "user/SET_ERROR";
export const FETCH_USER = "user/FETCH_USER";
// 2. actions.ts
export const setUser = (user: User) => ({ type: SET_USER, payload: user });
export const setLoading = (loading: boolean) => ({
type: SET_LOADING,
payload: loading,
});
export const setError = (error: string) => ({
type: SET_ERROR,
payload: error,
});
export const fetchUser = (id: string) => ({ type: FETCH_USER, payload: id });
// 3. reducer.ts
const initialState = { user: null, loading: false, error: null };
export const userReducer = (state = initialState, action: AnyAction) => {
switch (action.type) {
case SET_USER:
return { ...state, user: action.payload };
case SET_LOADING:
return { ...state, loading: action.payload };
case SET_ERROR:
return { ...state, error: action.payload };
default:
return state;
}
};
// 4. selectors.ts
export const selectUser = (state: RootState) => state.user.data;
export const selectLoading = (state: RootState) => state.user.loading;
export const selectError = (state: RootState) => state.user.error;
// 5. 组件里用
const user = useSelector(selectUser);
const loading = useSelector(selectLoading);
const dispatch = useDispatch();
dispatch(fetchUser(id));
一个用户模块,将近200行代码。
而且这还是简单的,复杂点的业务光action type就能写50个。
用Cursor + easy-model怎么写
// 1. 定义Model,一个类搞定
class UserModel {
user: User | null = null;
@loader.load()
async fetchUser(id: string) {
this.error = null;
this.user = await api.getUser(id);
}
}
// 2. 组件里用
function UserPage() {
const userModel = useModel(UserModel, []);
const { isLoading } = useLoader()
return (
<div>
{isLoading(userModel.fetchUser) && <Spinner />}
{userModel.user?.name}
</div>
);
}
一个用户模块,30行代码。
而且Cursor理解这种代码毫无压力,直接就能生成。
为什么Cursor能理解easy-model?
1. 类模型是AI最熟悉的模式
class UserModel {
// 字段 = 状态
name = "";
// 方法 = 操作
updateName(name: string) {
this.name = name;
}
}
这不就是最普通的OOP吗?AI从小学的就是这个。
2. 模板化,AI直接套用
// CRUD模板
class CRUDModel {
items: Item[] = [];
loading = false;
@loader.load()
async fetchAll() {
/* ... */
}
@loader.load()
async create(item: Item) {
/* ... */
}
async update(id: number, item: Item) {
/* ... */
}
delete(id: number) {
this.items = this.items.filter((i) => i.id !== id);
}
}
// 表单模板
class FormModel {
data = { name: "", email: "" };
errors: Record<string, string> = {};
setField(field: string, value: string) {
(this.data as any)[field] = value;
}
validate() {
/* ... */
}
}
// 分页模板
class ListModel {
items: Item[] = [];
pagination = { page: 1, size: 20, total: 0 };
@loader.load()
async fetch() {
/* ... */
}
}
Cursor看到这些模板就知道怎么写了。
3. 依赖注入,AI知道找谁
const apiSchema = object({ baseUrl: string() }).describe("API配置");
class UserApi {
@inject(apiSchema)
config?: { baseUrl: string };
async getUser(id: string) {
return fetch(`${this.config?.baseUrl}/users/${id}`);
}
}
AI知道这个类需要API配置,不会乱写。
4. 撤销重做,AI调试也方便
const history = useModelHistory(model);
history.back(); // 撤销
history.forward(); // 重做
同事的反应
同事看完沉默了几秒,然后说:
"这个库在哪?给我也整一个。"
GitHub: github.com/ZYF93/easy-…
npm: pnpm add @e7w/easy-model
点个⭐️,支持一下!