• 自定义拖拽列表


     效果图

     DataAnalysis.vue

    1. <template>
    2. <div class="app-container">
    3. <div class="operate">
    4. <el-select class="t_select" v-model="templateName" clearable placeholder="模版" size="default" @clear="clearTemplateData" @change="templateData">
    5. <el-option v-for="item in templateList" :key="item.id" :label="item.templateName" :value="item.id"/>
    6. el-select>
    7. <el-button @click="setTemplate" type="primary" size="default">保存模版el-button>
    8. <el-button @click="excelExport" type="primary" size="default">Excel导出el-button>
    9. div>
    10. <main>
    11. <Draggable
    12. class="item-container item-container1"
    13. group="drag"
    14. v-model:list="allProps"
    15. item-key="label"
    16. >
    17. <template #item="{ element }">
    18. <div class="item">{{ element.label }}div>
    19. template>
    20. Draggable>
    21. <Draggable
    22. class="item-container item-container2"
    23. group="drag"
    24. v-model:list="baseProps"
    25. item-key="label"
    26. >
    27. <template #item="{ element }">
    28. <div class="item">{{ element.label }}div>
    29. template>
    30. Draggable>
    31. <Draggable
    32. class="item-container item-container3"
    33. group="drag"
    34. v-model:list="multiLevelProps"
    35. item-key="label"
    36. >
    37. <template #item="{ element }">
    38. <div class="item">{{ element.label }}div>
    39. template>
    40. Draggable>
    41. <Draggable
    42. class="item-container item-container4"
    43. group="drag"
    44. v-model:list="groupProps"
    45. item-key="label"
    46. >
    47. <template #item="{ element }">
    48. <div class="item">{{ element.label }}div>
    49. template>
    50. Draggable>
    51. <el-table :data="brr" border :span-method="objectSpanMethod">
    52. <el-table-column
    53. v-for="item in groupProps"
    54. :prop="item.prop"
    55. :label="item.label"/>
    56. <MultiHeaders
    57. :multiHeaders="multiHeaderValues"
    58. :baseProps="baseProps"
    59. v-if="multiLevelProps && multiLevelProps.length"/>
    60. <el-table-column
    61. v-for="item in baseProps"
    62. :prop="item.prop"
    63. :label="item.label"
    64. v-else/>
    65. el-table>
    66. main>
    67. <el-dialog v-model="isShowTemplate" title="设置模版" width="30%">
    68. <el-form label-width="100px" :model="tForm" style="max-width: 460px">
    69. <el-form-item label="模版名称">
    70. <el-input v-model="tForm.templateName"/>
    71. el-form-item>
    72. el-form>
    73. <template #footer>
    74. <span class="dialog-footer">
    75. <el-button @click="isShowTemplate = false">取消el-button>
    76. <el-button type="primary" @click="saveTemplate">保存el-button>
    77. span>
    78. template>
    79. el-dialog>
    80. div>
    81. template>
    82. <script setup>
    83. import {ref,onMounted, computed,watch,getCurrentInstance} from "vue"
    84. import Draggable from "vuedraggable"
    85. import MultiHeaders from "./MultiHeaders.vue"
    86. import {useRoute} from "vue-router";
    87. import {useStore} from "vuex";
    88. import {useStorage} from "@vueuse/core";
    89. import {parseTime} from "@/utils/ruoyi";
    90. import {getAnalysisTemplate,saveAnalysisTemplate} from "@/api/common/dataAnalysis";
    91. const route = useRoute()
    92. document.title = '数据分析'
    93. const store = useStore()
    94. const {proxy} = getCurrentInstance()
    95. //全部表头属性
    96. const allProps = ref([
    97. {
    98. label: "项目编码",
    99. prop: "businessNo",
    100. },
    101. {
    102. label: "箱号",
    103. prop: "caseNum",
    104. },
    105. {
    106. label: "客户",
    107. prop: "customerName",
    108. },
    109. {
    110. label: "费用类型",
    111. prop: "feeCodeName",
    112. },
    113. {
    114. label: "提单号",
    115. prop: "mblNo",
    116. },
    117. {
    118. label: "币种",
    119. prop: "currencyName",
    120. },
    121. {
    122. label: "数量",
    123. prop: "num",
    124. },
    125. {
    126. label: "金额",
    127. prop: "shouldReceipt",
    128. },
    129. ])
    130. //基础表头属性①
    131. const baseProps = ref([])
    132. //多级表头属性③
    133. const multiLevelProps = ref([])
    134. //分组表头属性②
    135. const groupProps = ref([])
    136. //需要分组的数据
    137. const data = ref([])
    138. const multiHeaderValues = computed(() => {
    139. //获取去重后的multiLevelProps的值
    140. return multiLevelProps.value.map((item) => {
    141. return findGroup(item.prop)
    142. })
    143. })
    144. //选中的模版
    145. const template = ref([])
    146. onMounted(() => {
    147. queryData()
    148. getTemplate()
    149. })
    150. let index = ref(0)
    151. watch([()=>groupProps.value,()=>baseProps.value,()=>multiLevelProps.value,()=>template.value],()=>{
    152. addGroup()
    153. index.value = 0
    154. },{
    155. deep:true
    156. })
    157. function addGroup(){
    158. //获取brr和arr
    159. getBrr()
    160. //排序
    161. // arr.value.forEach(item=>{
    162. // data.value.sort(comprisonFunction(item))
    163. // })
    164. data.value.sort(comprisonFunction(arr.value[0]))
    165. brr.value.sort(comprisonFunction(arr.value[0]))
    166. //对brr去重
    167. goWeight()
    168. //分层级合并列
    169. setTabelRowSpan(brr.value, arr.value);
    170. //合并baseProps中字段
    171. mergeValue()
    172. // console.log(brr.value)
    173. // console.log(results.value)
    174. // console.log(baseProps.value)
    175. // console.log(groupProps.value)
    176. // console.log(multiHeaderValues.value)
    177. // console.log(multiLevelProps.value)
    178. // console.table(brr.value)
    179. }
    180. const brr = ref([])//分组列去重后的数据(groupProps中值的k:v)
    181. const arr = ref([])//要分组的Table属性(groupProps中值的key)
    182. function getBrr(){
    183. brr.value = []
    184. arr.value = []
    185. data.value.forEach((item) => {
    186. let obj={}
    187. for (let i = 0; i < groupProps.value.length; i++) {
    188. let tempObj = {}
    189. tempObj[groupProps.value[i].prop] = item[groupProps.value[i].prop]
    190. obj = {...obj,...tempObj}
    191. if ( arr.value.length < groupProps.value.length){
    192. arr.value.push(groupProps.value[i].prop)
    193. }
    194. }
    195. brr.value.push(obj)
    196. })
    197. }
    198. function goWeight(){
    199. let obj = {};
    200. let tempArr=brr.value
    201. brr.value = tempArr.reduce((curr, next) => {
    202. let str=''
    203. arr.value.forEach(item=>{
    204. str+=next[item]
    205. })
    206. obj[str] ? '' : obj[str]=curr.push(next);
    207. return curr;
    208. }, []);
    209. }
    210. function setTabelRowSpan(tableData, fieldArr){
    211. let lastItem = {};
    212. fieldArr.forEach((field, index) => {
    213. tableData.forEach(item => {
    214. item.mergeCell = fieldArr;
    215. const rowSpan = `rowspan_${field}`
    216. //判断是否合并到上个单元格。
    217. if(fieldArr.slice(0, index + 1).every(e => lastItem[e] === item[e])){
    218. //是:合并行
    219. item[rowSpan] = 0;
    220. lastItem[rowSpan] += 1;
    221. }else{
    222. //否:完成一次同类合并。lastItem重新赋值,进入下一次合并计算。
    223. item[rowSpan] = 1;
    224. lastItem = item;
    225. }
    226. })
    227. })
    228. }
    229. function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    230. //判断当前单元格是否需要合并
    231. if (row.mergeCell.includes(column.property)) {
    232. const rowspan = row[`rowspan_${column.property}`]
    233. if (rowspan) {
    234. return {rowspan: rowspan, colspan: 1};
    235. } else {
    236. return {rowspan: 0, colspan: 0};
    237. }
    238. }
    239. }
    240. function mergeValue(){
    241. if(multiHeaderValues.value.length>0){
    242. butes()
    243. }
    244. brr.value.forEach(item=>{
    245. data.value.forEach(temp=>{
    246. let isTrue = true
    247. arr.value.forEach(arrTmp=>{
    248. if (temp[arrTmp]!==item[arrTmp]){
    249. isTrue = false
    250. }
    251. })
    252. let m_level = ''
    253. multiLevelProps.value.forEach(mpItem=>{
    254. m_level = m_level === '' ? temp[mpItem.prop] : m_level+'_'+temp[mpItem.prop]
    255. })
    256. if (isTrue){//data中每个元素(即对象)的groupProps属性值相等才会合并
    257. baseProps.value.forEach(bpItem=>{
    258. if ((typeof (temp[bpItem.prop])==='number')){//数据类型累加
    259. if(multiLevelProps.value.length!==0){
    260. results.value.forEach(rItem=>{
    261. if(m_level === rItem){
    262. if (temp[bpItem.prop]!==''&&temp[bpItem.prop]!==null){
    263. if (item[bpItem.prop+"_"+rItem]===undefined){
    264. item[bpItem.prop+"_"+rItem]=temp[bpItem.prop]
    265. }else {
    266. item[bpItem.prop+"_"+rItem]=item[bpItem.prop+"_"+rItem] + temp[bpItem.prop]
    267. }
    268. }
    269. }
    270. })
    271. }else{
    272. if (temp[bpItem.prop]!==''&&temp[bpItem.prop]!==null){
    273. if (item[bpItem.prop]===undefined){
    274. item[bpItem.prop]=temp[bpItem.prop]
    275. }else {
    276. item[bpItem.prop]=item[bpItem.prop] + temp[bpItem.prop]
    277. }
    278. }
    279. }
    280. return
    281. }
    282. //字符串类型拼接
    283. if (temp[bpItem.prop]!==''&&temp[bpItem.prop]!==null){
    284. if(multiLevelProps.value.length!==0){
    285. results.value.forEach(rItem=>{
    286. if(m_level === rItem){
    287. if (temp[bpItem.prop]!==''&&temp[bpItem.prop]!==null){
    288. if (item[bpItem.prop+"_"+rItem]===undefined){
    289. item[bpItem.prop+"_"+rItem]=temp[bpItem.prop]
    290. }else {
    291. if (!item[bpItem.prop+"_"+rItem].includes(temp[bpItem.prop]))
    292. item[bpItem.prop+"_"+rItem]=item[bpItem.prop+"_"+rItem] +','+ temp[bpItem.prop]
    293. }
    294. }
    295. }
    296. })
    297. }else {
    298. if (temp[bpItem.prop] !== '' && temp[bpItem.prop] !== null) {
    299. if (item[bpItem.prop] === undefined) {
    300. item[bpItem.prop] = temp[bpItem.prop]
    301. } else {
    302. if (!item[bpItem.prop].includes(temp[bpItem.prop]))
    303. item[bpItem.prop] = item[bpItem.prop] + ',' + temp[bpItem.prop]
    304. }
    305. }
    306. }
    307. }
    308. })
    309. }
    310. })
    311. })
    312. }
    313. //递归循环数据
    314. let results = ref([])
    315. function butes(){
    316. const m_len = multiHeaderValues.value.length
    317. if(m_len>0){
    318. if(m_len >= 2){
    319. results.value = recurse(multiHeaderValues.value[index.value],multiHeaderValues.value[++index.value],m_len,multiHeaderValues.value)
    320. }else{
    321. results.value = multiHeaderValues.value[0]
    322. }
    323. return results.value
    324. }
    325. }
    326. function recurse(arr1,arr2,len,arr){
    327. let newArr = []
    328. arr1.forEach(item=>{
    329. arr2.forEach(item2=>{
    330. newArr.push(item+'_'+item2)
    331. })
    332. })
    333. index.value++
    334. if(index.value < len){
    335. return recurse(newArr,arr[index.value],len,arr)
    336. }else{
    337. return newArr
    338. }
    339. }
    340. function comprisonFunction (propName) {
    341. return function (object1, object2) {
    342. let value1 = object1[propName];
    343. let value2 = object2[propName];
    344. if (value1 > value2 ) {
    345. return -1;
    346. } else if(value1 < value2) {
    347. return 1;
    348. } else {
    349. return 0;
    350. }
    351. }
    352. }
    353. // const obj = ref({})
    354. // const groupArr = ref([])
    355. // function getGroupVal() {
    356. // obj.value = {}
    357. // groupArr.value = []
    358. // for (let i = 0; i < groupProps.value.length; i++) {
    359. // obj.value[groupProps.value[i].prop + 'Arr'] = [];
    360. // groupArr.value[i] = []
    361. // data.value.forEach(item => {
    362. // if (!obj.value[groupProps.value[i].prop + 'Arr'].includes(item[groupProps.value[i].prop])) {
    363. // obj.value[groupProps.value[i].prop + 'Arr'].push(item[groupProps.value[i].prop]);
    364. // let abc = {}
    365. // abc[groupProps.value[i].prop] = item[groupProps.value[i].prop]
    366. // // console.log(abc)
    367. // groupArr.value[i].push(abc)
    368. // }
    369. // })
    370. // }
    371. // }
    372. function findGroup(prop) {
    373. const set = new Set()
    374. data.value.forEach(item => {
    375. set.add(item[prop])
    376. })
    377. //去重后再转换成数组
    378. return Array.from(set)
    379. }
    380. //导出excel时数据表头
    381. function excelHeader(){
    382. const newArr = []
    383. results.value.forEach(rItem=>{
    384. baseProps.value.forEach(item=>{
    385. let arr = []
    386. arr.push(item.prop+"_"+rItem)
    387. newArr.push(arr)
    388. })
    389. })
    390. return newArr
    391. }
    392. function generateArray() {
    393. const rows = [] //多重表头例如[[1,2,3][4,5]]
    394. const ranges = [] //合并单元格
    395. const mainLength = groupProps.value.length
    396. //所有多重表头(包括最后一行)
    397. const headers = multiHeaderValues.value.concat([baseProps.value])
    398. //数据表头
    399. const mHeader = excelHeader()
    400. //所有多重表头长度乘积
    401. const allCols = headers.reduce((res, cur) => {
    402. return res * cur.length
    403. }, 1)
    404. let colspan = allCols // 4 总共需要的单元格
    405. for (let i = 0; i < headers.length; i++) {
    406. const curRow = headers[i]
    407. //需要合并的单元格数量
    408. colspan = colspan / curRow.length
    409. //需要重复的次数
    410. const cycleTime = allCols / colspan / curRow.length
    411. let row = new Array(mainLength).fill('')
    412. if (i === headers.length - 1) {
    413. row = [...groupProps.value]
    414. }
    415. for (let k = 0; k < cycleTime; k++) {
    416. curRow.forEach((val, index) => {
    417. const C = index * colspan + k * curRow.length * colspan + mainLength
    418. const range = {s: {r: i, c: C}, e: {r: i, c: C + colspan - 1}}
    419. if (colspan > 1) ranges.push(range)
    420. row.push(val)
    421. for (let j = 1; j < colspan; j++) {
    422. row.push("")
    423. }
    424. })
    425. }
    426. rows.push(row)
    427. }
    428. // for(let m=0;m
    429. // ranges.push(
    430. // {
    431. // s:{
    432. // r:headers.length-1,
    433. // c:m
    434. // },
    435. // e:{
    436. // r:0,
    437. // c:m
    438. // }
    439. // }
    440. // )
    441. // }
    442. return {
    443. ranges,
    444. rows,
    445. mHeader
    446. }
    447. }
    448. //报表导出
    449. function excelExport() {
    450. import("@/utils/Export2Excel").then((excel) => {
    451. // const tHeader = groupProps.value.map((item)=>item.name)
    452. // const filterVal = groupProps.value.map((item)=>item.prop)
    453. const {ranges, rows,mHeader} = generateArray()
    454. const tHeader = rows[rows.length - 1].map((item) => item.label)
    455. // const filterVal = rows[rows.length - 1].map((item) => item.prop)
    456. const multiHeader = rows.slice(0, -1)
    457. const gHeader = groupProps.value.map((item)=>item.prop)
    458. const filterVal = gHeader.concat(mHeader.map((item)=>item[0]))
    459. const TData = formatJson(filterVal, brr.value)
    460. excel.export_json_to_excel({
    461. header: tHeader,
    462. multiHeader: multiHeader,
    463. data: TData,
    464. filename: "数据分析",
    465. merges: ranges,
    466. autoWidth: true,
    467. bookType: "xlsx",
    468. })
    469. })
    470. }
    471. function formatJson(filterVal, jsonData) {
    472. return jsonData.map((v) =>
    473. filterVal.map((j) => {
    474. return v[j]
    475. })
    476. )
    477. }
    478. const myOrigin = window.location.origin
    479. function queryData(){
    480. window.addEventListener('message',function (e) {
    481. if (e.origin === myOrigin) {
    482. document.title = e.data.title+'-数据分析'
    483. if (e.data.isPush) {
    484. data.value = JSON.parse(e.data.data)
    485. allProps.value = JSON.parse(e.data.allProps)
    486. data.value.forEach(item=>{
    487. //业务类型
    488. if(item.businessType === 0){
    489. item.businessType = '海运出口'
    490. } else if(item.businessType === 1){
    491. item.businessType = '空运出口'
    492. } else if(item.businessType === 2){
    493. item.businessType = '海运进口'
    494. }
    495. //单据日期
    496. if(item.glMarineSpecialOutDTO.id){
    497. item.expectSailingStartDate = parseTime(item.glMarineSpecialOutDTO.expectSailingStartDate, "{y}-{m}-{d}")
    498. } else if(item.glMarineImportOutDTO.id){
    499. item.expectSailingStartDate = parseTime(item.glMarineImportOutDTO.expectSailingStartDate, "{y}-{m}-{d}")
    500. } else if(item.glAirExportOutDTO.id){
    501. item.expectSailingStartDate = parseTime(item.glAirExportOutDTO.expectSailingStartDate, "{y}-{m}-{d}")
    502. }
    503. //装运日期
    504. if(item.glMarineSpecialOutDTO.shipmentDate){
    505. item.shipmentDate = parseTime(item.glMarineSpecialOutDTO.shipmentDate, "{y}-{m}-{d}")
    506. }
    507. //送达日期
    508. if(item.glMarineSpecialOutDTO.deliveryDate){
    509. item.deliveryDate = parseTime(item.glMarineSpecialOutDTO.deliveryDate, "{y}-{m}-{d}")
    510. }
    511. //预计到港日期
    512. if(item.glMarineSpecialOutDTO.expectSailingArrivalDate){
    513. item.expectSailingArrivalDate = parseTime(item.glMarineSpecialOutDTO.expectSailingArrivalDate, "{y}-{m}-{d}")
    514. } else if(item.glMarineImportOutDTO.id){
    515. item.expectSailingArrivalDate = parseTime(item.glMarineImportOutDTO.expectSailingArrivalDate, "{y}-{m}-{d}")
    516. } else if(item.glAirExportOutDTO.id){
    517. item.expectSailingArrivalDate = parseTime(item.glAirExportOutDTO.expectSailingArrivalDate, "{y}-{m}-{d}")
    518. }
    519. //预计开航日期
    520. if(item.glMarineSpecialOutDTO.expectSailingStartDate){
    521. item.expectSailingStartDate = parseTime(item.glMarineSpecialOutDTO.expectSailingStartDate, "{y}-{m}-{d}")
    522. } else if(item.glMarineImportOutDTO.id){
    523. item.expectSailingStartDate = parseTime(item.glMarineImportOutDTO.expectSailingStartDate, "{y}-{m}-{d}")
    524. } else if(item.glAirExportOutDTO.id){
    525. item.expectSailingStartDate = parseTime(item.glAirExportOutDTO.expectSailingStartDate, "{y}-{m}-{d}")
    526. }
    527. })
    528. let obj = {
    529. data:data.value,
    530. allProps:allProps.value
    531. }
    532. useStorage(e.data.tableName,JSON.stringify(obj))
    533. } else {
    534. let arr = JSON.parse(useStorage(e.data.tableName).value)
    535. data.value = arr.data
    536. allProps.value = arr.allProps
    537. }
    538. }
    539. })
    540. }
    541. //保存模版
    542. //被选中的模版
    543. const templateName = ref('')
    544. const isShowTemplate = ref(false)
    545. const tForm = ref({
    546. templateName:''
    547. })
    548. //模版弹窗
    549. function setTemplate(){
    550. isShowTemplate.value = true
    551. }
    552. //所有的模版
    553. const templateList = ref([])
    554. //从数据库中获取当前用户的所有模版数据
    555. function getTemplate(){
    556. getAnalysisTemplate({
    557. employeeId: store.state.user.info.id,
    558. pageNum:1,
    559. pageSize:100
    560. }).then(res => {
    561. templateList.value = res.data.records
    562. })
    563. }
    564. //将模版数据保存数据库
    565. function saveTemplate(){
    566. let params = {
    567. "employeeId": store.state.user.info.id,
    568. "templateName": tForm.value.templateName,
    569. "data":JSON.stringify({
    570. "baseProps":JSON.stringify(baseProps.value),
    571. "groupProps": JSON.stringify(groupProps.value),
    572. "multiLevelProps": JSON.stringify(multiLevelProps.value),
    573. "multiHeaderValues": JSON.stringify(multiHeaderValues.value)
    574. })
    575. }
    576. saveAnalysisTemplate(params).then(response => {
    577. isShowTemplate.value = false
    578. getTemplate()
    579. proxy.$modal.msgSuccess("保存成功");
    580. })
    581. }
    582. //根据模版获取数据生成数据报表
    583. function templateData(val){
    584. if(val !== undefined){
    585. templateList.value.forEach(item=>{
    586. if(item.id === val){
    587. template.value = JSON.parse(item.data)
    588. }
    589. })
    590. if(template.value.hasOwnProperty("baseProps")){
    591. baseProps.value = JSON.parse(template.value.baseProps)
    592. groupProps.value = JSON.parse(template.value.groupProps)
    593. multiLevelProps.value = JSON.parse(template.value.multiLevelProps)
    594. multiHeaderValues.value = JSON.parse(template.value.multiHeaderValues)
    595. }
    596. }
    597. }
    598. function clearTemplateData(){
    599. template.value =[]
    600. baseProps.value = []
    601. groupProps.value = []
    602. multiLevelProps.value = []
    603. multiHeaderValues.value = []
    604. }
    605. script>
    606. <style lang="scss" scoped>
    607. .item {
    608. background: #333;
    609. padding: 5px;
    610. }
    611. .item-container {
    612. background: #eee;
    613. padding: 10px;
    614. display: flex;
    615. min-height: 51px;
    616. align-self: flex-start;
    617. flex-wrap: wrap;
    618. align-items: flex-start;
    619. gap: 10px;
    620. cursor: move;
    621. color: #ccc;
    622. }
    623. .item-container1 {
    624. grid-column: 1/3;
    625. }
    626. main {
    627. display: grid;
    628. gap: 10px;
    629. // margin-top: 10px;
    630. grid-template-columns: 200px 1fr;
    631. }
    632. .operate{
    633. margin-bottom: 5px;
    634. .t_select{
    635. margin-right: 12px;
    636. }
    637. }
    638. style>

    MultiHeaders.vue

    1. <template>
    2. <el-table-column v-for="item in headers" :label="item.name">
    3. <template v-if="item.child.length>0">
    4. <multi-header v-if="item.child.length>0" :child="item.child" :baseProps="baseProps" :upProp="item.prop">multi-header>
    5. template>
    6. <el-table-column v-else v-for="bItem in baseProps" :label="bItem.label" :prop="bItem.prop+'_'+item.prop" >el-table-column>
    7. el-table-column>
    8. template>
    9. <script setup>
    10. import {computed, watch} from "vue"
    11. import MultiHeader from "@/views/configTable/MultiHeader.vue";
    12. const props = defineProps({
    13. multiHeaders: { //右边款字段的值=table表头
    14. typeof: Array,
    15. default: [],
    16. },
    17. baseProps: { // 左上框数据
    18. typeof: Array,
    19. default: [],
    20. },
    21. upProp: {
    22. typeof: String,
    23. default: '',
    24. },
    25. })
    26. function childData(list,i){
    27. const arr = []
    28. //最后一个数组
    29. if(ilength){
    30. list[i].forEach(item=>{
    31. const obj = {
    32. name:'',
    33. prop:'',
    34. child:[]
    35. }
    36. obj['name'] = item
    37. obj['prop'] = item
    38. obj['child'] = []
    39. arr.push(obj)
    40. })
    41. }
    42. return arr
    43. }
    44. function transListDataToTreeData(list,i) {
    45. //共3条数据
    46. const arr = list[i] // 第一层数组 1
    47. if(arr){
    48. const news = []
    49. arr.forEach(item=>{
    50. let obj = {
    51. name:item,
    52. prop:item,
    53. child:[]
    54. }
    55. const child = childData(list,i+1)
    56. if(child.length > 0){
    57. obj.child = transListDataToTreeData(list,i+1)
    58. }else{
    59. obj.child = child
    60. }
    61. news.push(obj)
    62. })
    63. return news
    64. }else{
    65. return []
    66. }
    67. }
    68. function sliceArr(arr,size){
    69. const res = []
    70. for (let i=0;i<Math.ceil(arr.length/size);i++){
    71. let start = i*size
    72. let end = start + size
    73. res.push(arr.slice(start,end))
    74. }
    75. return res
    76. }
    77. const headers = computed(() => {
    78. // return props.multiHeaders[0]
    79. return transListDataToTreeData(props.multiHeaders,0)
    80. })
    81. const subHeaders = computed(() => {
    82. return props.multiHeaders.slice(1)
    83. })
    84. watch(
    85. () => headers.value,
    86. (value) => {
    87. console.log(value)
    88. }
    89. )
    90. script>
    91. <style lang="scss" scoped>style>

  • 相关阅读:
    ElementPlus非表单组件ElUpload值更新后校验不消失问题
    为什么STM32的HAL库那么难用?
    python/pygame 挑战魂斗罗 笔记(三)
    安杰思医学冲刺科创板:​年营收3亿 拟募资7.7亿
    Excel 快速分析
    前端包管理器的简介,pnpm的使用以及和npm的区别
    【memcpy函数的介绍与使用和模拟实现】
    EAP-TLS实验之Ubuntu20.04环境搭建配置(FreeRADIUS3.0)(四)
    大厂真题:【DP】米哈游2023秋招-米小游与魔法少女-奇运
    主流图像处理 Python 库汇总
  • 原文地址:https://blog.csdn.net/ahwangzc/article/details/134244678