antv/x6 2.x 搭建流程图编辑页面(1)

news2024/11/20 15:16:57

进来闲来无事,看到x6 2.x版本也更新了有几个月了,便想着熟悉下2.x版本

一、首先搭建项目基础框架。

// yarn 方式
yarn create @vitejs/app v3-ts --template vue-ts
cd v3-ts
yarn
yarn dev

// npm 
npm init @vitejs/app v3-ts --template vue-ts
cd v3-ts
npm install 
npm run dev

二、下载antv/x6以及对应所需要的插件包

package.json

{
  "@antv/x6": "^2.0.0",
  "@antv/x6-plugin-clipboard": "^2.0.0", // 如果使用剪切板功能,需要安装此包
  "@antv/x6-plugin-history": "^2.0.0", // 如果使用撤销重做功能,需要安装此包
  "@antv/x6-plugin-keyboard": "^2.0.0", // 如果使用快捷键功能,需要安装此包
  "@antv/x6-plugin-minimap": "^2.0.0", // 如果使用小地图功能,需要安装此包
  "@antv/x6-plugin-scroller": "^2.0.0", // 如果使用滚动画布功能,需要安装此包
  "@antv/x6-plugin-selection": "^2.0.0", // 如果使用框选功能,需要安装此包
  "@antv/x6-plugin-snapline": "^2.0.0", // 如果使用对齐线功能,需要安装此包
  "@antv/x6-plugin-dnd": "^2.0.0", // 如果使用 dnd 功能,需要安装此包
  "@antv/x6-plugin-stencil": "^2.0.0", // 如果使用 stencil 功能,需要安装此包
  "@antv/x6-plugin-transform": "^2.0.0", // 如果使用图形变换功能,需要安装此包
  "@antv/x6-plugin-export": "^2.0.0", // 如果使用图片导出功能,需要安装此包
  "@antv/x6-react-components": "^2.0.0", // 如果使用配套 UI 组件,需要安装此包
  "@antv/x6-react-shape": "^2.0.0", // 如果使用 react 渲染功能,需要安装此包
  "@antv/x6-vue-shape": "^2.0.0" // 如果使用 vue 渲染功能,需要安装此包
}

三、新建graph文件夹。并创建index.ts文件用来封装画布、侧边栏stencil组件、插件、快捷键与事件。

graph/index.ts

import { Graph, Shape} from "@antv/x6";

export default class FlowGraph {
  public static graph: Graph;

  public static init() {
    this.graph = new Graph({
      container: document.getElementById("graph-container")!,
      background: {
        color: "#fff",
      },
      grid: true,
      mousewheel: {
        enabled: true,
        zoomAtMousePosition: true,
        modifiers: "ctrl",
        minScale: 0.5,
        maxScale: 3,
      },
      connecting: {
        router: {
          name: "manhattan",
          args: {
            padding: 1,
          },
        },
        connector: {
          name: "rounded",
          args: {
            radius: 8,
          },
        },
        anchor: "center",
        connectionPoint: "anchor",
        allowBlank: false,
        snap: {
          radius: 20,
        },
        createEdge() {
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: "#A2B1C3",
                strokeWidth: 2,
                targetMarker: {
                  name: "block",
                  width: 12,
                  height: 8,
                },
              },
            },
            zIndex: 0,
          });
        },
        validateConnection({ targetMagnet }) {
          return !!targetMagnet;
        },
      },
      highlighting: {
        magnetAdsorbed: {
          name: "stroke",
          args: {
            attrs: {
              fill: "#5F95FF",
              stroke: "#5F95FF",
            },
          },
        },
      },
    });
    return this.graph;
  }
}

四、页面进行基础布局,并初始化画布。

App.vue

<script setup lang="ts">
import { onMounted, reactive } from "vue";
import FlowGraph from "./graph";

interface DataType {
  isReady: boolean;
}

const data = reactive<DataType>({
  isReady: false,
});

const getContainerSize = () => {
  return {
    width: (document.body.offsetWidth / 100) * 85,
    height: document.body.offsetHeight - 38,
  };
};

onMounted(() => {
  const graph = FlowGraph.init();

  graph.addNode({
    x: 200,
    y: 40,
    width: 120,
    height: 60,
    label: "rect",
    attrs: {
      body: {
        fill: "#efdbff",
        stroke: "#9254de",
      },
    },
  });

  data.isReady = true;
  const resizeFn = () => {
    const { width, height } = getContainerSize();
    graph.resize(width, height);
  };
  resizeFn();
  window.addEventListener("resize", resizeFn);
  return () => {
    window.removeEventListener("resize", resizeFn);
  };
});
</script>

<template>
  <div class="content">
    <div class="leftBox">
      <div class="storeTitle">
        <p>节点库</p>
      </div>
      <!-- 侧边栏stencil组件 -->
      <div id="stencil" />
    </div>
    <div class="panel">
      <!-- Toolbar 工具栏 -->
      <div class="toolbar">
        <!-- <Toolbar v-if="data.isReady" /> -->
      </div>
      <!-- 画布 -->
      <div id="graph-container" />
    </div>
    <!-- 属性配置 -->
    <div class="rightBox">
      <div class="rightTop">属性</div>
      <div class="rightPanel">
        <div class="config">
          <!-- <ConfigPanel v-if="data.isReady" /> -->
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less">
* {
  margin: 0;
  padding: 0;
}

html,
body,
#app {
  width: 100vw;
  height: 100vh;
  font-size: 14px;
}
.content {
  width: 100%;
  height: 100%;
  display: flex;
  overflow: hidden;

  .leftBox {
    width: 15vw;

    .storeTitle {
      height: 38px;
      line-height: 38px;
      display: flex;
      padding: 0 0.26vw;
      justify-content: space-between;
      background-color: #ededed;
      // background-color: #304053;
      p {
        // color: #fff;
        padding-left: 6px;
      }
    }

    #stencil {
      position: relative;
      width: 100%;
      height: calc(100% - 38px);
    }
  }
  .panel {
    width: 85vw;
    height: 100%;

    .toolbar {
      display: flex;
      align-items: center;
      height: 38px;
      border-bottom: 1px solid #ededed;
      // border-bottom: 1px solid #4b4343;
      position: relative;
      background-color: #ededed;
      // background-color: #304053;
      box-sizing: border-box;
      border-left: 2px solid #ededed;
      // border-left: 2px solid #040b22;
    }
  }

  .rightBox {
    width: 0;
  }
}
</style>
  • 此时画布创建成功,效果如下图:
    在这里插入图片描述
  • 接下来来完善侧边栏stencil组件

五、初始化侧边栏stencil组件

graph/index.ts

import { Graph, Shape } from "@antv/x6";
import { Stencil } from "@antv/x6-plugin-stencil";

export default class FlowGraph {
    public static graph: Graph;
    public static stencil: Stencil;

  public static init() {
    this.graph = new Graph({
      container: document.getElementById("graph-container")!,
      background: {
        color: "#fff",
      },
      grid: true,
      mousewheel: {
        enabled: true,
        zoomAtMousePosition: true,
        modifiers: "ctrl",
        minScale: 0.5,
        maxScale: 3,
      },
      connecting: {
        router: {
          name: "manhattan",
          args: {
            padding: 1,
          },
        },
        connector: {
          name: "rounded",
          args: {
            radius: 8,
          },
        },
        anchor: "center",
        connectionPoint: "anchor",
        allowBlank: false,
        snap: {
          radius: 20,
        },
        createEdge() {
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: "#A2B1C3",
                strokeWidth: 2,
                targetMarker: {
                  name: "block",
                  width: 12,
                  height: 8,
                },
              },
            },
            zIndex: 0,
          });
        },
        validateConnection({ targetMagnet }) {
          return !!targetMagnet;
        },
      },
      highlighting: {
        magnetAdsorbed: {
          name: "stroke",
          args: {
            attrs: {
              fill: "#5F95FF",
              stroke: "#5F95FF",
            },
          },
        },
      },
    });
    this.initStencil();
    return this.graph;
    }
    
    public static initStencil() {
        this.stencil = new Stencil({
          title: "流程图",
          target: this.graph,
          search(cell, keyword) {
            return (cell as any).label.indexOf(keyword) !== -1;
          },
          placeholder: "Search by shape name",
          notFoundText: "Not Found",
          stencilGraphWidth: 280,
          stencilGraphHeight: 180,
          collapsable: true,
          groups: [
            {
              title: "基础流程图",
              name: "group1",
            },
            {
              title: "系统设计图",
              name: "group2",
              graphHeight: 250,
              layoutOptions: {
                rowHeight: 70,
              },
            },
          ],
          layoutOptions: {
            columns: 3,
            columnWidth: 80,
            rowHeight: 55,
          },
        });
        document.getElementById("stencil")!.appendChild(this.stencil.container);
    }
}

六、此时可以在graph目录下新建shape.ts来注册更多不同类型的节点

graph/shape.ts

import { Graph } from "@antv/x6";

const ports = {
  groups: {
    top: {
      position: "top",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
    right: {
      position: "right",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
    bottom: {
      position: "bottom",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
    left: {
      position: "left",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
  },
  items: [
    {
      group: "top",
    },
    {
      group: "right",
    },
    {
      group: "bottom",
    },
    {
      group: "left",
    },
  ],
};
Graph.registerNode(
  "custom-rect",
  {
    inherit: "rect",
    width: 66,
    height: 36,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: "#5F95FF",
        fill: "#EFF4FF",
      },
      text: {
        fontSize: 12,
        fill: "#262626",
      },
    },
    ports: { ...ports },
  },
  true
);

Graph.registerNode(
  "custom-polygon",
  {
    inherit: "polygon",
    width: 66,
    height: 36,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: "#5F95FF",
        fill: "#EFF4FF",
      },
      text: {
        fontSize: 12,
        fill: "#262626",
      },
    },
    ports: {
      ...ports,
      items: [
        {
          group: "top",
        },
        {
          group: "bottom",
        },
      ],
    },
  },
  true
);

Graph.registerNode(
  "custom-circle",
  {
    inherit: "circle",
    width: 45,
    height: 45,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: "#5F95FF",
        fill: "#EFF4FF",
      },
      text: {
        fontSize: 12,
        fill: "#262626",
      },
    },
    ports: { ...ports },
  },
  true
);

Graph.registerNode(
  "custom-image",
  {
    inherit: "rect",
    width: 52,
    height: 52,
    markup: [
      {
        tagName: "rect",
        selector: "body",
      },
      {
        tagName: "image",
      },
      {
        tagName: "text",
        selector: "label",
      },
    ],
    attrs: {
      body: {
        stroke: "#5F95FF",
        fill: "#5F95FF",
      },
      image: {
        width: 26,
        height: 26,
        refX: 13,
        refY: 16,
      },
      label: {
        refX: 3,
        refY: 2,
        textAnchor: "left",
        textVerticalAnchor: "top",
        fontSize: 12,
        fill: "#fff",
      },
    },
    ports: { ...ports },
  },
  true
);

七、初始化侧边栏stencil组件内的节点。

graph/index.ts

import { Graph, Shape } from "@antv/x6";
import { Stencil } from "@antv/x6-plugin-stencil";
import './shape'

export default class FlowGraph {
  public static graph: Graph;
  public static stencil: Stencil;

  // 初始化画布
  public static init() {
    this.graph = new Graph({
      container: document.getElementById("graph-container")!,
      background: {
        color: "#fff",
      },
      grid: true,
      mousewheel: {
        enabled: true,
        zoomAtMousePosition: true,
        modifiers: "ctrl",
        minScale: 0.5,
        maxScale: 3,
      },
      connecting: {
        router: {
          name: "manhattan",
          args: {
            padding: 1,
          },
        },
        connector: {
          name: "rounded",
          args: {
            radius: 8,
          },
        },
        anchor: "center",
        connectionPoint: "anchor",
        allowBlank: false,
        snap: {
          radius: 20,
        },
        createEdge() {
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: "#A2B1C3",
                strokeWidth: 2,
                targetMarker: {
                  name: "block",
                  width: 12,
                  height: 8,
                },
              },
            },
            zIndex: 0,
          });
        },
        validateConnection({ targetMagnet }) {
          return !!targetMagnet;
        },
      },
      highlighting: {
        magnetAdsorbed: {
          name: "stroke",
          args: {
            attrs: {
              fill: "#5F95FF",
              stroke: "#5F95FF",
            },
          },
        },
      },
    });
      this.initStencil();
      this.initShape()
    return this.graph;
  }

  // 初始化侧边栏stencil组件
  public static initStencil() {
    this.stencil = new Stencil({
      title: "流程图",
      target: this.graph,
      search(cell, keyword) {
        return (cell as any).label.indexOf(keyword) !== -1;
      },
      placeholder: "Search by shape name",
      notFoundText: "Not Found",
      stencilGraphWidth: 280,
      stencilGraphHeight: 180,
      collapsable: true,
      groups: [
        {
          title: "基础流程图",
          name: "group1",
        },
        {
          title: "系统设计图",
          name: "group2",
          graphHeight: 250,
          layoutOptions: {
            rowHeight: 70,
          },
        },
      ],
      layoutOptions: {
        columns: 3,
        columnWidth: 80,
        rowHeight: 55,
      },
    });
    document.getElementById("stencil")!.appendChild(this.stencil.container);
  }

  // 初始化stencil组件内的节点
  public static initShape() {
    const { graph } = this;
    const r1 = graph.createNode({
      shape: "custom-rect",
      label: "开始",
      attrs: {
        body: {
          rx: 20,
          ry: 26,
        },
      },
    });
    const r2 = graph.createNode({
      shape: "custom-rect",
      label: "过程",
    });
    const r3 = graph.createNode({
      shape: "custom-rect",
      attrs: {
        body: {
          rx: 6,
          ry: 6,
        },
      },
      label: "可选过程",
    });
    const r4 = graph.createNode({
      shape: "custom-polygon",
      attrs: {
        body: {
          refPoints: "0,10 10,0 20,10 10,20",
        },
      },
      label: "决策",
    });
    const r5 = graph.createNode({
      shape: "custom-polygon",
      attrs: {
        body: {
          refPoints: "10,0 40,0 30,20 0,20",
        },
      },
      label: "数据",
    });
    const r6 = graph.createNode({
      shape: "custom-circle",
      label: "连接",
    });
    this.stencil.load([r1, r2, r3, r4, r5, r6], "group1");

    const imageShapes = [
      {
        label: "Client",
        image:
          "https://gw.alipayobjects.com/zos/bmw-prod/687b6cb9-4b97-42a6-96d0-34b3099133ac.svg",
      },
      {
        label: "Http",
        image:
          "https://gw.alipayobjects.com/zos/bmw-prod/dc1ced06-417d-466f-927b-b4a4d3265791.svg",
      },
      {
        label: "Api",
        image:
          "https://gw.alipayobjects.com/zos/bmw-prod/c55d7ae1-8d20-4585-bd8f-ca23653a4489.svg",
      },
      {
        label: "Sql",
        image:
          "https://gw.alipayobjects.com/zos/bmw-prod/6eb71764-18ed-4149-b868-53ad1542c405.svg",
      },
      {
        label: "Clound",
        image:
          "https://gw.alipayobjects.com/zos/bmw-prod/c36fe7cb-dc24-4854-aeb5-88d8dc36d52e.svg",
      },
      {
        label: "Mq",
        image:
          "https://gw.alipayobjects.com/zos/bmw-prod/2010ac9f-40e7-49d4-8c4a-4fcf2f83033b.svg",
      },
    ];
    const imageNodes = imageShapes.map((item) =>
      graph.createNode({
        shape: "custom-image",
        label: item.label,
        attrs: {
          image: {
            "xlink:href": item.image,
          },
        },
      })
    );
    this.stencil.load(imageNodes, "group2");
  }
}

  • 此时页面效果如下:
    在这里插入图片描述

接下来需要完善 快捷键与事件Toolbar 工具栏、以及节点属性配置。具体看下篇文章。

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

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

相关文章

人工神经网络BP神经网络结构及优化原理单隐层,多隐层及反向传播梯度下降释义

神经网络&#xff1a;人工神经网络&#xff08;Artificial Neural Networks&#xff0c;简写为ANNs&#xff09;也简称为神经网络&#xff08;NNs&#xff09;或称作连接模型&#xff08;Connection Model&#xff09;&#xff0c;它是一种模仿动物神经网络行为特征&#xff0c…

ASEMI整流模块MDA110-16参数,MDA110-16规格

编辑-Z ASEMI整流模块MDA110-16参数&#xff1a; 型号&#xff1a;MDA110-16 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;1600V 最大RMS电桥输入电压&#xff08;VRMS&#xff09;&#xff1a;1700V 最大平均正向整流输出电流&#xff08;IF&#xff0…

多线程synchronized对象锁与静态锁之间的8锁问题理解

目录8锁问题锁1&#xff1a;多个线程使用同一对象分别调用不同带有带synchronized关键字且非静态的方法锁2&#xff1a;在锁1基础上&#xff0c;增加A线程执行的方法的执行时间&#xff0c;使得B有机会参与执行锁3&#xff1a;多个线程使用同一对象&#xff0c;一个线程执行带有…

三菱Q系列QJ71C24N模块 MODBUS通信(含完整步骤+源代码)

MODBUS通信的其它相关基础知识请参看下面的文章链接: SMART S7-200PLC MODBUS通信_RXXW_Dor的博客-CSDN博客MODBUS 是 OSI 模型第 7 层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信。自从 1979 年出现工业串行链路的事实标准以来,…

7z压缩包有可能被破解吗,需要多久,暴力穷举和字典破解分别的速度分析

开门见山&#xff0c;我看到网上有很多此类软件&#xff0c;功能就是来破解7zip格式的压缩包&#xff0c;但都没有认真进行测试&#xff0c;这里认真进行判断和测试 首先&#xff0c;目前世界最快的计算机为Frontier&#xff0c;算力1,685.65 PFlop/s。目前最高的算力为全网比…

【IoT】智能小产品:简易电子琴设计

说明 随着电子技术的发展&#xff0c;电子技术正在逐渐改善着人们的学习、生活、工作&#xff0c;因此开发本系统希望能够给人们多带来一点生活上的乐趣&#xff0c;电子技术与音乐的结合不断加深。 由此而产生的电子琴在这种形势下&#xff0c;因其体积小&#xff0c;易于携…

芯科EFRBG22C112 empty工程创建

目录 1.使用工具 2.创建工程 2.1进入welcome,选择芯片&#xff0c;点击start ​编辑 2.2选择sdk4.2.0版本 2.3点击Create New Project 2.4同步步骤创建引导程序bootloader-apploader 3.遇到问题 1.使用工具 ARM仿真器 EFR32BG22C112芯片开发板 pc 使用ARM仿真器连接BG22…

PMP考试多少分算通过?

PMP 是没有具体分数的&#xff0c;只有等级&#xff0c; PASS 就是通过了这张成绩单就是 PASS&#xff0c;3A。主要看头部这里&#xff0c;PASS 就是通过了&#xff0c;FAIL 就是没通过。至于说的 3A&#xff0c;2A1T 啥的&#xff0c;是对应的每个模块的成绩&#xff0c;PMP 的…

【leetcode - 基础】编程能力( 4 / 20天 )

目录 Day - 1 896. 单调数列 - 简单ac 28. 找出字符串中第一个匹配项的下标 - KMP 1、kmp模板 2、java api Day - 2 110. 平衡二叉树 - 递归 1、自顶向下 - 暴力 459. 重复的子字符串 - 暴力 Day - 3 150. 逆波兰表达式求值 - 栈 后缀表达式 66.加一 - 模拟 Day…

Tensorflow 基础与实战

目录 一、线性回归实现 1.1 数据加载与查看绘图 1.2 模型建立、训练与预测 二、神经网络实现 2.1 数据加载与查看绘图 2.2 模型建立、训练与预测 三、逻辑回归实现 3.1 数据加载与查看绘图 3.2 模型建立、训练与预测 四、softmax分类 4.1 数据加载 4.2 数据归一化 …

ReadyAPI x64bit 3.43.0 Crack

ReadyAPI 允许团队在一个集中的界面中创建、管理和执行自动化的功能、安全和性能测试——为敏捷和 DevOps 软件团队提高 API 质量。 ReadyAPI 在单一平台上提供三个模块&#xff1a; 在ReadyAPI 测试模块中&#xff0c;您创建功能测试以验证您的服务是否按预期工作。您可以使用…

高频数组算法

1.二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输…

程序员的职业生涯个人规划(附上学习资料)

目录 前言 1.程序员的规划 2.程序员的进化路径 3.IT行业的难度 4.你的选择 5.再谈谈资本、工具人和内卷 总结&#xff1a; 前言 今天不讲技术也不讲干货&#xff0c;来聊一聊程序员职业生涯的个人规划。希望对不管是想入门的还是已经在这条路上的朋友能有一个帮助。 1.程…

opencv之直方图绘制及均衡化

直方图均衡化优势&#xff1a;增强图像对比度&#xff0c;使对比度较低的局部区域获得高对比度。当图像非常暗或者非常亮&#xff0c;并且背景和前景之间的差异非常小时&#xff0c;此方法非常有效&#xff0c;能够解决暴露过度或暴露不足的问题。直方图均衡化缺陷&#xff1a;…

多彩的书写工具,画图写字更好看,米家液晶小黑板多彩版上手

平时临时记些信息&#xff0c;或者是教小朋友认字的时候&#xff0c;液晶小黑板都是特别实用的工具&#xff0c;我之前就用过米家液晶小黑板&#xff0c;最近我发现米家新出了一款彩色笔迹的小黑板&#xff0c;书写效果更加好看&#xff0c;比以前单色款的更好用。 这款米家液晶…

【技术分享】MA21日均线交易策略

文章目录1.前言1.1.相关术语1.2.MA均线系统设置分类1.3.斐波那契数列2.MA21日均线2.1.MA21日均线2.2.MA21日均线交易策略2.3.MA21日均线案例分析1.前言 1.1.相关术语 空头市场&#xff08;Bear Market&#xff09;&#xff1a;亦称熊市&#xff0c;指价格长期呈 下跌 趋势的证…

操作系统权限提升(十)之系统错误配置-计划任务提权

系列文章 操作系统权限提升(一)之操作系统权限介绍 操作系统权限提升(二)之常见提权的环境介绍 操作系统权限提升(三)之Windows系统内核溢出漏洞提权 操作系统权限提升(四)之系统错误配置-Tusted Service Paths提权 操作系统权限提升(五)之系统错误配置-PATH环境变量提权 操作…

VUE3.0学习

一、父子传值 父组件向子组件传值和vue2.0相比区别不大&#xff0c;区别在于api的使用&#xff0c;让接收参数的写法多样化。父组件::::: <template><div class"about"><div><main><TheWelcome :info"parMsg"/></main>…

【react】理解Fiber

FiberFiber概念结构Fiber 树的遍历是这样发生的【深度遍历】。window.requestIdleCallback()requestAnimationFrameFiber 是如何工作的结论有react fiber&#xff0c;为什么不需要vue fiberFiber 概念 JavaScript引擎和页面渲染引擎两个线程是互斥的&#xff0c;当其中一个线…

12月 被大厂以“人员优化”的名义 无情的辞退了...

前几天&#xff0c;一个认识了好几年在大厂工作的测试员朋友&#xff0c;年近30了&#xff0c;却被大厂以“人员优化”的名义无情被辞&#xff0c;据他说&#xff0c;有一个月散伙饭都吃了好几顿…… 在很多企业&#xff0c;都有KPI考核&#xff0c;然后在此基础上还会弄个“…