当前位置:   article > 正文

教程11 Vue3 + Django前后端分离项目——Element Plus Table 表格(数据增、删、改、除、分页)_vue3+django

vue3+django

目录

一、查询公告信息表中的数据,并绑定到表格中

1. 后端接口(http://127.0.0.1:8000/notices) 

2. utils/api.ts中增加如下函数,用于调用后端接口查询所有公告信息

3. views文件夹中新建一个NoticesManagement.vue文件

二、实现分页

1. 后端接口(http://127.0.0.1:8000/notices/1/2) 

2. utils/api.ts中增加函数,用于调用后端接口根据页码查询公告信息

3.  修改NoticesManagement.vue文件

三、删除

1. 后端接口(http://127.0.0.1:8000/delete_notice/1) 

2. utils/api.ts中增加函数,用于调用后端接口根据公告id删除公告信息

3.  修改NoticesManagement.vue文件

四、新增公告 

1. 后端接口(http://127.0.0.1:8000/add_notice) 

2. utils/api.ts中增加函数,用于调用后端接口增加公告信息

3.  修改NoticesManagement.vue文件

五、编辑公告 

1. 后端接口(http://127.0.0.1:8000/edit_notice/) 

2. utils/api.ts中增加函数,用于调用后端接口编辑公告信息

3.  修改NoticesManagement.vue文件

六、筛选公告

​编辑​1.  修改NoticesManagement.vue文件

七、多选

1.  修改NoticesManagement.vue文件

八、全选、清除、批量删除 

1.  修改NoticesManagement.vue文件

九、Excel导入导出

1. Excel导入

2. Excel导出

3. 安装依赖包

4.  Excel模板template.xlsx放入public文件夹中

5.   修改NoticesManagement.vue文件


一、查询公告信息表中的数据,并绑定到表格中

1. 后端接口(http://127.0.0.1:8000/notices) 

2. utils/api.ts中增加如下函数,用于调用后端接口查询所有公告信息

  1. // 获得所有公告信息
  2. export function getAllNoticesUrl() {
  3. return request({
  4. url: 'api/notices/',
  5. method: 'get',
  6. })
  7. }

3. views文件夹中新建一个NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-table ref="tableNoticeRef" :data="tableDataNotices" style="width: 100%">
  4. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  5. <el-table-column prop="title" label="标题" width="380">
  6. <template #default="scope" width="300">
  7. <span>{{ scope.row.title }}</span>
  8. </template>
  9. </el-table-column>
  10. <el-table-column prop="user" label="发布人姓名" width="100">
  11. <template #default="scope" width="180">
  12. <span>{{ scope.row.user }}</span>
  13. </template>
  14. </el-table-column>
  15. <el-table-column prop="content" label="内容" width="280">
  16. <template #default="scope" width="180">
  17. <span>{{ scope.row.content }}</span>
  18. </template>
  19. </el-table-column>
  20. </el-table>
  21. </template>
  22. <script setup lang="ts">
  23. import { ref, onMounted } from "vue";
  24. import { getAllNoticesUrl } from "../utils/api";
  25. // 声明一个公告类型的接口
  26. interface Notice {
  27. id: number; // 公告编号
  28. title: string; // 公告标题
  29. content: string; // 公告内容
  30. add_time: string; // 发布时间
  31. user_id: number; // 用户编号
  32. user: string; // 用户信息
  33. }
  34. // 公告数据
  35. var tableDataNotices = ref<Notice[]>([]);
  36. // 查询所有的公告并绑定到表格中
  37. const getAllNoticesData = () => {
  38. getAllNoticesUrl().then((res: any) => {
  39. console.log(res);
  40. tableDataNotices.value = res.data;
  41. });
  42. };
  43. // 页面加载后查询所有公告数据
  44. onMounted(() => {
  45. getAllNoticesData();
  46. });
  47. </script>

二、实现分页

1. 后端接口(http://127.0.0.1:8000/notices/1/2/) 

2. utils/api.ts中增加函数,用于调用后端接口根据页码查询公告信息

  1. // 分页
  2. export function getNoticesByPageUrl(params: any) {
  3. return request({
  4. url: 'api/notices/' + Number(params['currentPage']) + '/' + Number(params['pageSize']) + '/',
  5. method: 'get',
  6. })
  7. }

3.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-table ref="tableNoticeRef" :data="tableDataNotices" style="width: 100%">
  4. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  5. <el-table-column prop="title" label="标题" width="380">
  6. <template #default="scope" width="300">
  7. <span>{{ scope.row.title }}</span>
  8. </template>
  9. </el-table-column>
  10. <el-table-column prop="user" label="发布人姓名" width="100">
  11. <template #default="scope" width="180">
  12. <span>{{ scope.row.user }}</span>
  13. </template>
  14. </el-table-column>
  15. <el-table-column prop="content" label="内容" width="280">
  16. <template #default="scope" width="180">
  17. <span>{{ scope.row.content }}</span>
  18. </template>
  19. </el-table-column>
  20. </el-table>
  21. <!-- 分页组件 -->
  22. <el-pagination
  23. @size-change="handleSizeChange"
  24. @current-change="handleCurrentChange"
  25. :current-page="currentPage"
  26. :page-sizes="pageSizes"
  27. :page-size="pageSize"
  28. layout="total, sizes, prev, pager, next, jumper"
  29. :total="total"
  30. >
  31. </el-pagination>
  32. </template>
  33. <script setup lang="ts">
  34. import { ref, onMounted } from "vue";
  35. import { getAllNoticesUrl, getNoticesByPageUrl } from "../utils/api";
  36. // 声明一个公告类型的接口
  37. interface Notice {
  38. id: number; // 公告编号
  39. title: string; // 公告标题
  40. content: string; // 公告内容
  41. add_time: string; // 发布时间
  42. user_id: number; // 用户编号
  43. user: string; // 用户信息
  44. }
  45. // 公告数据
  46. var tableDataNotices = ref<Notice[]>([]);
  47. // 查询所有的公告并绑定到表格中
  48. // const getAllNoticesData = () => {
  49. // getAllNoticesUrl().then((res: any) => {
  50. // console.log(res);
  51. // tableDataNotices.value = res.data;
  52. // let total = tableDataNotices.value.length; // 修改总页数
  53. // });
  54. // };
  55. // 查询所有的公告并绑定到表格中(分页)
  56. const getAllNoticesData = () => {
  57. let params = {
  58. currentPage: currentPage.value,
  59. pageSize: pageSize.value,
  60. };
  61. getNoticesByPageUrl(params).then((res: any) => {
  62. console.log(res);
  63. tableDataNotices.value = res.data;
  64. total.value = res.total; // 修改总页数
  65. });
  66. };
  67. // 页面加载后查询所有公告数据
  68. onMounted(() => {
  69. getAllNoticesData();
  70. });
  71. // 分页
  72. const pageSizes = [5, 10, 15, 20, 50, 100];
  73. const pageSize = ref(5); // 每页记录条数
  74. const currentPage = ref(1); // 当前页的索引
  75. const small = ref(false);
  76. const background = ref(false);
  77. const disabled = ref(false);
  78. const total = ref(0); // 总页数
  79. // 分页
  80. const handleSizeChange = (val: number) => {
  81. console.log("${val} items per page");
  82. pageSize.value = val;
  83. getAllNoticesData();
  84. };
  85. const handleCurrentChange = (val: number) => {
  86. console.log("current page: ${val}");
  87. currentPage.value = val;
  88. getAllNoticesData();
  89. };
  90. </script>

三、删除

1. 后端接口(http://127.0.0.1:8000/delete_notice/1) 

2. utils/api.ts中增加函数,用于调用后端接口根据公告id删除公告信息

  1. // 删除公告
  2. export function deleteNoticeUrl(params:any) {
  3. return request({
  4. url: 'api/delete_notice/' + params + "/",
  5. method: 'delete',
  6. })
  7. }

3.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-table ref="tableNoticeRef" :data="tableDataNotices" style="width: 100%">
  4. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  5. <el-table-column prop="title" label="标题" width="380">
  6. <template #default="scope" width="300">
  7. <span>{{ scope.row.title }}</span>
  8. </template>
  9. </el-table-column>
  10. <el-table-column prop="user" label="发布人姓名" width="100">
  11. <template #default="scope" width="180">
  12. <span>{{ scope.row.user }}</span>
  13. </template>
  14. </el-table-column>
  15. <el-table-column prop="content" label="内容" width="280">
  16. <template #default="scope" width="180">
  17. <span>{{ scope.row.content }}</span>
  18. </template>
  19. </el-table-column>
  20. <el-table-column label="操作" width="300">
  21. <template #default="scope">
  22. <div>
  23. <el-popconfirm confirm-button-text="是" cancel-button-text="否" title="您确定删除吗?"
  24. icon-color="#626AEF" @confirm="handleDelete(scope.row)">
  25. <template #reference>
  26. <el-button>删除</el-button>
  27. </template>
  28. </el-popconfirm>
  29. </div>
  30. </template>
  31. </el-table-column>
  32. </el-table>
  33. <!-- 分页组件 -->
  34. <el-pagination
  35. @size-change="handleSizeChange"
  36. @current-change="handleCurrentChange"
  37. :current-page="currentPage"
  38. :page-sizes="pageSizes"
  39. :page-size="pageSize"
  40. layout="total, sizes, prev, pager, next, jumper"
  41. :total="total"
  42. >
  43. </el-pagination>
  44. </template>
  45. <script setup lang="ts">
  46. import { ref, onMounted } from "vue";
  47. import { getAllNoticesUrl, getNoticesByPageUrl, deleteNoticeUrl } from "../utils/api";
  48. // 声明一个公告类型的接口
  49. interface Notice {
  50. id: number; // 公告编号
  51. title: string; // 公告标题
  52. content: string; // 公告内容
  53. add_time: string; // 发布时间
  54. user_id: number; // 用户编号
  55. user: string; // 用户信息
  56. }
  57. // 公告数据
  58. var tableDataNotices = ref<Notice[]>([]);
  59. // 查询所有的公告并绑定到表格中
  60. // const getAllNoticesData = () => {
  61. // getAllNoticesUrl().then((res: any) => {
  62. // console.log(res);
  63. // tableDataNotices.value = res.data;
  64. // let total = tableDataNotices.value.length; // 修改总页数
  65. // });
  66. // };
  67. // 查询所有的公告并绑定到表格中(分页)
  68. const getAllNoticesData = () => {
  69. let params = {
  70. currentPage: currentPage.value,
  71. pageSize: pageSize.value,
  72. };
  73. getNoticesByPageUrl(params).then((res: any) => {
  74. console.log(res);
  75. tableDataNotices.value = res.data;
  76. total.value = res.total; // 修改总页数
  77. });
  78. };
  79. // 页面加载后查询所有公告数据
  80. onMounted(() => {
  81. getAllNoticesData();
  82. });
  83. // 分页
  84. const pageSizes = [5, 10, 15, 20, 50, 100];
  85. const pageSize = ref(5); // 每页记录条数
  86. const currentPage = ref(1); // 当前页的索引
  87. const small = ref(false);
  88. const background = ref(false);
  89. const disabled = ref(false);
  90. const total = ref(0); // 总页数
  91. // 分页
  92. const handleSizeChange = (val: number) => {
  93. console.log("${val} items per page");
  94. pageSize.value = val;
  95. getAllNoticesData();
  96. };
  97. const handleCurrentChange = (val: number) => {
  98. console.log("current page: ${val}");
  99. currentPage.value = val;
  100. getAllNoticesData();
  101. };
  102. //删除
  103. const handleDelete = (row: Notice) => {
  104. let params = row.id;
  105. deleteNoticeUrl(params).then((res) => {
  106. console.log(res.data.meta);
  107. getAllNoticesData();
  108. });
  109. };
  110. /*
  111. const handleDelete = (index: number, row: Notice) => {
  112. let params = row.id;
  113. deleteNotice(params);
  114. };
  115. const deleteNotice = async (params: any) => {
  116. try {
  117. const response = await deleteNoticeUrl(params);
  118. console.log(response.data.meta);
  119. getAllNoticesData();
  120. } catch (error) {
  121. console.error(error);
  122. }
  123. };
  124. */
  125. </script>

4. 添加删除对话框

  1. <el-popconfirm
  2. confirm-button-text="是"
  3. cancel-button-text="否"
  4. :icon="InfoFilled"
  5. icon-color="#626AEF"
  6. title="您确定要删除吗?"
  7. @confirm="handleDelete(scope.$index, scope.row)"
  8. @cancel="cancelEvent"
  9. >
  10. <template #reference>
  11. <el-button>Delete</el-button>
  12. </template>
  13. </el-popconfirm>
  1. <script lang="ts" setup>
  2. ……
  3. import { InfoFilled } from '@element-plus/icons-vue'
  4. const cancelEvent = () => {
  5. console.log('cancel!')
  6. }
  7. </script>

四、新增公告 

 

1. 后端接口(http://127.0.0.1:8000/add_notice) 

  1. {
  2. "title": "会议通知",
  3. "content": "今天上午10:00,会议室开会,地点信息楼210",
  4. "user_id":"11"
  5. }

2. utils/api.ts中增加函数,用于调用后端接口增加公告信息

  1. // 新增公告
  2. export function addNoticeUrl(data:any) {
  3. return request({
  4. url: 'api/add_notice/',
  5. method: 'post',
  6. data: data,
  7. })
  8. }

3.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-row :gutter="20">
  4. <el-col :span="4">
  5. <template #default="scope">
  6. <el-button text :icon="Edit" @click="handleAdd()" v-permiss="15">
  7. 新增
  8. </el-button>
  9. </template>
  10. </el-col>
  11. </el-row>
  12. <el-table ref="tableNoticeRef" :data="tableDataNotices" style="width: 100%">
  13. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  14. <el-table-column prop="title" label="标题" width="380">
  15. <template #default="scope" width="300">
  16. <span>{{ scope.row.title }}</span>
  17. </template>
  18. </el-table-column>
  19. <el-table-column prop="user" label="发布人姓名" width="100">
  20. <template #default="scope" width="180">
  21. <span>{{ scope.row.user }}</span>
  22. </template>
  23. </el-table-column>
  24. <el-table-column prop="content" label="内容" width="280">
  25. <template #default="scope" width="180">
  26. <span>{{ scope.row.content }}</span>
  27. </template>
  28. </el-table-column>
  29. <el-table-column label="操作" width="300">
  30. <template #default="scope">
  31. <div>
  32. <el-popconfirm confirm-button-text="是" cancel-button-text="否" title="您确定删除吗?"
  33. icon-color="#626AEF" @confirm="handleDelete(scope.row)">
  34. <template #reference>
  35. <el-button>删除</el-button>
  36. </template>
  37. </el-popconfirm>
  38. </div>
  39. </template>
  40. </el-table-column>
  41. </el-table>
  42. <!-- 分页组件 -->
  43. <el-pagination
  44. @size-change="handleSizeChange"
  45. @current-change="handleCurrentChange"
  46. :current-page="currentPage"
  47. :page-sizes="pageSizes"
  48. :page-size="pageSize"
  49. layout="total, sizes, prev, pager, next, jumper"
  50. :total="total"
  51. >
  52. </el-pagination>
  53. <!-- 新增对话框 -->
  54. <el-dialog title="新增" v-model="addVisible" width="30%">
  55. <el-form label-width="70px">
  56. <el-form-item label="标题">
  57. <el-input v-model="noticeForm.title"></el-input>
  58. </el-form-item>
  59. <el-form-item label="公告">
  60. <el-input v-model="noticeForm.content"></el-input>
  61. </el-form-item>
  62. </el-form>
  63. <template #footer>
  64. <span class="dialog-footer">
  65. <el-button @click="addVisible = false">取 消</el-button>
  66. <el-button type="primary" @click="saveAdd">确 定</el-button>
  67. </span>
  68. </template>
  69. </el-dialog>
  70. </template>
  71. <script setup lang="ts">
  72. import { ref, onMounted, reactive } from "vue";
  73. import { getAllNoticesUrl, getNoticesByPageUrl, deleteNoticeUrl, addNoticeUrl } from "../utils/api";
  74. import { Delete, Edit, Search, Plus } from "@element-plus/icons-vue";
  75. // 声明一个公告类型的接口
  76. interface Notice {
  77. id: number; // 公告编号
  78. title: string; // 公告标题
  79. content: string; // 公告内容
  80. add_time: string; // 发布时间
  81. user_id: number; // 用户编号
  82. user: string; // 用户信息
  83. }
  84. // 公告数据
  85. var tableDataNotices = ref<Notice[]>([]);
  86. // 查询所有的公告并绑定到表格中
  87. // const getAllNoticesData = () => {
  88. // getAllNoticesUrl().then((res: any) => {
  89. // console.log(res);
  90. // tableDataNotices.value = res.data;
  91. // let total = tableDataNotices.value.length; // 修改总页数
  92. // });
  93. // };
  94. // 查询所有的公告并绑定到表格中(分页)
  95. const getAllNoticesData = () => {
  96. let params = {
  97. currentPage: currentPage.value,
  98. pageSize: pageSize.value,
  99. };
  100. getNoticesByPageUrl(params).then((res: any) => {
  101. console.log(res);
  102. tableDataNotices.value = res.data;
  103. total.value = res.total; // 修改总页数
  104. });
  105. };
  106. // 页面加载后查询所有公告数据
  107. onMounted(() => {
  108. getAllNoticesData();
  109. });
  110. // 分页
  111. const pageSizes = [5, 10, 15, 20, 50, 100];
  112. const pageSize = ref(5); // 每页记录条数
  113. const currentPage = ref(1); // 当前页的索引
  114. const small = ref(false);
  115. const background = ref(false);
  116. const disabled = ref(false);
  117. const total = ref(0); // 总页数
  118. // 分页
  119. const handleSizeChange = (val: number) => {
  120. console.log("${val} items per page");
  121. pageSize.value = val;
  122. getAllNoticesData();
  123. };
  124. const handleCurrentChange = (val: number) => {
  125. console.log("current page: ${val}");
  126. currentPage.value = val;
  127. getAllNoticesData();
  128. };
  129. //删除
  130. const handleDelete = (row: Notice) => {
  131. let params = row.id;
  132. deleteNoticeUrl(params).then((res) => {
  133. console.log(res.data.meta);
  134. getAllNoticesData();
  135. });
  136. };
  137. // 新增公告
  138. const addVisible = ref(false); // 是否显示新增公告对话框
  139. let noticeForm = reactive({
  140. title: "", // 公告标题
  141. content: "", // 公告内容
  142. });
  143. const handleAdd = () => {
  144. noticeForm.title = ''
  145. noticeForm.content = ''
  146. addVisible.value = true;
  147. };
  148. const saveAdd = async () => {
  149. try {
  150. let data = {
  151. title: noticeForm.title,
  152. content: noticeForm.content,
  153. user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  154. };
  155. const res = await addNoticeUrl(data);
  156. console.log(res.data);
  157. dialogFormVisible.value = false;
  158. getAllNoticesData();
  159. } catch (error) {
  160. console.error(error);
  161. }
  162. };
  163. // const saveAdd = () => {
  164. // dialogFormVisible.value = false;
  165. // let data = {
  166. // title: noticeForm.title,
  167. // content: noticeForm.content,
  168. // user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  169. // };
  170. // console.log(data);
  171. // addNoticeUrl(data).then((res) => {
  172. // console.log(res.data);
  173. // dialogFormVisible.value = false;
  174. // getAllNoticesData();
  175. // });
  176. // };
  177. </script>

五、编辑公告 

1. 后端接口(http://127.0.0.1:8000/edit_notice/) 

  1. {
  2. "id":19,
  3. "title": "会议通知",
  4. "content": "abcccccc"
  5. }

2. utils/api.ts中增加函数,用于调用后端接口编辑公告信息

  1. // 编辑公告
  2. export function editNoticeUrl(data:any) {
  3. return request({
  4. url: 'api/edit_notice/',
  5. method: 'put',
  6. data: data,
  7. })
  8. }

3.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-row :gutter="20">
  4. <el-col :span="4">
  5. <template #default="scope">
  6. <el-button
  7. text
  8. :icon="Edit"
  9. @click="handleAdd(scope.$index, scope.row)"
  10. v-permiss="15"
  11. >
  12. 新增
  13. </el-button>
  14. </template>
  15. </el-col>
  16. </el-row>
  17. <el-table ref="tableNoticeRef" :data="tableDataNotices" style="width: 100%">
  18. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  19. <el-table-column prop="title" label="标题" width="380">
  20. <template #default="scope" width="300">
  21. <span>{{ scope.row.title }}</span>
  22. </template>
  23. </el-table-column>
  24. <el-table-column prop="user" label="发布人姓名" width="100">
  25. <template #default="scope" width="180">
  26. <span>{{ scope.row.user }}</span>
  27. </template>
  28. </el-table-column>
  29. <el-table-column prop="content" label="内容" width="280">
  30. <template #default="scope" width="180">
  31. <span>{{ scope.row.content }}</span>
  32. </template>
  33. </el-table-column>
  34. <el-table-column label="操作" width="300">
  35. <template #default="scope">
  36. <el-button
  37. text
  38. :icon="Edit"
  39. @click="handleEdit(scope.$index, scope.row)"
  40. v-permiss="15"
  41. >
  42. 编辑
  43. </el-button>
  44. <el-popconfirm
  45. confirm-button-text="是"
  46. cancel-button-text="否"
  47. title="您确定删除吗?"
  48. icon-color="#626AEF"
  49. @confirm="handleDelete(scope.row)">
  50. <template #reference>
  51. <el-button>删除</el-button>
  52. </template>
  53. </el-popconfirm>
  54. </template>
  55. </el-table-column>
  56. </el-table>
  57. <!-- 分页组件 -->
  58. <el-pagination
  59. @size-change="handleSizeChange"
  60. @current-change="handleCurrentChange"
  61. :current-page="currentPage"
  62. :page-sizes="pageSizes"
  63. :page-size="pageSize"
  64. layout="total, sizes, prev, pager, next, jumper"
  65. :total="total"
  66. >
  67. </el-pagination>
  68. <!-- 新增对话框 -->
  69. <el-dialog title="新增" v-model="addVisible" width="30%">
  70. <el-form label-width="70px">
  71. <el-form-item label="标题">
  72. <el-input v-model="noticeForm.title"></el-input>
  73. </el-form-item>
  74. <el-form-item label="公告">
  75. <el-input v-model="noticeForm.content"></el-input>
  76. </el-form-item>
  77. </el-form>
  78. <template #footer>
  79. <span class="dialog-footer">
  80. <el-button @click="addVisible = false">取 消</el-button>
  81. <el-button type="primary" @click="saveAdd">确 定</el-button>
  82. </span>
  83. </template>
  84. </el-dialog>
  85. <!-- 编辑弹出框 -->
  86. <el-dialog title="编辑" v-model="editVisible" width="30%">
  87. <el-form label-width="70px">
  88. <el-form-item label="编号" v-if="false">
  89. <el-input v-model="noticeForm.id"></el-input>
  90. </el-form-item>
  91. <el-form-item label="标题">
  92. <el-input v-model="noticeForm.title"></el-input>
  93. </el-form-item>
  94. <el-form-item label="内容">
  95. <el-input v-model="noticeForm.content"></el-input>
  96. </el-form-item>
  97. </el-form>
  98. <template #footer>
  99. <span class="dialog-footer">
  100. <el-button @click="editVisible = false">取 消</el-button>
  101. <el-button type="primary" @click="saveEdit">确 定</el-button>
  102. </span>
  103. </template>
  104. </el-dialog>
  105. </template>
  106. <script setup lang="ts">
  107. import { ref, onMounted, reactive } from "vue";
  108. import {
  109. getAllNoticesUrl,
  110. getNoticesByPageUrl,
  111. deleteNoticeUrl,
  112. addNoticeUrl,
  113. editNoticeUrl,
  114. } from "../utils/api";
  115. import { Delete, Edit, Search, Plus } from "@element-plus/icons-vue";
  116. import { ElMessage, ElMessageBox } from "element-plus";
  117. // 声明一个公告类型的接口
  118. interface Notice {
  119. id: number; // 公告编号
  120. title: string; // 公告标题
  121. content: string; // 公告内容
  122. add_time: string; // 发布时间
  123. user_id: number; // 用户编号
  124. user: string; // 用户信息
  125. }
  126. // 公告数据
  127. var tableDataNotices = ref<Notice[]>([]);
  128. // 查询所有的公告并绑定到表格中
  129. // const getAllNoticesData = () => {
  130. // getAllNoticesUrl().then((res: any) => {
  131. // console.log(res);
  132. // tableDataNotices.value = res.data;
  133. // let total = tableDataNotices.value.length; // 修改总页数
  134. // });
  135. // };
  136. // 查询所有的公告并绑定到表格中(分页)
  137. const getAllNoticesData = () => {
  138. let params = {
  139. currentPage: currentPage.value,
  140. pageSize: pageSize.value,
  141. };
  142. getNoticesByPageUrl(params).then((res: any) => {
  143. console.log(res);
  144. tableDataNotices.value = res.data;
  145. total.value = res.total; // 修改总页数
  146. });
  147. };
  148. // 页面加载后查询所有公告数据
  149. onMounted(() => {
  150. getAllNoticesData();
  151. });
  152. // 分页
  153. const pageSizes = [5, 10, 15, 20, 50, 100];
  154. const pageSize = ref(5); // 每页记录条数
  155. const currentPage = ref(1); // 当前页的索引
  156. const small = ref(false);
  157. const background = ref(false);
  158. const disabled = ref(false);
  159. const total = ref(0); // 总页数
  160. // 分页
  161. const handleSizeChange = (val: number) => {
  162. console.log("${val} items per page");
  163. pageSize.value = val;
  164. getAllNoticesData();
  165. };
  166. const handleCurrentChange = (val: number) => {
  167. console.log("current page: ${val}");
  168. currentPage.value = val;
  169. getAllNoticesData();
  170. };
  171. //删除
  172. const handleDelete = (row: Notice) => {
  173. let params = row.id;
  174. deleteNoticeUrl(params).then((res) => {
  175. console.log(res.data.meta);
  176. getAllNoticesData();
  177. });
  178. };
  179. // 新增公告
  180. const addVisible = ref(false); // 是否显示新增公告对话框
  181. let noticeForm = reactive({
  182. id: 0,
  183. title: "", // 公告标题
  184. content: "", // 公告内容
  185. });
  186. const handleAdd = (index: number, row: any) => {
  187. noticeForm.title = "";
  188. noticeForm.content = "";
  189. addVisible.value = true;
  190. };
  191. const saveAdd = () => {
  192. addVisible.value = false;
  193. let data = {
  194. title: noticeForm.title,
  195. content: noticeForm.content,
  196. user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  197. };
  198. console.log(data);
  199. addNoticeUrl(data).then((res) => {
  200. console.log(res.data);
  201. getAllNoticesData();
  202. });
  203. };
  204. // 编辑公告
  205. const editVisible = ref(false);
  206. let idx: number = -1;
  207. const handleEdit = (index: number, row: any) => {
  208. idx = index;
  209. noticeForm.id = row.id;
  210. noticeForm.title = row.title;
  211. noticeForm.content = row.content;
  212. editVisible.value = true;
  213. };
  214. const saveEdit = async () => {
  215. try {
  216. const data = {
  217. id: noticeForm.id,
  218. title: noticeForm.title,
  219. content: noticeForm.content,
  220. };
  221. const res = await editNoticeUrl(data);
  222. console.log(res.data);
  223. ElMessage.success(`修改第 ${idx + 1} 行成功`);
  224. editVisible.value = false;
  225. getAllNoticesData();
  226. } catch (error) {
  227. console.error(error);
  228. // Handle error
  229. }
  230. };
  231. // const saveEdit = () => {
  232. // editVisible.value = false;
  233. // ElMessage.success(`修改第 ${idx + 1} 行成功`);
  234. // let data = {
  235. // id: noticeForm.id,
  236. // title: noticeForm.title,
  237. // content: noticeForm.content,
  238. // };
  239. // console.log(data);
  240. // editNoticeUrl(data).then((res) => {
  241. // console.log(res.data);
  242. // getAllNoticesData();
  243. // });
  244. // };
  245. </script>

六、筛选公告

​1.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-row :gutter="20">
  4. <el-col :span="4">
  5. <template #default="scope">
  6. <el-button
  7. text
  8. :icon="Edit"
  9. @click="handleAdd(scope.$index, scope.row)"
  10. v-permiss="15"
  11. >
  12. 新增
  13. </el-button>
  14. </template>
  15. </el-col>
  16. </el-row>
  17. <el-table
  18. ref="tableNoticeRef"
  19. :data="
  20. tableDataNotices.filter(
  21. (data) =>
  22. !search ||
  23. data.title.includes(search) ||
  24. data.title.toLowerCase().includes(search.toLowerCase())
  25. )
  26. "
  27. style="width: 100%"
  28. status-icon
  29. >
  30. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  31. <el-table-column prop="title" label="标题" width="380">
  32. <template #default="scope" width="300">
  33. <span>{{ scope.row.title }}</span>
  34. </template>
  35. </el-table-column>
  36. <el-table-column prop="user" label="发布人姓名" width="100">
  37. <template #default="scope" width="180">
  38. <span>{{ scope.row.user }}</span>
  39. </template>
  40. </el-table-column>
  41. <el-table-column prop="content" label="内容" width="280">
  42. <template #default="scope" width="180">
  43. <span>{{ scope.row.content }}</span>
  44. </template>
  45. </el-table-column>
  46. <el-table-column label="操作" width="300">
  47. <template #header>
  48. <el-input v-model="search" size="small" placeholder="Type to search" />
  49. </template>
  50. <template #default="scope">
  51. <el-button
  52. text
  53. :icon="Edit"
  54. @click="handleEdit(scope.$index, scope.row)"
  55. v-permiss="15"
  56. >
  57. 编辑
  58. </el-button>
  59. <el-popconfirm
  60. confirm-button-text="是"
  61. cancel-button-text="否"
  62. title="您确定删除吗?"
  63. icon-color="#626AEF"
  64. @confirm="handleDelete(scope.row)"
  65. >
  66. <template #reference>
  67. <el-button>删除</el-button>
  68. </template>
  69. </el-popconfirm>
  70. </template>
  71. </el-table-column>
  72. </el-table>
  73. <!-- 分页组件 -->
  74. <el-pagination
  75. @size-change="handleSizeChange"
  76. @current-change="handleCurrentChange"
  77. :current-page="currentPage"
  78. :page-sizes="pageSizes"
  79. :page-size="pageSize"
  80. layout="total, sizes, prev, pager, next, jumper"
  81. :total="total"
  82. >
  83. </el-pagination>
  84. <!-- 新增对话框 -->
  85. <el-dialog title="新增" v-model="addVisible" width="30%">
  86. <el-form label-width="70px">
  87. <el-form-item label="标题">
  88. <el-input v-model="noticeForm.title"></el-input>
  89. </el-form-item>
  90. <el-form-item label="公告">
  91. <el-input v-model="noticeForm.content"></el-input>
  92. </el-form-item>
  93. </el-form>
  94. <template #footer>
  95. <span class="dialog-footer">
  96. <el-button @click="addVisible = false">取 消</el-button>
  97. <el-button type="primary" @click="saveAdd">确 定</el-button>
  98. </span>
  99. </template>
  100. </el-dialog>
  101. <!-- 编辑弹出框 -->
  102. <el-dialog title="编辑" v-model="editVisible" width="30%">
  103. <el-form label-width="70px">
  104. <el-form-item label="编号" v-if="false">
  105. <el-input v-model="noticeForm.id"></el-input>
  106. </el-form-item>
  107. <el-form-item label="标题">
  108. <el-input v-model="noticeForm.title"></el-input>
  109. </el-form-item>
  110. <el-form-item label="内容">
  111. <el-input v-model="noticeForm.content"></el-input>
  112. </el-form-item>
  113. </el-form>
  114. <template #footer>
  115. <span class="dialog-footer">
  116. <el-button @click="editVisible = false">取 消</el-button>
  117. <el-button type="primary" @click="saveEdit">确 定</el-button>
  118. </span>
  119. </template>
  120. </el-dialog>
  121. </template>
  122. <script setup lang="ts">
  123. import { ref, onMounted, reactive } from "vue";
  124. import {
  125. getAllNoticesUrl,
  126. getNoticesByPageUrl,
  127. deleteNoticeUrl,
  128. addNoticeUrl,
  129. editNoticeUrl,
  130. } from "../utils/api";
  131. import { Delete, Edit, Search, Plus } from "@element-plus/icons-vue";
  132. import { ElMessage, ElMessageBox } from "element-plus";
  133. // 声明一个公告类型的接口
  134. interface Notice {
  135. id: number; // 公告编号
  136. title: string; // 公告标题
  137. content: string; // 公告内容
  138. add_time: string; // 发布时间
  139. user_id: number; // 用户编号
  140. user: string; // 用户信息
  141. }
  142. // 公告数据
  143. var tableDataNotices = ref<Notice[]>([]);
  144. // 查询所有的公告并绑定到表格中
  145. // const getAllNoticesData = () => {
  146. // getAllNoticesUrl().then((res: any) => {
  147. // console.log(res);
  148. // tableDataNotices.value = res.data;
  149. // let total = tableDataNotices.value.length; // 修改总页数
  150. // });
  151. // };
  152. // 查询所有的公告并绑定到表格中(分页)
  153. const getAllNoticesData = () => {
  154. let params = {
  155. currentPage: currentPage.value,
  156. pageSize: pageSize.value,
  157. };
  158. getNoticesByPageUrl(params).then((res: any) => {
  159. console.log(res);
  160. tableDataNotices.value = res.data;
  161. total.value = res.total; // 修改总页数
  162. });
  163. };
  164. // 页面加载后查询所有公告数据
  165. onMounted(() => {
  166. getAllNoticesData();
  167. });
  168. // 分页
  169. const pageSizes = [5, 10, 15, 20, 50, 100];
  170. const pageSize = ref(5); // 每页记录条数
  171. const currentPage = ref(1); // 当前页的索引
  172. const small = ref(false);
  173. const background = ref(false);
  174. const disabled = ref(false);
  175. const total = ref(0); // 总页数
  176. // 分页
  177. const handleSizeChange = (val: number) => {
  178. console.log("${val} items per page");
  179. pageSize.value = val;
  180. getAllNoticesData();
  181. };
  182. const handleCurrentChange = (val: number) => {
  183. console.log("current page: ${val}");
  184. currentPage.value = val;
  185. getAllNoticesData();
  186. };
  187. //删除
  188. const handleDelete = (row: Notice) => {
  189. let params = row.id;
  190. deleteNoticeUrl(params).then((res) => {
  191. console.log(res.data.meta);
  192. getAllNoticesData();
  193. });
  194. };
  195. // 新增公告
  196. const addVisible = ref(false); // 是否显示新增公告对话框
  197. let noticeForm = reactive({
  198. id: 0,
  199. title: "", // 公告标题
  200. content: "", // 公告内容
  201. });
  202. const handleAdd = (index: number, row: any) => {
  203. noticeForm.title = "";
  204. noticeForm.content = "";
  205. addVisible.value = true;
  206. };
  207. async function saveAdd() {
  208. try {
  209. const data = {
  210. title: noticeForm.title,
  211. content: noticeForm.content,
  212. user_id: 1
  213. };
  214. dialogFormVisible.value = false;
  215. const res = await addNoticeUrl(data);
  216. console.log(res.data);
  217. await getAllNoticesData();
  218. } catch (error) {
  219. console.error(error);
  220. }
  221. }
  222. // const saveAdd = () => {
  223. // addVisible.value = false;
  224. // let data = {
  225. // title: noticeForm.title,
  226. // content: noticeForm.content,
  227. // user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  228. // };
  229. // console.log(data);
  230. // addNoticeUrl(data).then((res) => {
  231. // console.log(res.data);
  232. // getAllNoticesData();
  233. // });
  234. // };
  235. // 编辑公告
  236. const editVisible = ref(false);
  237. let idx: number = -1;
  238. const handleEdit = (index: number, row: any) => {
  239. idx = index;
  240. noticeForm.id = row.id;
  241. noticeForm.title = row.title;
  242. noticeForm.content = row.content;
  243. editVisible.value = true;
  244. };
  245. const saveEdit = () => {
  246. editVisible.value = false;
  247. ElMessage.success(`修改第 ${idx + 1} 行成功`);
  248. let data = {
  249. id: noticeForm.id,
  250. title: noticeForm.title,
  251. content: noticeForm.content,
  252. };
  253. console.log(data);
  254. editNoticeUrl(data).then((res) => {
  255. console.log(res.data);
  256. getAllNoticesData();
  257. });
  258. };
  259. // 筛选数据
  260. const search = ref("");
  261. </script>

七、多选

1.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-row :gutter="20">
  4. <el-col :span="4">
  5. <template #default="scope">
  6. <el-button
  7. text
  8. :icon="Edit"
  9. @click="handleAdd(scope.$index, scope.row)"
  10. v-permiss="15"
  11. >
  12. 新增
  13. </el-button>
  14. </template>
  15. </el-col>
  16. </el-row>
  17. <el-table
  18. ref="tableNoticeRef"
  19. :data="
  20. tableDataNotices.filter(
  21. (data) =>
  22. !search ||
  23. data.title.includes(search) ||
  24. data.title.toLowerCase().includes(search.toLowerCase())
  25. )
  26. "
  27. style="width: 100%"
  28. status-icon
  29. @selection-change="handleSelectionChange">
  30. <el-table-column type="selection" width="55" />
  31. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  32. <el-table-column prop="title" label="标题" width="380">
  33. <template #default="scope" width="300">
  34. <span>{{ scope.row.title }}</span>
  35. </template>
  36. </el-table-column>
  37. <el-table-column prop="user" label="发布人姓名" width="100">
  38. <template #default="scope" width="180">
  39. <span>{{ scope.row.user }}</span>
  40. </template>
  41. </el-table-column>
  42. <el-table-column prop="content" label="内容" width="280">
  43. <template #default="scope" width="180">
  44. <span>{{ scope.row.content }}</span>
  45. </template>
  46. </el-table-column>
  47. <el-table-column label="操作" width="300">
  48. <template #header>
  49. <el-input v-model="search" size="small" placeholder="Type to search" />
  50. </template>
  51. <template #default="scope">
  52. <el-button
  53. text
  54. :icon="Edit"
  55. @click="handleEdit(scope.$index, scope.row)"
  56. v-permiss="15"
  57. >
  58. 编辑
  59. </el-button>
  60. <el-popconfirm
  61. confirm-button-text="是"
  62. cancel-button-text="否"
  63. title="您确定删除吗?"
  64. icon-color="#626AEF"
  65. @confirm="handleDelete(scope.row)"
  66. >
  67. <template #reference>
  68. <el-button>删除</el-button>
  69. </template>
  70. </el-popconfirm>
  71. </template>
  72. </el-table-column>
  73. </el-table>
  74. <!-- 分页组件 -->
  75. <el-pagination
  76. @size-change="handleSizeChange"
  77. @current-change="handleCurrentChange"
  78. :current-page="currentPage"
  79. :page-sizes="pageSizes"
  80. :page-size="pageSize"
  81. layout="total, sizes, prev, pager, next, jumper"
  82. :total="total"
  83. >
  84. </el-pagination>
  85. <!-- 新增对话框 -->
  86. <el-dialog title="新增" v-model="addVisible" width="30%">
  87. <el-form label-width="70px">
  88. <el-form-item label="标题">
  89. <el-input v-model="noticeForm.title"></el-input>
  90. </el-form-item>
  91. <el-form-item label="公告">
  92. <el-input v-model="noticeForm.content"></el-input>
  93. </el-form-item>
  94. </el-form>
  95. <template #footer>
  96. <span class="dialog-footer">
  97. <el-button @click="addVisible = false">取 消</el-button>
  98. <el-button type="primary" @click="saveAdd">确 定</el-button>
  99. </span>
  100. </template>
  101. </el-dialog>
  102. <!-- 编辑弹出框 -->
  103. <el-dialog title="编辑" v-model="editVisible" width="30%">
  104. <el-form label-width="70px">
  105. <el-form-item label="编号" v-if="false">
  106. <el-input v-model="noticeForm.id"></el-input>
  107. </el-form-item>
  108. <el-form-item label="标题">
  109. <el-input v-model="noticeForm.title"></el-input>
  110. </el-form-item>
  111. <el-form-item label="内容">
  112. <el-input v-model="noticeForm.content"></el-input>
  113. </el-form-item>
  114. </el-form>
  115. <template #footer>
  116. <span class="dialog-footer">
  117. <el-button @click="editVisible = false">取 消</el-button>
  118. <el-button type="primary" @click="saveEdit">确 定</el-button>
  119. </span>
  120. </template>
  121. </el-dialog>
  122. </template>
  123. <script setup lang="ts">
  124. import { ref, onMounted, reactive } from "vue";
  125. import {
  126. getAllNoticesUrl,
  127. getNoticesByPageUrl,
  128. deleteNoticeUrl,
  129. addNoticeUrl,
  130. editNoticeUrl,
  131. } from "../utils/api";
  132. import { Delete, Edit, Search, Plus } from "@element-plus/icons-vue";
  133. import { ElMessage, ElMessageBox } from "element-plus";
  134. // 声明一个公告类型的接口
  135. interface Notice {
  136. id: number; // 公告编号
  137. title: string; // 公告标题
  138. content: string; // 公告内容
  139. add_time: string; // 发布时间
  140. user_id: number; // 用户编号
  141. user: string; // 用户信息
  142. }
  143. // 公告数据
  144. var tableDataNotices = ref<Notice[]>([]);
  145. // 查询所有的公告并绑定到表格中
  146. // const getAllNoticesData = () => {
  147. // getAllNoticesUrl().then((res: any) => {
  148. // console.log(res);
  149. // tableDataNotices.value = res.data;
  150. // let total = tableDataNotices.value.length; // 修改总页数
  151. // });
  152. // };
  153. // 查询所有的公告并绑定到表格中(分页)
  154. const getAllNoticesData = () => {
  155. let params = {
  156. currentPage: currentPage.value,
  157. pageSize: pageSize.value,
  158. };
  159. getNoticesByPageUrl(params).then((res: any) => {
  160. console.log(res);
  161. tableDataNotices.value = res.data;
  162. total.value = res.total; // 修改总页数
  163. });
  164. };
  165. // 页面加载后查询所有公告数据
  166. onMounted(() => {
  167. getAllNoticesData();
  168. });
  169. // 分页
  170. const pageSizes = [5, 10, 15, 20, 50, 100];
  171. const pageSize = ref(5); // 每页记录条数
  172. const currentPage = ref(1); // 当前页的索引
  173. const small = ref(false);
  174. const background = ref(false);
  175. const disabled = ref(false);
  176. const total = ref(0); // 总页数
  177. // 分页
  178. const handleSizeChange = (val: number) => {
  179. console.log("${val} items per page");
  180. pageSize.value = val;
  181. getAllNoticesData();
  182. };
  183. const handleCurrentChange = (val: number) => {
  184. console.log("current page: ${val}");
  185. currentPage.value = val;
  186. getAllNoticesData();
  187. };
  188. //删除
  189. const handleDelete = (row: Notice) => {
  190. let params = row.id;
  191. deleteNoticeUrl(params).then((res) => {
  192. console.log(res.data.meta);
  193. getAllNoticesData();
  194. });
  195. };
  196. // 新增公告
  197. const addVisible = ref(false); // 是否显示新增公告对话框
  198. let noticeForm = reactive({
  199. id: 0,
  200. title: "", // 公告标题
  201. content: "", // 公告内容
  202. });
  203. const handleAdd = (index: number, row: any) => {
  204. noticeForm.title = "";
  205. noticeForm.content = "";
  206. addVisible.value = true;
  207. };
  208. const saveAdd = () => {
  209. addVisible.value = false;
  210. let data = {
  211. title: noticeForm.title,
  212. content: noticeForm.content,
  213. user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  214. };
  215. console.log(data);
  216. addNoticeUrl(data).then((res) => {
  217. console.log(res.data);
  218. getAllNoticesData();
  219. });
  220. };
  221. // 编辑公告
  222. const editVisible = ref(false);
  223. let idx: number = -1;
  224. const handleEdit = (index: number, row: any) => {
  225. idx = index;
  226. noticeForm.id = row.id;
  227. noticeForm.title = row.title;
  228. noticeForm.content = row.content;
  229. editVisible.value = true;
  230. };
  231. const saveEdit = () => {
  232. editVisible.value = false;
  233. ElMessage.success(`修改第 ${idx + 1} 行成功`);
  234. let data = {
  235. id: noticeForm.id,
  236. title: noticeForm.title,
  237. content: noticeForm.content,
  238. };
  239. console.log(data);
  240. editNoticeUrl(data).then((res) => {
  241. console.log(res.data);
  242. getAllNoticesData();
  243. });
  244. };
  245. // 筛选数据
  246. const search = ref("");
  247. // 多选
  248. const multipleSelection = ref<Notice[]>([]);
  249. const handleSelectionChange = (val: Notice[]) => {
  250. multipleSelection.value = val;
  251. };
  252. </script>

八、全选、清除、批量删除 

1.  修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-row :gutter="20">
  4. <el-col :span="4">
  5. <template #default="scope">
  6. <el-button
  7. text
  8. :icon="Edit"
  9. @click="handleAdd(scope.$index, scope.row)"
  10. v-permiss="15"
  11. >
  12. 新增
  13. </el-button>
  14. </template>
  15. </el-col>
  16. </el-row>
  17. <el-table
  18. ref="tableNoticeRef"
  19. :data="
  20. tableDataNotices.filter(
  21. (data) =>
  22. !search ||
  23. data.title.includes(search) ||
  24. data.title.toLowerCase().includes(search.toLowerCase())
  25. )
  26. "
  27. style="width: 100%"
  28. status-icon
  29. @selection-change="handleSelectionChange">
  30. <el-table-column type="selection" width="55" />
  31. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  32. <el-table-column prop="title" label="标题" width="380">
  33. <template #default="scope" width="300">
  34. <span>{{ scope.row.title }}</span>
  35. </template>
  36. </el-table-column>
  37. <el-table-column prop="user" label="发布人姓名" width="100">
  38. <template #default="scope" width="180">
  39. <span>{{ scope.row.user }}</span>
  40. </template>
  41. </el-table-column>
  42. <el-table-column prop="content" label="内容" width="280">
  43. <template #default="scope" width="180">
  44. <span>{{ scope.row.content }}</span>
  45. </template>
  46. </el-table-column>
  47. <el-table-column label="操作" width="300">
  48. <template #header>
  49. <el-input v-model="search" size="small" placeholder="Type to search" />
  50. </template>
  51. <template #default="scope">
  52. <el-button
  53. text
  54. :icon="Edit"
  55. @click="handleEdit(scope.$index, scope.row)"
  56. v-permiss="15"
  57. >
  58. 编辑
  59. </el-button>
  60. <el-popconfirm
  61. confirm-button-text="是"
  62. cancel-button-text="否"
  63. title="您确定删除吗?"
  64. icon-color="#626AEF"
  65. @confirm="handleDelete(scope.row)"
  66. >
  67. <template #reference>
  68. <el-button>删除</el-button>
  69. </template>
  70. </el-popconfirm>
  71. </template>
  72. </el-table-column>
  73. </el-table>
  74. <!-- 分页组件 -->
  75. <el-pagination
  76. @size-change="handleSizeChange"
  77. @current-change="handleCurrentChange"
  78. :current-page="currentPage"
  79. :page-sizes="pageSizes"
  80. :page-size="pageSize"
  81. layout="total, sizes, prev, pager, next, jumper"
  82. :total="total"
  83. >
  84. </el-pagination>
  85. <!-- 新增对话框 -->
  86. <el-dialog title="新增" v-model="addVisible" width="30%">
  87. <el-form label-width="70px">
  88. <el-form-item label="标题">
  89. <el-input v-model="noticeForm.title"></el-input>
  90. </el-form-item>
  91. <el-form-item label="公告">
  92. <el-input v-model="noticeForm.content"></el-input>
  93. </el-form-item>
  94. </el-form>
  95. <template #footer>
  96. <span class="dialog-footer">
  97. <el-button @click="addVisible = false">取 消</el-button>
  98. <el-button type="primary" @click="saveAdd">确 定</el-button>
  99. </span>
  100. </template>
  101. </el-dialog>
  102. <!-- 编辑弹出框 -->
  103. <el-dialog title="编辑" v-model="editVisible" width="30%">
  104. <el-form label-width="70px">
  105. <el-form-item label="编号" v-if="false">
  106. <el-input v-model="noticeForm.id"></el-input>
  107. </el-form-item>
  108. <el-form-item label="标题">
  109. <el-input v-model="noticeForm.title"></el-input>
  110. </el-form-item>
  111. <el-form-item label="内容">
  112. <el-input v-model="noticeForm.content"></el-input>
  113. </el-form-item>
  114. </el-form>
  115. <template #footer>
  116. <span class="dialog-footer">
  117. <el-button @click="editVisible = false">取 消</el-button>
  118. <el-button type="primary" @click="saveEdit">确 定</el-button>
  119. </span>
  120. </template>
  121. </el-dialog>
  122. <div style="margin-top: 20px; margin-left: 20px">
  123. <el-button @click="toggleSelection(tableDataNotices)">全选</el-button>
  124. <el-button @click="toggleSelection()">清除</el-button>
  125. <el-button @click="handleDeleteArray()">批量删除</el-button>
  126. </div>
  127. </template>
  128. <script setup lang="ts">
  129. import { ref, onMounted, reactive } from "vue";
  130. import {
  131. getAllNoticesUrl,
  132. getNoticesByPageUrl,
  133. deleteNoticeUrl,
  134. addNoticeUrl,
  135. editNoticeUrl,
  136. } from "../utils/api";
  137. import { Delete, Edit, Search, Plus } from "@element-plus/icons-vue";
  138. import { ElMessage, ElMessageBox } from "element-plus";
  139. import { ElTable } from "element-plus";
  140. // 声明一个公告类型的接口
  141. interface Notice {
  142. id: number; // 公告编号
  143. title: string; // 公告标题
  144. content: string; // 公告内容
  145. add_time: string; // 发布时间
  146. user_id: number; // 用户编号
  147. user: string; // 用户信息
  148. }
  149. // 公告数据
  150. var tableDataNotices = ref<Notice[]>([]);
  151. // 查询所有的公告并绑定到表格中
  152. // const getAllNoticesData = () => {
  153. // getAllNoticesUrl().then((res: any) => {
  154. // console.log(res);
  155. // tableDataNotices.value = res.data;
  156. // let total = tableDataNotices.value.length; // 修改总页数
  157. // });
  158. // };
  159. // 查询所有的公告并绑定到表格中(分页)
  160. const getAllNoticesData = () => {
  161. let params = {
  162. currentPage: currentPage.value,
  163. pageSize: pageSize.value,
  164. };
  165. getNoticesByPageUrl(params).then((res: any) => {
  166. console.log(res);
  167. tableDataNotices.value = res.data;
  168. total.value = res.total; // 修改总页数
  169. });
  170. };
  171. // 页面加载后查询所有公告数据
  172. onMounted(() => {
  173. getAllNoticesData();
  174. });
  175. // 分页
  176. const pageSizes = [5, 10, 15, 20, 50, 100];
  177. const pageSize = ref(5); // 每页记录条数
  178. const currentPage = ref(1); // 当前页的索引
  179. const small = ref(false);
  180. const background = ref(false);
  181. const disabled = ref(false);
  182. const total = ref(0); // 总页数
  183. // 分页
  184. const handleSizeChange = (val: number) => {
  185. console.log("${val} items per page");
  186. pageSize.value = val;
  187. getAllNoticesData();
  188. };
  189. const handleCurrentChange = (val: number) => {
  190. console.log("current page: ${val}");
  191. currentPage.value = val;
  192. getAllNoticesData();
  193. };
  194. //删除
  195. const handleDelete = (row: Notice) => {
  196. let params = row.id;
  197. deleteNoticeUrl(params).then((res) => {
  198. console.log(res.data.meta);
  199. getAllNoticesData();
  200. });
  201. };
  202. // 新增公告
  203. const addVisible = ref(false); // 是否显示新增公告对话框
  204. let noticeForm = reactive({
  205. id: 0,
  206. title: "", // 公告标题
  207. content: "", // 公告内容
  208. });
  209. const handleAdd = (index: number, row: any) => {
  210. noticeForm.title = "";
  211. noticeForm.content = "";
  212. addVisible.value = true;
  213. };
  214. const saveAdd = () => {
  215. addVisible.value = false;
  216. let data = {
  217. title: noticeForm.title,
  218. content: noticeForm.content,
  219. user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  220. };
  221. console.log(data);
  222. addNoticeUrl(data).then((res) => {
  223. console.log(res.data);
  224. getAllNoticesData();
  225. });
  226. };
  227. // 编辑公告
  228. const editVisible = ref(false);
  229. let idx: number = -1;
  230. const handleEdit = (index: number, row: any) => {
  231. idx = index;
  232. noticeForm.id = row.id;
  233. noticeForm.title = row.title;
  234. noticeForm.content = row.content;
  235. editVisible.value = true;
  236. };
  237. const saveEdit = () => {
  238. editVisible.value = false;
  239. ElMessage.success(`修改第 ${idx + 1} 行成功`);
  240. let data = {
  241. id: noticeForm.id,
  242. title: noticeForm.title,
  243. content: noticeForm.content,
  244. };
  245. console.log(data);
  246. editNoticeUrl(data).then((res) => {
  247. console.log(res.data);
  248. getAllNoticesData();
  249. });
  250. };
  251. // 筛选数据
  252. const search = ref("");
  253. // 多选
  254. const multipleSelection = ref<Notice[]>([]);
  255. const tableNoticeRef = ref<InstanceType<typeof ElTable>>();
  256. // 全选和清除按钮
  257. const toggleSelection = (rows?: Notice[]) => {
  258. if (rows) {
  259. rows.forEach((row) => {
  260. tableNoticeRef.value!.toggleRowSelection(row, undefined);
  261. });
  262. } else {
  263. tableNoticeRef.value!.clearSelection();
  264. }
  265. };
  266. const handleSelectionChange = (val: Notice[]) => {
  267. multipleSelection.value = val;
  268. };
  269. // 批量删除
  270. const handleDeleteArray = () => {
  271. for (var i = 0; i < multipleSelection.value.length; i++) {
  272. let params = multipleSelection.value[i].id;
  273. deleteNotice(params);
  274. getAllNoticesData();
  275. }
  276. // for (var i = 0; i < multipleSelection.value.length; i++) {
  277. // deleteNoticeUrl(multipleSelection.value[i].id).then((res) => {
  278. // console.log(res.data.meta);
  279. // getAllNoticesData();
  280. // });
  281. // }
  282. };
  283. </script>

九、Excel导入导出

1. Excel导入

 

2. Excel导出

3. 安装依赖包

npm install xlsx

4.  Excel模板template.xlsx放入public文件夹中

5.   修改NoticesManagement.vue文件

  1. <template>
  2. <h1>公告管理</h1>
  3. <el-row :gutter="20">
  4. <template #default="scope">
  5. <el-col :span="2">
  6. <el-button type="primary" @click="exportXlsx">导出Excel</el-button>
  7. </el-col>
  8. <el-col :span="2">
  9. <el-upload
  10. class="inline-block"
  11. action="#"
  12. :limit="1"
  13. accept=".xlsx, .xls"
  14. :show-file-list="false"
  15. :before-upload="beforeUpload"
  16. :http-request="handleMany"
  17. >
  18. <el-button type="primary">批量导入</el-button>
  19. </el-upload>
  20. </el-col>
  21. <el-col :span="2">
  22. <el-link href="/template.xlsx" type="primary" target="_blank">下载模板</el-link>
  23. </el-col>
  24. <el-col :span="2">
  25. <el-button
  26. text
  27. :icon="Edit"
  28. @click="handleAdd(scope.$index, scope.row)"
  29. v-permiss="15"
  30. >
  31. 新增
  32. </el-button>
  33. </el-col>
  34. </template>
  35. </el-row>
  36. <el-table
  37. ref="tableNoticeRef"
  38. :data="
  39. tableDataNotices.filter(
  40. (data) =>
  41. !search ||
  42. data.title.includes(search) ||
  43. data.title.toLowerCase().includes(search.toLowerCase())
  44. )
  45. "
  46. style="width: 100%"
  47. status-icon
  48. @selection-change="handleSelectionChange"
  49. >
  50. <el-table-column type="selection" width="55" />
  51. <el-table-column prop="id" label="编号" width="180" v-if="true" />
  52. <el-table-column prop="title" label="标题" width="380">
  53. <template #default="scope" width="300">
  54. <span>{{ scope.row.title }}</span>
  55. </template>
  56. </el-table-column>
  57. <el-table-column prop="user" label="发布人姓名" width="100">
  58. <template #default="scope" width="180">
  59. <span>{{ scope.row.user }}</span>
  60. </template>
  61. </el-table-column>
  62. <el-table-column prop="content" label="内容" width="280">
  63. <template #default="scope" width="180">
  64. <span>{{ scope.row.content }}</span>
  65. </template>
  66. </el-table-column>
  67. <el-table-column label="操作" width="300">
  68. <template #header>
  69. <el-input v-model="search" size="small" placeholder="Type to search" />
  70. </template>
  71. <template #default="scope">
  72. <el-button
  73. text
  74. :icon="Edit"
  75. @click="handleEdit(scope.$index, scope.row)"
  76. v-permiss="15"
  77. >
  78. 编辑
  79. </el-button>
  80. <el-popconfirm
  81. confirm-button-text="是"
  82. cancel-button-text="否"
  83. title="您确定删除吗?"
  84. icon-color="#626AEF"
  85. @confirm="handleDelete(scope.row)"
  86. >
  87. <template #reference>
  88. <el-button>删除</el-button>
  89. </template>
  90. </el-popconfirm>
  91. </template>
  92. </el-table-column>
  93. </el-table>
  94. <!-- 分页组件 -->
  95. <el-pagination
  96. @size-change="handleSizeChange"
  97. @current-change="handleCurrentChange"
  98. :current-page="currentPage"
  99. :page-sizes="pageSizes"
  100. :page-size="pageSize"
  101. layout="total, sizes, prev, pager, next, jumper"
  102. :total="total"
  103. >
  104. </el-pagination>
  105. <!-- 新增对话框 -->
  106. <el-dialog title="新增" v-model="addVisible" width="30%">
  107. <el-form label-width="70px">
  108. <el-form-item label="标题">
  109. <el-input v-model="noticeForm.title"></el-input>
  110. </el-form-item>
  111. <el-form-item label="公告">
  112. <el-input v-model="noticeForm.content"></el-input>
  113. </el-form-item>
  114. </el-form>
  115. <template #footer>
  116. <span class="dialog-footer">
  117. <el-button @click="addVisible = false">取 消</el-button>
  118. <el-button type="primary" @click="saveAdd">确 定</el-button>
  119. </span>
  120. </template>
  121. </el-dialog>
  122. <!-- 编辑弹出框 -->
  123. <el-dialog title="编辑" v-model="editVisible" width="30%">
  124. <el-form label-width="70px">
  125. <el-form-item label="编号" v-if="false">
  126. <el-input v-model="noticeForm.id"></el-input>
  127. </el-form-item>
  128. <el-form-item label="标题">
  129. <el-input v-model="noticeForm.title"></el-input>
  130. </el-form-item>
  131. <el-form-item label="内容">
  132. <el-input v-model="noticeForm.content"></el-input>
  133. </el-form-item>
  134. </el-form>
  135. <template #footer>
  136. <span class="dialog-footer">
  137. <el-button @click="editVisible = false">取 消</el-button>
  138. <el-button type="primary" @click="saveEdit">确 定</el-button>
  139. </span>
  140. </template>
  141. </el-dialog>
  142. <div style="margin-top: 20px; margin-left: 20px">
  143. <el-button @click="toggleSelection(tableDataNotices)">全选</el-button>
  144. <el-button @click="toggleSelection()">清除</el-button>
  145. <el-button @click="handleDeleteArray()">批量删除</el-button>
  146. </div>
  147. </template>
  148. <script setup lang="ts">
  149. import { ref, onMounted, reactive } from "vue";
  150. import {
  151. getAllNoticesUrl,
  152. getNoticesByPageUrl,
  153. deleteNoticeUrl,
  154. addNoticeUrl,
  155. editNoticeUrl,
  156. } from "../utils/api";
  157. import { Delete, Edit, Search, Plus } from "@element-plus/icons-vue";
  158. import { ElMessage, ElMessageBox } from "element-plus";
  159. import { ElTable } from "element-plus";
  160. import * as XLSX from "xlsx";
  161. import { UploadProps } from "element-plus";
  162. // 声明一个公告类型的接口
  163. interface Notice {
  164. id: number; // 公告编号
  165. title: string; // 公告标题
  166. content: string; // 公告内容
  167. add_time: string; // 发布时间
  168. user_id: number; // 用户编号
  169. user: string; // 用户信息
  170. }
  171. // 公告数据
  172. var tableDataNotices = ref<Notice[]>([]);
  173. // 查询所有的公告并绑定到表格中
  174. // const getAllNoticesData = () => {
  175. // getAllNoticesUrl().then((res: any) => {
  176. // console.log(res);
  177. // tableDataNotices.value = res.data;
  178. // let total = tableDataNotices.value.length; // 修改总页数
  179. // });
  180. // };
  181. // 查询所有的公告并绑定到表格中(分页)
  182. const getAllNoticesData = async () => {
  183. let params = {
  184. currentPage: currentPage.value,
  185. pageSize: pageSize.value,
  186. };
  187. await getNoticesByPageUrl(params).then((res: any) => {
  188. console.log(res);
  189. tableDataNotices.value = res.data;
  190. total.value = res.total; // 修改总页数
  191. });
  192. };
  193. // 页面加载后查询所有公告数据
  194. onMounted(() => {
  195. getAllNoticesData();
  196. });
  197. // 分页
  198. const pageSizes = [5, 10, 15, 20, 50, 100];
  199. const pageSize = ref(5); // 每页记录条数
  200. const currentPage = ref(1); // 当前页的索引
  201. const small = ref(false);
  202. const background = ref(false);
  203. const disabled = ref(false);
  204. const total = ref(0); // 总页数
  205. // 分页
  206. const handleSizeChange = (val: number) => {
  207. console.log("${val} items per page");
  208. pageSize.value = val;
  209. getAllNoticesData();
  210. };
  211. const handleCurrentChange = (val: number) => {
  212. console.log("current page: ${val}");
  213. currentPage.value = val;
  214. getAllNoticesData();
  215. };
  216. //删除
  217. const handleDelete = async (row: Notice) => {
  218. let params = row.id;
  219. await deleteNoticeUrl(params).then((res) => {
  220. console.log(res.data.meta);
  221. getAllNoticesData();
  222. });
  223. };
  224. // 新增公告
  225. const addVisible = ref(false); // 是否显示新增公告对话框
  226. let noticeForm = reactive({
  227. id: 0,
  228. title: "", // 公告标题
  229. content: "", // 公告内容
  230. });
  231. const handleAdd = (index: number, row: any) => {
  232. noticeForm.title = "";
  233. noticeForm.content = "";
  234. addVisible.value = true;
  235. };
  236. const saveAdd = async () => {
  237. addVisible.value = false;
  238. let data = {
  239. title: noticeForm.title,
  240. content: noticeForm.content,
  241. user_id: 1, // 用户编号先用个固定值,后面需要得到登录用户的编号
  242. };
  243. console.log(data);
  244. await addNoticeUrl(data).then((res) => {
  245. console.log(res.data);
  246. getAllNoticesData();
  247. });
  248. };
  249. // 编辑公告
  250. const editVisible = ref(false);
  251. let idx: number = -1;
  252. const handleEdit = (index: number, row: any) => {
  253. idx = index;
  254. noticeForm.id = row.id;
  255. noticeForm.title = row.title;
  256. noticeForm.content = row.content;
  257. editVisible.value = true;
  258. };
  259. const saveEdit = async () => {
  260. editVisible.value = false;
  261. ElMessage.success(`修改第 ${idx + 1} 行成功`);
  262. let data = {
  263. id: noticeForm.id,
  264. title: noticeForm.title,
  265. content: noticeForm.content,
  266. };
  267. console.log(data);
  268. await editNoticeUrl(data).then((res) => {
  269. console.log(res.data);
  270. getAllNoticesData();
  271. });
  272. };
  273. // 筛选数据
  274. const search = ref("");
  275. // 多选
  276. const multipleSelection = ref<Notice[]>([]);
  277. const tableNoticeRef = ref<InstanceType<typeof ElTable>>();
  278. // 全选和清除按钮
  279. const toggleSelection = (rows?: Notice[]) => {
  280. if (rows) {
  281. rows.forEach((row) => {
  282. tableNoticeRef.value!.toggleRowSelection(row, undefined);
  283. });
  284. } else {
  285. tableNoticeRef.value!.clearSelection();
  286. }
  287. };
  288. const handleSelectionChange = (val: Notice[]) => {
  289. multipleSelection.value = val;
  290. };
  291. // 批量删除
  292. const handleDeleteArray = async () => {
  293. // console.log(multipleSelection.value)
  294. for (var i = 0; i < multipleSelection.value.length; i++) {
  295. await deleteNoticeUrl(multipleSelection.value[i].id).then((res) => {
  296. console.log(res.data.meta);
  297. getAllNoticesData();
  298. });
  299. }
  300. };
  301. // Excel导入导出
  302. // 导出Excel函数
  303. const exportXlsx = () => {
  304. // 使用computed属性计算表格数据,只有在tableDataNotices变化时才会重新计算
  305. const list = computed(() => {
  306. // 将tableDataNotices数组转换为二维数组
  307. return [["编号", "标题", "内容", "发布时间", "发布人姓名"], ...tableDataNotices.value.map((item: any, i: number) => {
  308. // 返回一个数组,包含该条记录的所有字段
  309. return [i + 1, item.title, item.content, item.add_time, item.user];
  310. })];
  311. }).value;
  312. // 将数据转换为工作表
  313. let WorkSheet = XLSX.utils.aoa_to_sheet(list);
  314. // 创建一个新的工作簿
  315. let new_workbook = XLSX.utils.book_new();
  316. // 将工作表添加到工作簿中,并指定名称为“第一页”
  317. XLSX.utils.book_append_sheet(new_workbook, WorkSheet, "第一页");
  318. // 保存工作簿为Excel文件,文件名为“表格.xlsx”
  319. XLSX.writeFile(new_workbook, `表格.xlsx`);
  320. };
  321. // 导入Excel
  322. const importList = ref<any>([]);
  323. // 上传前对Excel文件进行解析
  324. const beforeUpload: UploadProps["beforeUpload"] = async (rawFile) => {
  325. // 调用analysisExcel函数,解析Excel文件并将结果保存在importList中
  326. importList.value = await analysisExcel(rawFile);
  327. // 返回true表示上传文件
  328. return true;
  329. };
  330. // 解析Excel文件
  331. const analysisExcel = (file: any) => {
  332. return new Promise(function (resolve, reject) {
  333. const reader = new FileReader();
  334. reader.onload = function (e: any) {
  335. const data = e.target.result;
  336. // 使用XLSX读取二进制数据并将其转换为json格式
  337. const workbook = XLSX.read(data, { type: "binary" });
  338. // 获取第一个Sheet的名称
  339. const sheetName = workbook.SheetNames[0];
  340. // 将Sheet转换为json格式
  341. const result = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
  342. resolve(result);
  343. };
  344. reader.readAsBinaryString(file);
  345. });
  346. };
  347. // 批量添加公告
  348. const handleMany = async () => {
  349. // 将importList中的数据转换为公告列表
  350. const notices = importList.value.map((item: any) => ({
  351. title: item["标题"],
  352. content: item["内容"],
  353. user_id: 1,
  354. }));
  355. // 添加公告并刷新页面
  356. for (let i = 0; i < notices.length; i++) {
  357. await addNoticeUrl(notices[i]);
  358. }
  359. location.reload();
  360. };
  361. </script>
 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/113624
推荐阅读
相关标签
  

闽ICP备14008679号