shop-wx/doc/examples/store-example.ts

434 lines
9.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 状态管理示例代码Pinia Store
* 展示项目中状态管理的编写规范和最佳实践
*/
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { getUserList, createUser, updateUser, deleteUser, type User, type UserParams } from '@/api/user';
/**
* 用户管理 Store
* 使用 Composition API 风格定义 Store
*/
export const useUserStore = defineStore('user', () => {
/**
* 状态定义(使用 ref
*/
// 用户列表
const userList = ref<User[]>([]);
// 当前用户
const currentUser = ref<User | null>(null);
// 加载状态
const loading = ref(false);
// 搜索关键词
const searchKeyword = ref('');
// 分页信息
const pagination = ref({
current: 1,
size: 10,
total: 0,
});
// 选中的用户ID列表
const selectedUserIds = ref<number[]>([]);
// 错误信息
const error = ref<string | null>(null);
/**
* 计算属性
*/
// 是否全选
const isAllSelected = computed(() => {
return userList.value.length > 0 && selectedUserIds.value.length === userList.value.length;
});
// 是否部分选中
const isIndeterminate = computed(() => {
return selectedUserIds.value.length > 0 && selectedUserIds.value.length < userList.value.length;
});
// 选中的用户列表
const selectedUsers = computed(() => {
return userList.value.filter(user => selectedUserIds.value.includes(user.id));
});
// 正常状态用户数
const activeUserCount = computed(() => {
return userList.value.filter(user => user.status === 0).length;
});
// 禁用状态用户数
const inactiveUserCount = computed(() => {
return userList.value.filter(user => user.status === 1).length;
});
/**
* 异步操作Actions
*/
// ✅ 获取用户列表
/**
* 获取用户列表
* @param params 搜索参数
*/
const fetchUserList = async (params?: UserParams) => {
loading.value = true;
error.value = null;
try {
const result = await getUserList(params);
userList.value = result.data;
pagination.value = {
current: result.page,
size: result.size,
total: result.total,
};
// 清空选中状态
selectedUserIds.value = [];
return result;
} catch (err: any) {
error.value = err.message || '获取用户列表失败';
console.error('获取用户列表失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 创建用户
/**
* 创建用户
* @param data 用户数据
*/
const createNewUser = async (data: any) => {
loading.value = true;
error.value = null;
try {
const newUser = await createUser(data);
// 添加到列表开头
userList.value.unshift(newUser);
return newUser;
} catch (err: any) {
error.value = err.message || '创建用户失败';
console.error('创建用户失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 更新用户
/**
* 更新用户信息
* @param data 用户数据
*/
const updateUserInfo = async (data: any) => {
loading.value = true;
error.value = null;
try {
const updatedUser = await updateUser(data);
// 更新列表中的用户
const index = userList.value.findIndex(user => user.id === data.id);
if (index !== -1) {
userList.value[index] = updatedUser;
}
return updatedUser;
} catch (err: any) {
error.value = err.message || '更新用户失败';
console.error('更新用户失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 删除用户
/**
* 删除用户
* @param id 用户ID
*/
const removeUser = async (id: number) => {
loading.value = true;
error.value = null;
try {
await deleteUser(id);
// 从列表中移除
userList.value = userList.value.filter(user => user.id !== id);
// 移除选中状态
selectedUserIds.value = selectedUserIds.value.filter(userId => userId !== id);
} catch (err: any) {
error.value = err.message || '删除用户失败';
console.error('删除用户失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 批量删除用户
/**
* 批量删除用户
* @param ids 用户ID列表
*/
const batchRemoveUsers = async (ids: number[]) => {
loading.value = true;
error.value = null;
try {
// 这里应该调用批量删除 API
// await batchDeleteUsers(ids);
// 模拟批量删除
for (const id of ids) {
await deleteUser(id);
}
// 从列表中移除
userList.value = userList.value.filter(user => !ids.includes(user.id));
// 清空选中状态
selectedUserIds.value = [];
} catch (err: any) {
error.value = err.message || '批量删除失败';
console.error('批量删除失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 切换用户状态
/**
* 切换用户状态
* @param id 用户ID
*/
const toggleUserStatus = async (id: number) => {
const user = userList.value.find(u => u.id === id);
if (!user) return;
const newStatus = user.status === 0 ? 1 : 0;
try {
await updateUser({ id, status: newStatus });
// 更新本地状态
user.status = newStatus;
} catch (err: any) {
error.value = err.message || '状态切换失败';
console.error('状态切换失败:', err);
throw err;
}
};
// ✅ 刷新用户列表
/**
* 刷新用户列表(使用当前搜索条件)
*/
const refreshUserList = () => {
return fetchUserList({
keyword: searchKeyword.value,
page: pagination.value.current,
size: pagination.value.size,
});
};
/**
* 同步操作Actions
*/
// ✅ 设置当前用户
/**
* 设置当前用户
* @param user 用户信息
*/
const setCurrentUser = (user: User | null) => {
currentUser.value = user;
};
// ✅ 设置搜索关键词
/**
* 设置搜索关键词
* @param keyword 关键词
*/
const setSearchKeyword = (keyword: string) => {
searchKeyword.value = keyword;
};
// ✅ 设置分页
/**
* 设置分页信息
* @param page 页码
* @param size 每页数量
*/
const setPagination = (page: number, size?: number) => {
pagination.value.current = page;
if (size) {
pagination.value.size = size;
}
};
// ✅ 全选/取消全选
/**
* 切换全选状态
*/
const toggleSelectAll = () => {
if (isAllSelected.value) {
selectedUserIds.value = [];
} else {
selectedUserIds.value = userList.value.map(user => user.id);
}
};
// ✅ 选择/取消选择用户
/**
* 切换用户选择状态
* @param userId 用户ID
*/
const toggleUserSelection = (userId: number) => {
const index = selectedUserIds.value.indexOf(userId);
if (index === -1) {
selectedUserIds.value.push(userId);
} else {
selectedUserIds.value.splice(index, 1);
}
};
// ✅ 清空选中状态
/**
* 清空所有选中状态
*/
const clearSelection = () => {
selectedUserIds.value = [];
};
// ✅ 清空错误信息
/**
* 清空错误信息
*/
const clearError = () => {
error.value = null;
};
// ✅ 重置状态
/**
* 重置 Store 状态
*/
const resetState = () => {
userList.value = [];
currentUser.value = null;
selectedUserIds.value = [];
searchKeyword.value = '';
pagination.value = {
current: 1,
size: 10,
total: 0,
};
error.value = null;
loading.value = false;
};
/**
* 返回状态和方法
*/
return {
// 状态
userList,
currentUser,
loading,
searchKeyword,
pagination,
selectedUserIds,
error,
// 计算属性
isAllSelected,
isIndeterminate,
selectedUsers,
activeUserCount,
inactiveUserCount,
// 异步操作
fetchUserList,
createNewUser,
updateUserInfo,
removeUser,
batchRemoveUsers,
toggleUserStatus,
refreshUserList,
// 同步操作
setCurrentUser,
setSearchKeyword,
setPagination,
toggleSelectAll,
toggleUserSelection,
clearSelection,
clearError,
resetState,
};
});
/**
* 其他 Store 示例
*/
// ✅ 主题管理 Store
export const useThemeStore = defineStore('theme', () => {
const theme = ref<'light' | 'dark'>('light');
const primaryColor = ref('#4a90ff');
const setTheme = (newTheme: 'light' | 'dark') => {
theme.value = newTheme;
};
const setPrimaryColor = (color: string) => {
primaryColor.value = color;
};
return {
theme,
primaryColor,
setTheme,
setPrimaryColor,
};
});
// ✅ 购物车 Store参考现有项目
export const useCartStore = defineStore('cart', () => {
const items = ref<any[]>([]);
const total = ref(0);
const addItem = (product: any) => {
// 添加商品到购物车逻辑
items.value.push(product);
calculateTotal();
};
const removeItem = (productId: string) => {
items.value = items.value.filter(item => item.id !== productId);
calculateTotal();
};
const calculateTotal = () => {
total.value = items.value.reduce((sum, item) => sum + item.price, 0);
};
return {
items,
total,
addItem,
removeItem,
};
});