You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
7.7 KiB

  1. <template>
  2. <div class="flex h-screen">
  3. <SideBar />
  4. <div class="flex-1 p-4 overflow-auto">
  5. <el-card>
  6. <template #header>
  7. <div class="flex justify-between items-center">
  8. <span>用户列表</span>
  9. <el-button type="primary" @click="handleCreateUser">新增用户</el-button>
  10. </div>
  11. </template>
  12. <el-form :inline="true" :model="searchForm" class="mb-4">
  13. <el-form-item label="用户名">
  14. <el-input v-model="searchForm.username" placeholder="请输入用户名" clearable></el-input>
  15. </el-form-item>
  16. <el-form-item label="状态">
  17. <el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
  18. <el-option label="启用" value="active"></el-option>
  19. <el-option label="禁用" value="inactive"></el-option>
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item>
  23. <el-button type="primary" @click="handleSearch">搜索</el-button>
  24. <el-button @click="resetSearch">重置</el-button>
  25. </el-form-item>
  26. </el-form>
  27. <el-table :data="tableData" stripe style="width: 100%">
  28. <el-table-column type="selection" width="55"></el-table-column>
  29. <el-table-column prop="id" label="ID" width="100"></el-table-column>
  30. <el-table-column prop="username" label="用户名" width="120"></el-table-column>
  31. <el-table-column prop="name" label="姓名" width="120"></el-table-column>
  32. <el-table-column prop="gender" label="性别" width="80">
  33. <template #default="scope">
  34. <el-tag :type="scope.row.gender === '男' ? 'primary' : 'success'">
  35. {{ scope.row.gender }}
  36. </el-tag>
  37. </template>
  38. </el-table-column>
  39. <el-table-column prop="age" label="年龄" width="80"></el-table-column>
  40. <el-table-column prop="email" label="邮箱"></el-table-column>
  41. <el-table-column prop="status" label="状态" width="100">
  42. <template #default="scope">
  43. <el-switch
  44. v-model="scope.row.status"
  45. active-text="启用"
  46. inactive-text="禁用"
  47. @change="handleStatusChange(scope.row)"
  48. ></el-switch>
  49. </template>
  50. </el-table-column>
  51. <el-table-column label="操作" width="160">
  52. <template #default="scope">
  53. <el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button>
  54. <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
  55. </template>
  56. </el-table-column>
  57. </el-table>
  58. <el-pagination
  59. class="mt-4 flex justify-center"
  60. @size-change="handleSizeChange"
  61. @current-change="handleCurrentChange"
  62. :current-page="currentPage"
  63. :page-sizes="[10, 20, 30, 50]"
  64. :page-size="pageSize"
  65. layout="total, sizes, prev, pager, next, jumper"
  66. :total="total"
  67. ></el-pagination>
  68. </el-card>
  69. </div>
  70. </div>
  71. </template>
  72. <script setup>
  73. import { ref, reactive, toRefs } from 'vue'
  74. import SideBar from '../components/SideBar.vue'
  75. // 搜索表单
  76. const searchForm = reactive({
  77. username: '',
  78. status: ''
  79. })
  80. // 表格数据
  81. const tableData = ref([
  82. { id: 1, username: 'user1', name: '张三', gender: '男', age: 20, email: 'zhangsan@example.com', status: true },
  83. { id: 2, username: 'user2', name: '李四', gender: '女', age: 24, email: 'lisi@example.com', status: true },
  84. { id: 3, username: 'user3', name: '王五', gender: '男', age: 30, email: 'wangwu@example.com', status: false },
  85. { id: 4, username: 'user4', name: '赵六', gender: '女', age: 22, email: 'zhaoliu@example.com', status: true },
  86. { id: 5, username: 'user5', name: '钱七', gender: '男', age: 28, email: 'qianqi@example.com', status: true },
  87. { id: 6, username: 'user6', name: '孙八', gender: '女', age: 25, email: 'sunba@example.com', status: false },
  88. { id: 7, username: 'user7', name: '周九', gender: '男', age: 32, email: 'zhoujiu@example.com', status: true },
  89. { id: 8, username: 'user8', name: '吴十', gender: '女', age: 27, email: 'wushi@example.com', status: true },
  90. ])
  91. // 分页
  92. const currentPage = ref(1)
  93. const pageSize = ref(10)
  94. const total = ref(100)
  95. // 对话框
  96. const dialogVisible = ref(false)
  97. const dialogTitle = ref('')
  98. const editForm = reactive({
  99. id: null,
  100. username: '',
  101. name: '',
  102. gender: '男',
  103. age: 0,
  104. email: '',
  105. status: true
  106. })
  107. // 表单验证规则
  108. const rules = reactive({
  109. username: [
  110. { required: true, message: '请输入用户名', trigger: 'blur' },
  111. { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
  112. ],
  113. name: [
  114. { required: true, message: '请输入姓名', trigger: 'blur' }
  115. ],
  116. email: [
  117. { required: true, message: '请输入邮箱', trigger: 'blur' },
  118. { type: 'email', message: '请输入正确的邮箱格式', trigger: ['blur', 'change'] }
  119. ]
  120. })
  121. // 表单引用
  122. const editFormRef = ref(null)
  123. // 搜索方法
  124. const handleSearch = () => {
  125. console.log('搜索条件:', searchForm)
  126. // 这里可以添加搜索逻辑
  127. }
  128. const resetSearch = () => {
  129. searchForm.username = ''
  130. searchForm.status = ''
  131. }
  132. // 表格操作
  133. const handleEdit = (row) => {
  134. // 复制数据到编辑表单
  135. Object.assign(editForm, row)
  136. dialogTitle.value = '编辑用户'
  137. dialogVisible.value = true
  138. }
  139. const handleDelete = (row) => {
  140. elMessageBox.confirm(
  141. '确定要删除该用户吗?',
  142. '提示',
  143. {
  144. confirmButtonText: '确定',
  145. cancelButtonText: '取消',
  146. type: 'warning'
  147. }
  148. ).then(() => {
  149. // 从表格数据中删除
  150. const index = tableData.value.findIndex(item => item.id === row.id)
  151. if (index !== -1) {
  152. tableData.value.splice(index, 1)
  153. elMessage({
  154. type: 'success',
  155. message: '删除成功!'
  156. })
  157. }
  158. }).catch(() => {
  159. elMessage({
  160. type: 'info',
  161. message: '已取消删除'
  162. })
  163. })
  164. }
  165. const handleStatusChange = (row) => {
  166. const statusText = row.status ? '启用' : '禁用'
  167. elMessage({
  168. type: 'success',
  169. message: `用户 ${row.username}${statusText}`
  170. })
  171. }
  172. // 分页事件处理
  173. const handleSizeChange = (newSize) => {
  174. pageSize.value = newSize
  175. console.log('每页条数:', newSize)
  176. }
  177. const handleCurrentChange = (newPage) => {
  178. currentPage.value = newPage
  179. console.log('当前页码:', newPage)
  180. }
  181. // 创建用户
  182. const handleCreateUser = () => {
  183. // 清空表单
  184. Object.keys(editForm).forEach(key => {
  185. if (key === 'id') {
  186. editForm[key] = null
  187. } else if (key === 'status') {
  188. editForm[key] = true
  189. } else if (key === 'gender') {
  190. editForm[key] = '男'
  191. } else {
  192. editForm[key] = ''
  193. }
  194. })
  195. dialogTitle.value = '新增用户'
  196. dialogVisible.value = true
  197. }
  198. // 保存用户
  199. const saveUser = () => {
  200. editFormRef.value.validate((valid) => {
  201. if (valid) {
  202. // 模拟保存操作
  203. setTimeout(() => {
  204. dialogVisible.value = false
  205. elMessage({
  206. type: 'success',
  207. message: dialogTitle.value === '新增用户' ? '创建成功!' : '更新成功!'
  208. })
  209. // 更新表格数据
  210. if (editForm.id) {
  211. // 更新现有用户
  212. const index = tableData.value.findIndex(item => item.id === editForm.id)
  213. if (index !== -1) {
  214. tableData.value.splice(index, 1, { ...editForm })
  215. }
  216. } else {
  217. // 创建新用户
  218. const newId = Math.max(...tableData.value.map(item => item.id)) + 1
  219. tableData.value.unshift({ ...editForm, id: newId })
  220. }
  221. }, 500)
  222. } else {
  223. console.log('验证失败')
  224. return false
  225. }
  226. })
  227. }
  228. </script>