当前位置:   article > 正文

vue3.2二次封装antd vue 中的Table组件,原有参数属性不变

vue3.2二次封装antd vue 中的Table组件,原有参数属性不变

vue3.2中的<script setup>语法

在项目中多处使用到表格组件,所以进行了一个基础的封装,主要是通过antd vue 中表格的slots配置项,通过配合插槽来进行封装自定义表格;

这次主要的一个功能是编辑之后变成input框 修改了之后变成完成发送请求重新渲染表格:

子组件的代码:这样封装不会改变antd 官网示例参数的传递方式
  1. <template>
  2. <!-- v-bind处理a-table 传递过来的参数-->
  3. <a-table ref="KldTable" class="kld-table" v-bind="attrs">
  4. <!-- 处理 slots ,动态渲染插槽需要使用这种方式-->
  5. <template v-for="key in renderArr " #[key]="{ record, column, text, index }">
  6. <!-- 通过这个插槽传递数据给父组件,做一些编辑提交的操作等等 -->
  7. <slot :name="key" :text="text" :column="column" :record="record" :index="index"></slot>
  8. </template>
  9. </a-table>
  10. </template>
  11. <script lang="ts">
  12. import { ref,useSlots } from 'vue';
  13. import { Table } from 'ant-design-vue';
  14. export default {
  15. name: "KldTable",
  16. setup(_, { attrs, emit }) {
  17. // 插槽的实例
  18. const slots = useSlots()
  19. const renderArr = Object.keys(slots)
  20. return {
  21. attrs,
  22. listeners: emit,
  23. KldTable: ref(),
  24. renderArr
  25. };
  26. },
  27. components: {
  28. ATable: Table
  29. }
  30. };
  31. </script>

 父组件的使用:子组件全局注册了,所以父组件没有引入

  1. <template>
  2. <kld-table :columns="columns" :data-source="dataSource">
  3. <!-- 通过columns 里面对象来遍历生成 可编辑的组件, 不能编辑序号是因为是因为没有传过去slots , 所以及时columns里面包含序号,但是由于表格组件渲染插槽没有他,所以不会序号不可编辑,通过给操作自定义一个属性,来避免渲染生成操作-->
  4. <template v-slot:[item.dataIndex]="{ record, text, column }" v-for="item in columns">
  5. <!-- 通过v-for生成 因为每个选项都需要变成input框所以用遍历,但是操作一列有自己的方式所以不需要,于是我就在操作一列无需添加插件属性slots,表示他不一样 -->
  6. <div :key="item.dataIndex">
  7. <span v-if="!record.isEdit">
  8. <span v-if="item.type === 'Select'">
  9. {{ getLabel(column.options, text) }}
  10. </span>
  11. <span v-else>
  12. {{ text }}
  13. </span>
  14. </span>
  15. <span v-else>
  16. <a-input-number size="small" v-model:value="record[item.dataIndex]"
  17. v-if="item.type === 'inputNumber'"></a-input-number>
  18. <a-select v-else-if="item.type === 'Select'" v-model:value="record[item.dataIndex]">
  19. <a-select-option v-for="option in column.options" :key="option.value" :value="option.value">
  20. {{ option.label }}
  21. </a-select-option>
  22. </a-select>
  23. <a-input size="small" v-else v-model:value="record[item.dataIndex]"></a-input>
  24. </span>
  25. </div>
  26. </template>
  27. <!-- 自定义表头样式 -->
  28. <template #headerCell="{ column }">
  29. <template v-if="column.dataIndex === 'ResourceName'">
  30. <span>
  31. <smile-outlined />
  32. {{ column.title }}
  33. </span>
  34. </template>
  35. </template>
  36. <!-- 自定义操作区域 -->
  37. <template #bodyCell="{ column, record, index }">
  38. <template v-if="column.dataIndex === 'operation'">
  39. <a-button :type="record.isEdit ? 'primary' : 'text'" @click="editPoint(record, column, index)">{{
  40. record.isEdit ? '完成' : '编辑' }}</a-button>
  41. <span v-if="!record.isEdit">
  42. <a-button type="text">详情</a-button>
  43. <a-popconfirm placement="top" ok-text="确认" cancel-text="取消">
  44. <template #title>
  45. <p>确定删除该扫描节点?</p>
  46. </template>
  47. <a-button type="text">删除</a-button>
  48. </a-popconfirm>
  49. </span>
  50. <span v-else>
  51. <a-button type="text" @click="cancelEdit(record)">取消</a-button>
  52. </span>
  53. </template>
  54. </template>
  55. </kld-table>
  56. </template>
  57. <script setup lang="ts">
  58. // import MyTable from './table.vue'
  59. import { SmileOutlined, } from '@ant-design/icons-vue';
  60. import { message, SelectProps } from 'ant-design-vue';
  61. const isEdit = ref<boolean>(false)
  62. const columns = [
  63. {
  64. title: '序号',
  65. dataIndex: 'numbers',
  66. key: 'numbers',
  67. width: '6%'
  68. },
  69. {
  70. title: '资源名称',
  71. dataIndex: 'ResourceName',
  72. slots: { customRender: 'ResourceName' }, //slots这个是重点,通过这个相当于告诉表格组件我有一个具名插槽要用,名字就是customRender后面的名字, 父组件中的useSlots插槽的实例就有这个ResourceName,下面也一样
  73. width: '12%'
  74. },
  75. {
  76. title: '资源名称IP',
  77. dataIndex: 'IP',
  78. slots: { customRender: 'IP' },
  79. width: '12%'
  80. },
  81. {
  82. title: '数据库类型',
  83. dataIndex: 'DatabaseType',
  84. slots: { customRender: 'DatabaseType' },
  85. width: '12%'
  86. },
  87. {
  88. title: '数据库名',
  89. dataIndex: 'Dbname',
  90. slots: { customRender: 'Dbname' },
  91. width: '12%',
  92. },
  93. {
  94. title: 'Select选择器',
  95. dataIndex: 'Username',
  96. slots: { customRender: 'Username' },
  97. width: '12%',
  98. type: 'Select',
  99. options: [] as any,
  100. },
  101. {
  102. title: '数字类型',
  103. dataIndex: 'Quantity',
  104. slots: { customRender: 'Quantity' },
  105. width: '12%',
  106. type: 'inputNumber'
  107. },
  108. {
  109. title: '操作',
  110. dataIndex: 'operation',
  111. }
  112. ]
  113. const dataSource = ref([
  114. {
  115. numbers: 1,
  116. Username: '1',
  117. Dbname: '测试2',
  118. DatabaseType: '3',
  119. ResourceName: 'ces1',
  120. IP: '3333',
  121. Quantity: 99
  122. }, {
  123. numbers: 2,
  124. Username: '2',
  125. Dbname: '测试2',
  126. DatabaseType: '8900',
  127. ResourceName: '777',
  128. IP: '55',
  129. Quantity: 101
  130. }
  131. ])
  132. //当前组件挂载时设置初始 Select选择器的下拉数据
  133. onMounted(async () => {
  134. const i = columns.findIndex((ele: any) => ele.dataIndex === 'Username');
  135. columns[i].options = [
  136. {
  137. value: '1',
  138. label: '文本',
  139. },
  140. {
  141. value: '2',
  142. label: '数字',
  143. },
  144. ];
  145. });
  146. const editPoint = (record: any, column: any, index: any) => {
  147. console.log(record, 666, column, index);
  148. if (isEdit.value) {
  149. message.warning('有其他项正在编辑,请先完成');
  150. } else {
  151. // 触发显示input
  152. record.isEdit = true
  153. isEdit.value = true
  154. }
  155. }
  156. // 取消编辑
  157. const cancelEdit = (record: any) => {
  158. record.isEdit = false
  159. isEdit.value = false
  160. }
  161. // 处理下拉数据回显
  162. const getLabel = (options: SelectProps['options'], value: string) => {
  163. if (options?.length !== 0 && (value || value === '0')) {
  164. return options.find((item) => {
  165. return item.value === value;
  166. })?.label;
  167. }
  168. };
  169. </script>

效果图如下:追加显示下拉选择器,数字,已经正常输入框

 追加效果图

父组件中的删除,详情,取消,完成,按钮功能自行发挥这里就不写具体的操作细节,父组件功能还在不断更新中

仅供参考,如果有不对的还请各位大佬指教

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/article/detail/41365
推荐阅读
相关标签
  

闽ICP备14008679号