el-table 指定表格合并行与单元格,以及表头合并单元格

news2024/11/20 3:29:36

 

 

1:页面html

<template>
  <div class="container">
    <div class="flex-end">
      <el-button type="primary" @click="allEndBtn">批量办结</el-button>
      <el-button type="primary" @click="downLoadBtn">导出</el-button>
      <el-button type="primary" @click="printBtn">打印</el-button>
      <el-button type="primary" @click="backBtn">返回</el-button>
    </div>
    <div class="flex-center red lineH40 fontSize16">
        生成汇总签单成功,可到汇总签单数据列表查看审批情况
    </div>
    <div class="lineH30">
      <div class="flex-center fontSize18">{{tableTitle}}</div> 
      <div class="flex-center fontSize18">{{ tableName }}</div>
      <div class="flex-center fontSize12">
         填单日期:{{ tableCreatTime }}
      </div>
    </div> 
    <div class="" ref="hzqdREF">
      <div class="flex-end">编号:{{ codeNum }}</div>
      <el-table
        :data="tableData"
        :span-method="objectSpanMethod"
        border
        style="width: 100%; margin-bottom: 20px"
        :header-cell-style="headerCellStyle"
        :cell-style="{textAlign:'center'}">
        <el-table-column
          prop="label"
          label="会签项目"
          width="150">
          <template slot-scope="scope">
            <div v-if="scope.$index==3">{{ scope.row.label }}</div> 
            <div v-else>{{ scope.row.label }}</div>
          </template>
        </el-table-column>
        <el-table-column
          prop=""
          label=""
          width="60">
          <template slot-scope="scope">
            <div v-if="scope.$index==3">小写</div>
            <div v-else-if="scope.$index==4">大写</div>
            <div v-else>{{ scope.row.labelLater }}</div>
          </template>
        </el-table-column>
        <el-table-column 
          min-width="160"
          prop="labelLater"
          :label="tableObj.projectName">
          <template slot-scope="scope">
            <div v-if="scope.$index==3||scope.$index==4">
                {{ scope.row.labelLater }}
            </div>
            <div v-else>{{ scope.$index+1 }}</div>
          </template>
        </el-table-column>
        <el-table-column
          width="60"
          prop="index"
          label="序号">
          <template slot-scope="scope">
            <div v-if="scope.$index==3||scope.$index==4">
                {{ scope.$index+1 }}
            </div>
            <div class="flex" v-else>
              <div>{{ scope.row.unit }}</div> 
              <div>
                <div class="backTag " v-if="scope.row.backed==1">
                <div class="sanJiao"></div>
                <div class="backColor">有退回</div>
              </div>
            </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column
          min-width="260"
          prop="unit"
          label="单位/内容">
          <template slot-scope="scope">
            <div class="flex" v-if="scope.$index==3||scope.$index==4">
              <div>{{ scope.row.unit }}</div> 
              <div>
                <div class="backTag " v-if="scope.row.backed==1">
                <div class="sanJiao"></div>
                <div class="backColor">有退回</div>
              </div>
            </div>
            </div>
            <div v-else>{{ scope.row.amount }}</div>
          </template>
        </el-table-column>
        <el-table-column
          width="120"
          prop="amount"
          label="金额">
          <template slot-scope="scope">
            <div v-if="scope.$index==3||scope.$index==4">
                {{ scope.row.amount }}
            </div>
            <div v-else></div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div v-if="bottomTableData.length>0" ref="bottomTableREF">
      <el-table
        class="margin-B30" 
        v-loading="loading"
        :data="bottomTableData"
        :border="true"
        style="width: 100%"
        :header-cell-style="{textAlign:'center'}"
        :cell-style="{textAlign:'center'}">
        <el-table-column fixed label="处理人" width="100">
          <template slot-scope="scope">
            {{ scope.row.userName }}
          </template>
        </el-table-column>
        <el-table-column fixed label="处理单位" width="200">
          <template slot-scope="scope">
            {{ scope.row.unitName }}
          </template>
        </el-table-column>
        <el-table-column fixed label="处理时间" width="100">
          <template slot-scope="scope">
            {{ scope.row.creatTime }}
          </template>
        </el-table-column>
        <el-table-column fixed label="付款申请编号" width="160">
          <template slot-scope="scope">
            {{ scope.row.paymentCode }}
          </template>
        </el-table-column>
        <el-table-column fixed label="申请金(元)" width="130">
          <template slot-scope="scope">
            {{ scope.row.applyAmount }}
          </template>
        </el-table-column>
        <el-table-column fixed label="处理意见" min-width="240">
          <template slot-scope="scope">
            {{ scope.row.opinion }}
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

2:js部分

<script>
import { downloadPdf, printPdf } from "@/utils/index";
import { numberToQianFenWei } from "@/utils/qianFenWei.js";
export default {
  data () {
    return {
      tableTitle:"上海申通地铁建设集团有限公司",
      tableName:"工程项目汇总签单",
      tableCreatTime:"2023年06月10日",
      codeNum:"",
      mergeObj: {}, // 用来记录需要合并行的下标
      // 表格中的列名
      tableProps: [
        'label',
        'labelLater',
        'index',
        'unit',
        'amount',
      ] ,
      tableData: [],
      tableObj:{
        projectName:"会签项目111",// 会签项目
        paymentDate:"支付日期22",// 支付日期
        allcCountersign:"会签总笔数33",// 会签总笔数
        dataList:"单据数量44",// 单据数量
        countersignAllAmount:"11111",// 会签总金额
        countersignAllAmountDX:"十一元整",// 会签总金额
        CWFZRsign:"财务负责人签字",// 财务负责人签字
        JTDSZsign:"集团董事长签字",// 集团董事长签字
      },
      loading:false,
      bottomTableData:[{}],
    };
  },
  watch:{
    "tableData":function (newVal,oldVal){
      if(newVal.length>0){
        this.getSpanArr(this.tableData);
      }
    }
  },
  created () {
    // 
    setTimeout(()=>{
      this.getData();
    },1000)
  },
  computed: {
    // 千分位元 保留两位小数
    QFWYBLLWXS(){
      return (val) => {
        if(val===null||val===""){
          return "";
        }else if(val==="0"||val===0){
          return "0.00";
        }else{
          let LiangWeiXaioShu=(val-0).toFixed(2);
          if( isNaN(LiangWeiXaioShu)){
            return "";
          }else{
            if(LiangWeiXaioShu>=0){
              return numberToQianFenWei(LiangWeiXaioShu);
            }else{
              return "-"+numberToQianFenWei(
                String(LiangWeiXaioShu).slice(1)
              );
            }
          } 
        }
      }
    }
  },
  methods:{
    // 批量办结
    allEndBtn(){},
    // 导出
    downLoadBtn(){
      downloadPdf(
        this.$refs["refsPayOrderListTable"],
        this.tableTitle + this.tableName,
        "1300px",
        this.codeNum,
        {
          textAlign: "left",
          font: "30px Vedana",
          x: 10,
          conHeight: 500,
          conWidth: 600,
        }
      );
      if(this.$refs["bottomTableREF"]){
        downloadPdf(
            this.$refs["bottomTableREF"],
            this.tableTitle + this.tableName + '意见',
            "1300px",
            this.codeNum,
            {
              textAlign: "left",
              font: "30px Vedana",
              x: 10,
              conHeight: 500,
              conWidth: 1000,
            }
        );
      }
    },
    // 打印
    printBtn(){
      if(this.bottomTableData.length > 0){
        this.$refs["bottomTableREF"].style.width =  '1530px'
        printPdf(
            [this.$refs["hzqdREF"],this.$refs["bottomTableREF"],],
            "",
            "",
            "1",
            this.codeNum,
            {
              textAlign: "left",
              font: "30px Vedana",
              x: 10,
              conHeight: 500,
              conWidth: 1000,
            }
        );
        setTimeout(() => {
          this.$refs["bottomTableREF"].style.width =  ''
        }, 500)
      } else {
        printPdf(
            [this.$refs["hzqdREF"]],
            "",
            "",
            "1",
            this.codeNum,
            {
              textAlign: "left",
              font: "30px Vedana",
              x: 10,
              conHeight: 500,
              conWidth: 1000,
            }
        );
      }
    },
    // 返回
    backBtn(){
      this.$router.go(-1);
    },
    //表格头部样式
    headerCellStyle({ row, column, rowIndex, columnIndex }){
      // 第一步:设置表头的第0列暂不操作,将地1列和第2列隐去使其消失
      if ((columnIndex == 1)) {
        return { display: "none" };
      }
      // // 第二步, 由于1、2列没有了,后续列就会贴上来(后续列往左错位问题)
      if ((rowIndex == 0) & (columnIndex == 0)) {
        // 解决后续列错位问题,就是将隐去的第1列的位置再补上,通过第0列来补
        this.$nextTick(() => {
          /*原来第0列只占据一个位置,现在要去占据两个位置。
            即占据两列,即设置为横向两个单元格
          */ 
        document.querySelector(`.${column.id}`).setAttribute("colspan", "2");
          /*这里的column.id实际是dom元素的class,
            故用点.不用井#,可审查dom验证
            所以 --通过设置原生的colspan属性,
            让原来的第一列只占据一个单元格的表头占据2个单元格即可
          */  
        });
      }
      return { textAlign:'center',backgroundColor:"white", }
    },
    // getSpanArr方法
    getSpanArr(data) {
      this.tableProps.forEach(propVal=> {
        let count = 0; // 用来记录需要合并行的起始位置
        this.mergeObj[propVal] = []; // 记录每一列的合并信息
        data.forEach((item, index) => {
          // index == 0表示数据为第一行,直接 push 一个 1
          if(index === 0) {
            this.mergeObj[propVal].push(1);
          } else {
            /*判断当前行是否与上一行其值相等
            如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 
            并push 一个 0 作为占位
            */  
            if(item[propVal] === data[index - 1][propVal]) { 
              this.mergeObj[propVal][count] += 1;
              this.mergeObj[propVal].push(0);
            } else {
              // 如果当前行和上一行其值不相等 
              count = index; // 记录当前位置 
              this.mergeObj[propVal].push(1); // 重新push 一个 1
            }
          }
        })
      })
    },
    // objectSpanMethod方法
    /*默认接受四个值
        ----row==当前行的数据
        ----column==当前列的数据
        ----rowIndex==行的下标
        ----columnIndex==列的下标
    */
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 只有 第一列  合并行
      if(columnIndex===0){
        // 判断列的属性
        if(this.tableProps.indexOf(column.property) !== -1) {
          // 判断其值是不是为0 
          if(this.mergeObj[column.property][rowIndex]) { 
            return {
              rowspan: this.mergeObj[column.property][rowIndex],
              colspan: rowIndex===3?1: 2
            };
          } else {
            // 如果为0则为需要合并的行
            return {
              rowspan: 0,
              colspan: 0
            }; 
          }
        }
      }
    },
    // 获取表格数据
    getData(){
      this.tableData=[];
      //{},{},{},{},{},{},{},{},{}, {unit:"a阿萨达"}
      this.tableData=[];
      if(this.tableData.length<10){
        let zeroData={
          label:"支付日期",
          labelLater:this.tableObj.paymentDate,
          unit:this.tableData[0]!=undefined?
            this.tableData[0].unit:"阿达阿达是的",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"1",
          amount:this.tableData[0]!=undefined?this.tableData[0].amount:""
        };
        let oneData={
          label:"会签总笔数",
          labelLater:this.tableObj.allcCountersign,
          unit:this.tableData[1]!=undefined?
            this.tableData[1].unit:"阿达阿达是的阿达阿达是",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[1]!=undefined?this.tableData[1].amount:""
        };
        let twoData={
          label:"单据数量",
          labelLater:this.tableObj.dataList,
          unit:this.tableData[2]!=undefined?this.tableData[2].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[2]!=undefined?this.tableData[2].amount:""
        };
        let threeData={
          label:"会签总金额",
          labelLater:this.QFWYBLLWXS(this.tableObj.countersignAllAmount),
          unit:this.tableData[3]!=undefined?this.tableData[3].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[3]!=undefined?this.tableData[3].amount:""
        };
        let fourData={
          label:"会签总金额",
          labelLater:this.tableObj.countersignAllAmountDX,
          unit:this.tableData[4]!=undefined?this.tableData[4].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[4]!=undefined?this.tableData[4].amount:""
        };
        let fiveData={
          label:"财务负责人",
          labelLater:this.tableObj.CWFZRsign,
          unit:this.tableData[5]!=undefined?this.tableData[5].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[5]!=undefined?this.tableData[5].amount:""
        };
        let sixData={
          label:"集团董事长",
          labelLater:this.tableObj.JTDSZsign,
          unit:this.tableData[6]!=undefined?this.tableData[6].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[6]!=undefined?this.tableData[6].amount:""
        };
        let sevenData={
          label:"网银录入",
          labelLater:"",
          unit:this.tableData[7]!=undefined?this.tableData[7].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[7]!=undefined?this.tableData[7].amount:""
        };
        let eightData ={
          label:"网银复核",
          labelLater:"",
          unit:this.tableData[8]!=undefined?this.tableData[8].unit:"",
          backed:this.tableData[0]!=undefined?this.tableData[0].backed:"",
          amount:this.tableData[8]!=undefined?this.tableData[8].amount:""
        };
        this.tableData.splice(0,1,zeroData);
        this.tableData.splice(1,1,oneData);
        this.tableData.splice(2,1,twoData);
        this.tableData.splice(3,1,threeData);
        this.tableData.splice(4,1,fourData);
        this.tableData.splice(5,1,fiveData);
        this.tableData.splice(6,1,sixData);
        this.tableData.splice(7,1,sevenData);
        this.tableData.splice(8,1,eightData);
        console.log("少于9条数据========",this.tableData)
      }else{
        this.addArrPoperty(this.tableData,0,"支付日期",
            this.tableObj.paymentDate
        );
        this.addArrPoperty(this.tableData,1,"会签总笔数",
            this.tableObj.allcCountersign
        );
        this.addArrPoperty(this.tableData,2,"单据数量",
            this.tableObj.dataList
        );
        this.addArrPoperty(this.tableData,3,"会签总金额",
            this.QFWYBLLWXS(this.tableObj.countersignAllAmount)
        );
        this.addArrPoperty(this.tableData,4,"会签总金额",
            this.tableObj.countersignAllAmountDX
        );
        this.addArrPoperty(this.tableData,5,"财务负责人",
            this.tableObj.CWFZRsign
        );
        this.addArrPoperty(this.tableData,6,"集团董事长",
            this.tableObj.JTDSZsign
        );
        this.addArrPoperty(this.tableData,7,"网银录入","");
        this.addArrPoperty(this.tableData,8,"网银复核","");
        console.log("多于9条数据========",this.tableData)
      }
    },
    addArrPoperty(arr,index,label,labelLater){
      arr[index].label=label;
      arr[index].labelLater=labelLater;
    },
  }
}
</script>

3:样式

<style scoped>
  .red{
    color: red;
  }
  .lineH40{
    line-height: 40px;
  }
  .lineH30{
    line-height: 30px;
  }
  .fontSize16{
    font-size: 16px;
  }
  .fontSize18{
    font-size: 18px;
    font-weight: 500;
  }
  .fontSize12{
    font-size: 12px;
    font-weight: 600;
  }
  table {
    border-spacing: 0;
    border-collapse: collapse;
    border: 1px solid #7f7f7f;
    width: 100%;
    margin-bottom: 30px;
  }
  table td {
    padding: 8px;
    border: 1px solid #7f7f7f;
    text-align: center;
    min-width: 80px;
    min-height: 30px;
  }
  .headStyle td{
    text-align: center; 
    font-weight: 600;
  }
  .margin-B30{
    margin-bottom: 30px;
  }
  .backTag{
    margin-left: 3px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .sanJiao{
    content:"";
    border:11px solid red;
    border-top-color:transparent;
    border-left-color:transparent;
    border-bottom-color:transparent;
    width:0px;
    height:0px;
  }
  .backColor{
    border: none;
    background-color: red;
    padding-right: 5px;
    color: white;
  }
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1478470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【第十天】C++函数对象/仿函数、谓词、适配器及常见algorithm算法

一、函数对象 重载了函数调用运算符()的类 实例化的对象叫函数对象&#xff0c;也叫仿函数。 如果函数对象 有一个参数 叫&#xff1a;一元函数对象/仿函数如果函数对象 有二个参数 叫&#xff1a;二元函数对象/仿函数如果函数对象 有三个及以上参数 叫&#xff1a;多元函数对…

Java设计模式 | 七大原则之合成复用原则

基本介绍 合成复用原则&#xff08;Composite Reuse Principle&#xff09;尽量使用合成/聚合的方式&#xff0c;而不是使用继承 设计原则核心思想总结 找出应用中可能需要变化之处&#xff0c;把他们独立出来&#xff0c;不要和那些不需要变化的代码混在一起针对接口编程&…

Ubuntu系统下DPDK环境搭建

目录 一.虚拟机配置1.添加一个网卡(桥接模式)2.修改网卡类型3.修改网卡名称4.重启虚拟机5.查看网卡信息6.dpdk配置内存巨型页 三 DPDK源代码下载和编译1.下载源代码2.解压源代码3.安装编译环境4.编译5.设置dpdk的环境变量6.禁止多队列网卡7.加载igb_uio模块8.网卡绑定9.验证测试…

Docker 入门笔记

课程地址 容器技术概述 docker能做什么&#xff1a;将应用程序代码和依赖打包为一个镜像&#xff0c;作为交付介质&#xff0c;在各种环境中部署 相比于虚拟机&#xff0c;docker 只虚拟出一个隔离的程序运行环境&#xff0c;其需要则资源大大减少 容器内的程序就好像直接运…

安装 docker 可视化工具 portainer

portainer 官方网站 https://www.portainer.io/ 一、portainer 介绍 Portainer是一款开源的容器管理平台&#xff0c;它提供了一个直观易用的Web界面&#xff0c;帮助用户管理Docker容器集群、镜像、卷等资源。Portainer 支持多种 Docker 环境&#xff0c;包括本地Docker、Sw…

EXTJS实现自定义表格

宽度自适应 width: 100%, 高度自适应 height: 100% 同时设置表格所处页面高度100% html,body,#griddemo{height: 100%;} 自定义显示的文本内容 Ext.onReady(function () {Ext.QuickTips.init()function sexText(val) {if (val 0) {return <span style"color:green…

20240229作业

1.编写链表&#xff0c;链表里面随便搞点数据&#xff0c;使用 fprintf 将链表中所有的数据&#xff0c;保存到文件中&#xff0c;使用 fscanf 读取文件中的数据&#xff0c;写入链表中 #include <stdio.h> #include <stdlib.h>// 定义链表节点结构体 struct List…

Linux系统安装使用nginx

1.编译安装Nginx服务 (1)关闭防火墙&#xff0c;将安装nginx所需要软件包传到/opt目录下 systemctl stop firewalld systemctl disable firewalld setenforce 0 将压缩包传入到/opt目录下 cd /opt wget http://nginx.org/download/nginx-1.18.0.tar.gz (2). 安装依赖…

小红书的几种赚钱方式解读

小红书的七种变现方式&#xff1a; 1.通过小红书蒲公英平台接广告&#xff0c;粉丝数量大于1000的用户可以开通。单条笔记的广告费用从几百元到几十万不等。 2.开设小红书专栏&#xff0c;粉丝数量大于1万的用户可以开通。 3.进行私域变现&#xff0c;将小红书的咨询引导到微信…

解决内嵌帆软报表出现重定向问题

最近收到反馈&#xff0c;某些程序的前端通过iframe标签内嵌finebi帆软报表时&#xff0c;出现一系列问题。 问题1: 如下图所示&#xff0c;单点登录(单点登录地址schema是https)后service地址的schema协议是http, 浏览器内核的安全策略不允许http访问https。 解决方案&#xf…

HTTP笔记(五)

个人学习笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 目录 一&#xff1a;HTTP报文首部 &#xff08;1&#xff09;HTTP请求报文 &#xff08;2&#xff09…

基于深度学习的水稻病害检测系统(含UI界面、yolov8、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 可以任意更换主干结构&#xff0c;支持几百种网络主干。 数据集&#xff1a;     网上下载的数据集&#x…

用户增长6步法

什么是用户增长&#xff1f; 通过痛点、产品、渠道、内容、技术、数据等要素实现用户的获取、激活、留存、变现、推荐&#xff0c;用户增长包含了产品出现前的用户增长、产品生产周期内的用户增长、产品生命周期外的用户增长三个阶段。 用户增长6步法&#xff1a;方法、模型和…

【重温设计模式】桥接模式及其Java示例

【重温设计模式】桥接模式及其Java示例 桥接模式的介绍 今天我们要探讨的&#xff0c;正是一种名为“桥接模式”的设计模式。桥接模式&#xff0c;英文名Bridge Pattern&#xff0c;是一种结构型设计模式&#xff0c;它的主要目的是将抽象部分与实现部分分离&#xff0c;使得两…

Unity(第十一部)场景

游戏有多个场景组成&#xff08;新手村&#xff0c;某某副本&#xff0c;主城&#xff09; 场景是有多个物体组成&#xff08;怪物&#xff0c;地形&#xff0c;玩家等&#xff09; 物体是有多个组件组成&#xff08;刚体组件&#xff0c;自定义脚本&#xff09; 创建场景 编辑…

77. 组合(力扣LeetCode)

文章目录 77. 组合题目描述回溯算法组合问题的剪枝操作 77. 组合 题目描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [ [2,4], [3,4],…

Android T 远程动画显示流程其三——桌面侧动画启动到系统侧结束流程

前言 接着前文分析Android T 远程动画显示流程其二 我们通过IRemoteAnimationRunner跨进程通信从系统进程来到了桌面进程&#xff0c;这里是真正动画播放的逻辑。 之后又通过IRemoteAnimationFinishedCallback跨进程通信回到系统进程&#xff0c;处理动画结束时的逻辑。 进入…

07-Linux部署Nginx

Linux部署Nginx 简介 NGINX是一款高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3/SMTP代理服务器。它的特点包括占用内存少、并发能力强&#xff0c;因此在处理高负载和高并发的场景时表现优秀。NGINX由俄罗斯的程序设计师Igor Sysoev开发&#xff0c;最初是为俄…

LeetCode:2867. 统计树中的合法路径数目(筛质数+ DFS Java)

目录 2867. 统计树中的合法路径数目 题目描述&#xff1a; 实现代码与思路&#xff1a; 筛质数 DFS 原理思路&#xff1a; 2867. 统计树中的合法路径数目 题目描述&#xff1a; 给你一棵 n 个节点的无向树&#xff0c;节点编号为 1 到 n 。给你一个整数 n 和一个长度为 …

精读《React 高阶组件》

本期精读文章是&#xff1a;React Higher Order Components in depth 1 引言 高阶组件&#xff08; higher-order component &#xff0c;HOC &#xff09;是 React 中复用组件逻辑的一种进阶技巧。它本身并不是 React 的 API&#xff0c;而是一种 React 组件的设计理念&…