• vite + vue3 + ts配置《企业级项目》二次封装el-table、分页


     ​前期回顾    ​      

    Vite项目,vite + vue3 + ts + vuex + vue-router + axios + scss + 自动导入api(就是用v3不需要引入api直接使用)_0.活在风浪里的博客-CSDN博客_vue3+vite​webpack回顾 ​ (移动端打包)一步一步,一步 从代码到,打包成为手机App,上传至nginx服务器 (Vue项目)_0.活在风浪里的博客-CSDN博客_移动端打包一步一步,一步 从代码到,打包成为手机App,上传至ngnix服务器 (Vue项目) https://blog.csdn.net/m0_57904695/article/details/122500485?ops_request_misc=%257B%2522request%255Fid%2522%253A%25221656https://blog.csdn.net/m0_57904695/article/details/125487996?spm=1001.2014.3001.5501封装好的源码已上传主页资源

    先介绍、在贴码,


     Element UI的默认语言是英文。那么如何才能将其改成中文呢?

     封装了一个子组件(table、分页),在不同页面引入

    封装的功能有哪些?

     分页、表格排序、文字居中、溢出隐藏、操作列、开关、宽、最小宽、type类型(selection/index/expand)、格式化 、不同页面不同操作列、vuex、vue持久化插件、(此处没有接口所以用到,还涉及了query与params传值区别)

    子组件 

    说思路:data数据请求接口拿到,表头数据一般也是后台接口,如没,前台可自定义自己写

    最简单示例

    1. //lable指定表头名 //prop指定每一项数据
    2. <el-table :data="tableData">
    3. <el-table-column
    4. :label="item.label"
    5. :prop="item.prop"
    6. :key="index" v-for="(item,index) in tableHeader"
    7. >
    8. </el-table-column>
    9. </el-table>
    10. //表头
    11. tableHeader:[
    12. {label:'姓名' , prop : 'uname'},
    13. {label:'年龄' , prop : 'age'},
    14. {label:'性别' , prop : 'sex'},
    15. ],
    16. //表数据
    17. tableData:[
    18. {uname:"小明",age:'20',sex:'男'},
    19. {uname:"小黑",age:'18',sex:'男'},
    20. ]

    类似这样:

     念及此!那开始正文

    子组件

    1. <template>
    2. <!-- 项目的子组件 封装后的表格、分页 -->
    3. <!-- 表格数据 Start-->
    4. <el-table :data="tableData" height="200" style="width: 100%" border>
    5. <!-- 循环表头 template是不会渲染为dom 在小程序中是block -->
    6. <template v-for="(item, index) in tableHeader" :key="index">
    7. <el-table-column
    8. :prop="item.prop"
    9. :label="item.label"
    10. :align="item.align || 'center'"
    11. :show-overflow-tooltip="item.overHidden || false"
    12. :min-width="item.minWidth || '100px'"
    13. :sortable="item.sortable || false"
    14. :type="item.type || 'normal'"
    15. :fixed="item.fixed"
    16. :width="item.width || ''"
    17. :formatter="stateFormat"
    18. >
    19. <!-- 自定义列 开关-->
    20. <template #default="scope" v-if="item.dataType==='switch'">
    21. <el-switch
    22. v-model="scope.row.status"
    23. active-text="开"
    24. inactive-text="关"
    25. active-color="#13ce66"
    26. inactive-color="#ff4949"
    27. @change="changeSwitchStatus(scope.row.id, scope.row.status)"
    28. />
    29. </template>
    30. <!-- 自定义列 按钮 -->
    31. <!-- <template #default="scope" v-if="item.dataType==='operate'">
    32. <el-button size="small" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
    33. <el-button
    34. size="small"
    35. type="danger"
    36. @click="handleDelete(scope.$index, scope.row)"
    37. >Delete</el-button>
    38. </template>-->
    39. </el-table-column>
    40. </template>
    41. <!-- 自定义列 按钮 -->
    42. <el-table-column fixed="right" label="操作列" :width="operateWidth" v-if="isOperate">
    43. <template #default="scope">
    44. <el-button size="small" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
    45. <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">Delete</el-button>
    46. </template>
    47. </el-table-column>
    48. </el-table>
    49. <!-- 表格数据 End-->
    50. <!-- 分页 Start-->
    51. <el-pagination
    52. :page-sizes="pageSizesArr"
    53. :layout="layout"
    54. :total="total"
    55. @size-change="handleSizeChange"
    56. @current-change="handleCurrentChange"
    57. ></el-pagination>
    58. <!-- 分页 End-->
    59. </template>

    对子组件属性和自定义解释 

     

     子组件全部代码:

    1. <template>
    2. <!-- 项目的子组件 封装后的表格、分页 -->
    3. <!-- 表格数据 Start-->
    4. <el-table :data="tableData" height="200" style="width: 100%" border>
    5. <!-- 循环表头 template是不会渲染为dom 在小程序中是block -->
    6. <template v-for="(item, index) in tableHeader" :key="index">
    7. <el-table-column
    8. :prop="item.prop"
    9. :label="item.label"
    10. :align="item.align || 'center'"
    11. :show-overflow-tooltip="item.overHidden || false"
    12. :min-width="item.minWidth || '100px'"
    13. :sortable="item.sortable || false"
    14. :type="item.type || 'normal'"
    15. :fixed="item.fixed"
    16. :width="item.width || ''"
    17. >
    18. <!-- 自定义列 开关-->
    19. <template #default="scope" v-if="item.dataType==='switch'">
    20. <el-switch
    21. v-model="scope.row.status"
    22. active-text="开"
    23. inactive-text="关"
    24. active-color="#13ce66"
    25. inactive-color="#ff4949"
    26. @change="changeSwitchStatus(scope.row.id, scope.row.status)"
    27. />
    28. </template>
    29. <!-- 加密手机号 -->
    30. <template #default="scope" v-if="item.dataType==='phone'">{{encryptionPhone(scope.row)}}</template>
    31. <!-- 自定义列 按钮 -->
    32. <template #default="scope" v-if="item.dataType==='operate'">
    33. <el-button size="small" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
    34. <el-button
    35. size="small"
    36. type="danger"
    37. @click="handleDelete(scope.$index, scope.row)"
    38. >Delete</el-button>
    39. <el-button size="small" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
    40. <el-button
    41. size="small"
    42. type="danger"
    43. @click="handleDelete(scope.$index, scope.row)"
    44. >Delete</el-button>
    45. </template>
    46. </el-table-column>
    47. </template>
    48. <!-- 自定义列 按钮 -->
    49. <el-table-column fixed="right" label="操作列" :width="operateWidth" v-if="isOperate">
    50. <template #default="scope">
    51. <el-button size="small" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
    52. <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">Delete</el-button>
    53. </template>
    54. </el-table-column>
    55. </el-table>
    56. <!-- 表格数据 End-->
    57. <!-- 分页 Start-->
    58. <el-pagination
    59. :page-sizes="pageSizesArr"
    60. :layout="layout"
    61. :total="total"
    62. @size-change="handleSizeChange"
    63. @current-change="handleCurrentChange"
    64. ></el-pagination>
    65. <!-- 分页 End-->
    66. </template>
    67. <script setup>
    68. import { defineProps, defineEmits, onMounted, reactive } from "vue";
    69. const emits = defineEmits([
    70. "handleSizeChange",
    71. "handleCurrentChange",
    72. "handleChangeSwitchStatus",
    73. ]);
    74. // 表格数据格式化
    75. const stateFormat = (row, column, cellValue, index) => {
    76. // console.log("😂👨🏾‍❤️‍👨🏼==>: ", row.phone);
    77. // if (cellValue != null) {
    78. // const rol = row.phone.slice(0, 3);
    79. // const ral = row.phone.slice(7, 12);
    80. // const pho = rol + "****" + ral;
    81. // return pho;
    82. // }
    83. };
    84. //开关改变事件
    85. const changeSwitchStatus = (rowId, _boolean) => {
    86. emits("handleChangeSwitchStatus", rowId, _boolean);
    87. };
    88. // 操作列 编辑
    89. const handleEdit = (index, row) => {
    90. console.log(" index🚀", index);
    91. console.log(" row🚀", row);
    92. };
    93. // 操作列 删除
    94. const handleDelete = (index, row) => {
    95. console.log(" index🚀", index);
    96. console.log(" row🚀", row);
    97. };
    98. // 页数改变的时候触发的事件
    99. const handleSizeChange = (val) => {
    100. emits("handleSizeChange", val);
    101. };
    102. // 当前页改变的时候触发的事件
    103. const handleCurrentChange = (val) => {
    104. emits("handleCurrentChange", val);
    105. };
    106. // 手机号格式化
    107. const encryptionPhone = (row) => {
    108. // console.log(row);
    109. let phone = row.phone;
    110. if (phone != null) {
    111. const rol = phone.slice(0, 3);//用于截取数组,并返回截取到的新的数组,数组与字符串对象都使用(⚠️:对原数组不会改变)
    112. const ral = phone.slice(7, 12);
    113. const pho = rol + "****" + ral;
    114. return pho;
    115. }
    116. };
    117. const props = defineProps({
    118. // 表格显示的数据
    119. tableData: {
    120. type: Array,
    121. default: function () {
    122. return [];
    123. },
    124. },
    125. // 表头数据
    126. tableHeader: {
    127. type: Array,
    128. default: function () {
    129. return [];
    130. },
    131. },
    132. // 控制操作列是否显示
    133. isOperate: {
    134. type: Boolean,
    135. default: function () {
    136. return false;
    137. },
    138. },
    139. operateWidth: {
    140. type: Number,
    141. default: () => 200,
    142. },
    143. // 总页数
    144. total: {
    145. type: Number,
    146. // 必传类型
    147. required: true,
    148. default: 0,
    149. },
    150. // 分页的页容量数组
    151. pageSizesArr: {
    152. type: Array,
    153. default() {
    154. return [10, 20, 30, 50];
    155. },
    156. },
    157. // 分页的布局
    158. layout: {
    159. type: String,
    160. default: "total, sizes, prev, pager, next, jumper",
    161. },
    162. });
    163. onMounted(() => {
    164. // console.log("!这里输出😂👨🏾‍❤️‍👨🏼==>: ", props.tableData);
    165. // console.log("表格🚀", props.tableData, props.tableHeader, props.isOperate);
    166. // console.log("页容量🚀", props.total);
    167. });
    168. </script>
    169. <style lang="scss">
    170. * {
    171. margin: 0;
    172. padding: 0;
    173. }
    174. .el-switch__label--left {
    175. position: relative;
    176. left: 45px;
    177. color: #fff;
    178. z-index: -1111;
    179. }
    180. .el-switch__core {
    181. width: 50px !important;
    182. }
    183. .el-switch__label--right {
    184. position: relative;
    185. right: 46px;
    186. color: #fff;
    187. z-index: -1111;
    188. }
    189. .el-switch__label--right.is-active {
    190. z-index: 1111;
    191. color: #fff !important;
    192. }
    193. .el-switch__label--left.is-active {
    194. z-index: 1111;
    195. color: #fff !important;
    196. }
    197. </style>

    home页面:

    1. <template>
    2. <h1 style="color:green; text-align: center;">这里是home父组件 , 他们调用一个子组件</h1>
    3. <!-- query 刷新页面,地址栏参数不保存,地址栏不可见 必须在router.ts配置name -->
    4. <el-button
    5. type="primary"
    6. @click="$router.push({path:'/about',query:{id:666}})"
    7. >{{$route.params.id}}----跳转 about</el-button>
    8. <!-- 子组件 Start -->
    9. <comm-table-pagination
    10. :tableData="tableData"
    11. :tableHeader="tableHeader"
    12. :isOperate="isOperate"
    13. :total="total"
    14. :operateWidth="operateWidth"
    15. @handleSizeChange="onHandleSizeChange"
    16. @handleCurrentChange="onHandleCurrentChange"
    17. >
    18. <template v-slot:btn>
    19. <el-button type="success" size="small" @click="$router.push('/about')">跳转 about页面</el-button>
    20. <el-button link type="success" size="small">Edit</el-button>
    21. <el-button link type="success" size="small">Edit</el-button>
    22. <el-button link type="success" size="small">Edit</el-button>
    23. <el-button link type="success" size="small">Edit</el-button>
    24. </template>
    25. </comm-table-pagination>
    26. <!-- 子组件 End -->
    27. </template>
    28. <script setup>
    29. import commTablePagination from "@/components/commTable.vue";
    30. import { reactive, ref, onMounted } from "vue";
    31. // 表格所需的数据
    32. const tableData = reactive([
    33. {
    34. id: 1,
    35. title: "我是title活在风浪里我是title活在风浪里",
    36. status: "启动",
    37. docAuthor: "zhangshan",
    38. submitTime: "2020-06-06 23:58:49",
    39. },
    40. {
    41. id: 2,
    42. title: "我是title活在风浪里我是title活在风浪里",
    43. status: "禁用",
    44. docAuthor: "zhangshan",
    45. submitTime: "2020-06-07 00:10:59",
    46. },
    47. {
    48. title: "我是title活在风浪里我是title活在风浪里",
    49. status: "启动",
    50. docAuthor: "zhangshan",
    51. submitTime: "2020-06-11 08:07:26",
    52. },
    53. {
    54. title: "我是title活在风浪里我是title活在风浪里",
    55. status: "启动",
    56. docAuthor: "zhangshan",
    57. submitTime: "2020-06-11 08:07:26",
    58. },
    59. {
    60. title: "我是title活在风浪里我是title活在风浪里",
    61. status: "启动",
    62. docAuthor: "zhangshan",
    63. submitTime: "2020-06-11 08:07:26",
    64. },
    65. {
    66. title: "我是title活在风浪里我是title活在风浪里",
    67. status: "启动",
    68. docAuthor: "zhangshan",
    69. submitTime: "2020-06-11 08:07:26",
    70. },
    71. ]);
    72. // 表头数据 辅助tableData的数据 这里是自己定义
    73. const tableHeader = reactive([
    74. {
    75. type: "index",
    76. label: "#",
    77. fixed: true,
    78. width: "60px", // 宽度 不指定会 自适应屏幕铺满
    79. },
    80. {
    81. prop: "title",
    82. label: "稿件名称",
    83. overHidden: true, // 超出显示省略号 比如某一行字数多,缩小屏幕就省略号显示
    84. sortable: true,
    85. },
    86. {
    87. prop: "status",
    88. label: "稿件状态",
    89. sortable: true,
    90. },
    91. {
    92. prop: "docAuthor",
    93. label: "作者",
    94. },
    95. {
    96. prop: "submitTime",
    97. label: "提交日期",
    98. sortable: true, // 是否可排序
    99. align: "left", // 对齐方式
    100. width: "120px", // 最小宽度
    101. width: "200px",
    102. },
    103. ]);
    104. const operateWidth = ref(160); // 操作列宽度
    105. const isOperate = ref(true); // 操作列是否显示
    106. const pageSize = ref(10); // 每页显示条数
    107. const pageNum = ref(2); // 当前页码
    108. const total = ref(100); // 总条数
    109. // 分页改变事件
    110. const onHandleSizeChange = (val) => {
    111. pageSize.value = val;
    112. // getData(); 以上数据来自接口,这里是模拟数据,如果是真实数据页数变了,需要再次调用请求后台的接口,重新刷新页面
    113. };
    114. // 当前页改变事件
    115. const onHandleCurrentChange = (val) => {
    116. pageNum.value = val;
    117. // getData(); 以上数据来自接口,这里是模拟数据,如果是真实数据页数变了,需要再次调用请求后台的接口,重新刷新页面
    118. };
    119. </script>

    about页面:

    1. <template>
    2. <h1 style="color:red; text-align: center;">这里是about 父组件 , 他们调用一个子组件</h1>
    3. <!-- params 刷新页面,地址栏参数不保存,不可见 必须在router.ts设置name-->
    4. <el-button
    5. type="primary"
    6. @click="$router.push({ name: 'home', params: {id:'1'}}) "
    7. >{{$route.query.id}}----跳转 home</el-button>
    8. <p>{{ $store.state.count }}</p>
    9. <el-button type="primary" @click="add">点击++</el-button>
    10. <!-- 子组件 Start -->
    11. <comm-table-pagination
    12. :tableData="$store.state.tableData"
    13. :tableHeader="tableHeader"
    14. :isOperate="isOperate"
    15. :total="total"
    16. :operateWidth="operateWidth"
    17. @handleSizeChange="onHandleSizeChange"
    18. @handleChangeSwitchStatus="onHandleChangeSwitchStatus"
    19. ></comm-table-pagination>
    20. <!-- 子组件 End -->
    21. </template>
    22. <script setup>
    23. import commTablePagination from "@/components/commTable.vue";
    24. import { reactive, ref, onMounted } from "vue";
    25. import { useStore } from "vuex";
    26. let store = useStore();
    27. // 表格所需的数据
    28. let tableData = reactive([
    29. {
    30. id: 1,
    31. title: "我是title活在风浪里我是title活在风浪里",
    32. status: true,
    33. docAuthor: "zhangshan",
    34. submitTime: "2020-06-06 23:58:49",
    35. phone: "11288888888",
    36. },
    37. {
    38. id: 2,
    39. title: "我是title活在风浪里我是title活在风浪里",
    40. status: true,
    41. docAuthor: "zhangshan",
    42. submitTime: "2020-06-07 00:10:59",
    43. phone: "15888888888",
    44. },
    45. {
    46. id: 3,
    47. title: "我是title活在风浪里我是title活在风浪里",
    48. status: false,
    49. docAuthor: "zhangshan",
    50. submitTime: "2020-06-11 08:07:26",
    51. phone: "16588888888",
    52. },
    53. {
    54. id: 4,
    55. title: "我是title活在风浪里我是title活在风浪里",
    56. status: true,
    57. docAuthor: "zhangshan",
    58. submitTime: "2020-06-11 08:07:26",
    59. phone: "18588888888",
    60. },
    61. {
    62. id: 5,
    63. title: "我是title活在风浪里我是title活在风浪里",
    64. status: false,
    65. docAuthor: "zhangshan",
    66. submitTime: "2020-06-11 08:07:26",
    67. phone: "16988888888",
    68. },
    69. {
    70. id: 6,
    71. title: "我是title活在风浪里我是title活在风浪里",
    72. status: false,
    73. docAuthor: "zhangshan",
    74. submitTime: "2020-06-11 08:07:26",
    75. phone: "17688888888",
    76. },
    77. ]);
    78. // 表头数据 辅助tableData的数据 这里是自己定义
    79. let tableHeader = reactive([
    80. {
    81. type: "index",
    82. label: "#",
    83. fixed: true,
    84. width: "60px", // 宽度 不指定会 自适应屏幕铺满
    85. },
    86. {
    87. prop: "title",
    88. label: "稿件名称",
    89. overHidden: true, // 超出显示省略号 比如某一行字数多,缩小屏幕就省略号显示
    90. sortable: true,
    91. },
    92. {
    93. prop: "status",
    94. label: "稿件状态",
    95. dataType: "switch", // 自定义列类型
    96. },
    97. {
    98. prop: "docAuthor",
    99. label: "作者",
    100. },
    101. {
    102. prop: "submitTime",
    103. label: "提交日期",
    104. sortable: true, // 是否可排序
    105. align: "left", // 对齐方式
    106. minWidth: "120px", // 最小宽度
    107. width: "200px",
    108. },
    109. {
    110. prop: "phone",
    111. label: "手机号",
    112. dataType: "phone", // 自定义列类型
    113. },
    114. {
    115. label: "操作",
    116. sortable: true, // 是否可排序
    117. minWidth: "120px", // 最小宽度
    118. width: "300px",
    119. dataType: "operate", // 自定义列类型 在子组件判断如果是operate就显示操作按钮
    120. fixed: "right", // 固定列
    121. },
    122. ]);
    123. let operateWidth = ref(300); // 操作列宽度
    124. let isOperate = ref(false); // 操作列是否显示 这个页面用的操作列第二种方式 指定数据,在循环中添加,关闭默认操作列isOperate
    125. let pageSize = ref(10); // 每页显示条数
    126. let pageNum = ref(2); // 当前页码
    127. let total = ref(100); // 总条数
    128. // 分页改变事件
    129. const onHandleSizeChange = (val) => {
    130. pageSize.value = val;
    131. // getData(); 以上数据来自接口,这里是模拟数据,如果是真实数据页数变了,需要再次调用请求后台的接口,重新刷新页面
    132. };
    133. // 当前页改变事件
    134. const onHandleCurrentChange = (val) => {
    135. pageNum.value = val;
    136. // getData(); 以上数据来自接口,这里是模拟数据,如果是真实数据页数变了,需要再次调用请求后台的接口,重新刷新页面
    137. };
    138. //
    139. const onHandleChangeSwitchStatus = (rowId, parameter) => {
    140. tableData.map((v) => {
    141. if (v.id === rowId) {
    142. v.status = parameter;
    143. }
    144. });
    145. store.commit("setTableData", tableData);
    146. };
    147. function add() {
    148. store.commit("increment");
    149. }
    150. onMounted(() => {
    151. if (localStorage.getItem("vuex")) {
    152. store.commit(
    153. "setTableData",
    154. JSON.parse(localStorage.getItem("vuex")).tableData
    155. );
    156. } else {
    157. store.commit("setTableData", tableData);
    158. }
    159. });
    160. </script>

    到此基本已经可以了,可根据实际变化,在变动一下

     

     

    结语:

    祝大家2022愈来愈强! 

  • 相关阅读:
    【算法面试必刷Java版十】两个链表的第一个公共结点
    java毕业设计木材产销系统的生产管理模块mybatis+源码+调试部署+系统+数据库+lw
    智慧经营| 物业数字化管理系统
    spacy教程(持续更新ing...)
    FreeRTOS 延时函数和软件定时器 详解
    vue:功能:table动态合并+前端导出
    内外通、效益增 | 数商云•瓴犀产品3.0开启全方位精准精细化协同模式
    第三章-内存管理
    图片转excel表格怎么弄?有何密笈?
    剑指offer——JZ25 合并两个排序的链表 解题思路与具体代码【C++】
  • 原文地址:https://blog.csdn.net/m0_57904695/article/details/125613767