当前位置: 首页 > news >正文

Vue - 基于Element UI封装一个表格动态列组件

1 组件需求背景

在后台管理系统中,表格的使用频率非常高,统一封装表格动态列组件并全局注册使用,可大大提升代码的复用性可维护性

2 全局注册

  • src/plugins/index.js:
import columns from './columns/index'export default {install(Vue) {// 动态列Vue.prototype.$columns = columns}
}
  • src/main.js:
import plugins from './plugins' // plugins
// 表格动态列组件
import DynamicColumn from '@/components/DynamicColumn'
Vue.component('DynamicColumn', DynamicColumn)
Vue.use(plugins)
  • 页面(Page.vue)中使用
 <DynamicColumnv-for="(ite, index) in columns":key="index":item="ite":data-list="infoList"/>infoList: [],
columns: this.$columns.getColumns('investmentDecision_list'),

Vue注册组件相关内容可见我的另外一篇博客:Vue - 组件注册及其原理

3 具体组件相关代码

  • src/plugins/columns/index.js:
const columns = {getColumns: function(columnType) {const list = columnList[columnType].listconst newColumn = []list.forEach((v, i) => {newColumn.push({...v,visible: v.visible === undefined ? true : v.visible, // 是否显示字段prop: v.prop, // 字段keylabel: v.label, // 字段名称align: v.align, // 对齐方式sortable: v.sortable, // 是否排序inputType: v.inputType, // 输入方式fixed: v.fixed, // 是否固定列tip: v.tip, // 是否列名解析width: v.width, // 列宽unit: v.unit, // 后缀,如"%"等keepDecimals: v.keepDecimals, // 保留小数位formatThousand: v.formatThousand, // 是否格式化千分位division: v.division, // 是否需要除数,如格式化万则需要除10000class: v.class, // 样式style: v.style, // 样式disabled: v.disabled, // 禁用controls: v.controls,tagTypeStyle: v.tagTypeStyle, // tag标签风格,函数类型,返回一个字符串,参考值为:default | primary | success | info | warning | dangerrender: v.render, // 渲染函数,返回一个处理后的值展示到页面中min: v.min, // 最小值max: v.max, // 最大值routerLink: v.routerLink,chartType: v.chartType, // Echart 图表类型,参考值为:1代表柱形折线图,2代表饼图chartData: v.chartData, // Echart 图表数据chartKey: v.chartKey, // Echart 图表Id的后缀columnTagText: v.columnTagText // 列标签标识})})return newColumn}
}export default columns
  • src/components/DynamicColumn.vue:
<!--动态列-->
<template><!-- :key="`${item.prop}+${item.label}`" --><!-- :show-overflow-tooltip="!item.chartType" --><el-table-columnv-if="item.visible":key="item.prop==='secCode'?Math.random():`${item.prop}+${item.label}`":prop="item.prop":label="item.label":fixed="item.fixed":min-width="getCellWidth(item,dataList)":align="item.align||'left'":show-overflow-tooltip="true":sortable="item.sortable"><template slot="header"><el-tooltipv-if="item.tip"class="item"effect="dark":content="item.tip"placement="top-start"><span><span v-if="item.valid" style="color: #ec051b; font-size: 1.5em">*</span><span>{{ item.label }}</span><i class="el-icon-question" /></span></el-tooltip><span v-else><span v-if="item.valid" style="color: #ec051b; font-size: 1.5em">*</span><span>{{ item.label }}</span></span></template><template slot-scope="scope"><el-inputv-if="item.inputType === 'input'"v-model="scope.row[item.prop]"size="mini":placeholder="$t('pleaseEnter')":disabled="item.disabled||(scope.row.disabled&&scope.row.disabled.includes(item.prop))"@change="onChange(scope.row,item)"@blur="onBlur(scope.row,item)"/><el-input-numberv-else-if="item.inputType === 'number'"v-model="scope.row[item.prop]"size="mini":placeholder="$t('pleaseEnter')":precision="item.keepDecimals":controls="item.controls":min="item.min":max="item.max":disabled="item.disabled||(scope.row.disabled&&scope.row.disabled.includes(item.prop))"@change="onChange(scope.row,item)"@blur="onBlur(scope.row,item)"/><el-selectv-else-if="item.inputType === 'select'"v-model="scope.row[item.prop]":placeholder="$t('pleaseSelect')"size="mini":disabled="item.disabled||(scope.row.disabled&&scope.row.disabled.includes(item.prop))"@click.native="lastValue = scope.row[item.prop]"@change="onChange(scope.row,item)"><el-optionv-for="ite in scope.row[item.prop + 'list'] || []":key="ite.value":label="ite.label":value="ite.value":disabled="ite.disabled"/></el-select><el-date-pickerv-else-if="item.inputType === 'date'"v-model="scope.row[item.prop]":format="item.format||'yyyy-MM-dd'":value-format="item.format||'yyyy-MM-dd'":type="item.dateType||'date'":placeholder="$t('pleaseSelect')":disabled="item.disabled||(scope.row.disabled&&scope.row.disabled.includes(item.prop))"size="mini"@change="onChange(scope.row,item)"/><el-switchv-else-if="item.inputType === 'switch'"v-model="scope.row[item.prop]":active-text="item.activeText":inactive-text="item.inactiveText":active-value="item.activeValue":inactive-value="item.inactiveValue"@change="onChange(scope.row,item)"/><el-radio-groupv-else-if="item.inputType === 'radio'"v-model="scope.row[item.prop]":disabled="item.disabled||(scope.row.disabled&&scope.row.disabled.includes(item.prop))"@change="onChange(scope.row,item)"><el-radiov-for="ite in scope.row[item.prop + 'List'] || []":key="ite.value":disabled="ite.disabled":label="ite.value">{{ ite.label }}</el-radio></el-radio-group><el-checkboxv-else-if="item.inputType === 'checkbox' && scope.row[item.prop]!==undefined"v-model="scope.row[item.prop]":disabled="item.disabled||(scope.row.disabled&&scope.row.disabled.includes(item.prop))"@change="onChange(scope.row,item)">{{ scope.row[item.prop+"Label"] }}</el-checkbox><el-tagv-else-if="item.tagTypeStyle":disable-transitions="true":type="item.tagTypeStyle(scope.row,scope.row[item.prop])||'primary'">{{ formatter(scope.row, item) }}</el-tag><router-linkv-else-if="!item.columnTagText && item.routerLink && item.routerLink(scope.row)"class="dy-router-link":to="item.routerLink(scope.row)"><span>{{ formatter(scope.row, item) }}</span></router-link><BarLineChartv-else-if="item.chartType==1 && scope.row[item.prop]":dom-id="`${scope.row[item.chartKey]}${item.prop}`":data="scope.row[item.prop]"height="50px"background-color="transparent"/><!-- <GridsBarLineChartv-else-if="item.chartType==2 && scope.row.chartData":dom-id="`${scope.row[item.chartKey]}${item.prop}`":data="scope.row.chartData"height="50px"/>--><divv-else-if="item.columnTagText":class="item.class":style="item.style"@click="handleClick(scope.row,item)"><div v-if="item.routerLink && item.routerLink(scope.row)"><router-link class="dy-router-link" :to="item.routerLink(scope.row)"><span>{{ formatter(scope.row, item) }}</span></router-link><div style="margin-top: -8px;"><el-tagv-if="item.columnTagText(scope.row)"type="danger"size="mini">{{ item.columnTagText(scope.row) }}</el-tag></div></div><div v-else>{{ formatter(scope.row, item) }}</div></div><spanv-else:class="item.class":style="item.style"@click="handleClick(scope.row,item)">{{ formatter(scope.row, item) }}</span></template></el-table-column>
</template><script>
import { moneyFormat, keepDecimals, isNumber } from '@/utils/utils'
import Sortable from 'sortablejs'
// 组件
import BarLineChart from '@/components/Echarts/BarLineChart'export default {components: {BarLineChart},props: {// 非必传,只有存在多个表格时,该参数作为表格的唯一标识,主要用于拖拽tableSign: {type: String,default: null},// 所有的列字段,用于拖拽schemas: {type: Array,default: () => {return []}},// 不在schemas内,并且在动态列之前的列数empty: {type: Number,default: 0},// 列字段item: {type: Object,default: () => {return {}}},// 自定义格式化方法format: {type: Function,default: null},// 自定义格式化方法对应的字段formatColumns: {type: Function,default: () => {return []}},// 表格数据dataList: {type: Array,default: () => []}},data() {return {lastValue: undefined // 上次的值}},mounted() {// 表格拖拽方法if (this.schemas.length > 0) {this.columnDrop()}},methods: {// 计算列宽(因为element自适应的宽度还是存在部分字段名称换行情况,所以需要重新计算)getCellWidth(item, dataList) {const { label, width: defaultWidth } = itemif (defaultWidth) {return defaultWidth}if (!label) {return 0}let renderTextMax = ''if (dataList.length > 0) {dataList.forEach((row) => {// 取内容文本的最大值const renderText = this.formatter(row, item) ?? ''this.calculateWidth(renderText) >this.calculateWidth(renderTextMax) && (renderTextMax = renderText)})}// 取表头和内容文本的较大值this.calculateWidth(label) > this.calculateWidth(renderTextMax) &&(renderTextMax = label)let width = 0const html = document.createElement('span')html.innerText = renderTextMaxhtml.className = 'getTextWidth'document.querySelector('body').appendChild(html)width = document.querySelector('.getTextWidth').offsetWidthdocument.querySelector('.getTextWidth').remove()if (width > 260) {return 280}return width + 20},// 计算字符宽度calculateWidth(renderText) {let flexWidth = 0for (let i = 0; i < String(renderText).length; i++) {const char = renderText[i]if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {// 如果是英文字符,为字符分配8个单位宽度flexWidth += 8} else if (char >= '\u4e00' && char <= '\u9fa5') {// 如果是中文字符,为字符分配16个单位宽度flexWidth += 16} else {// 其他种类字符,为字符分配8个单位宽度flexWidth += 8}}return flexWidth},// change事件,向父组件传递字段和值onChange(row, item) {row.oldValue = this.lastValue // 传选择之前的值this.setItemAndValue(this.$parent, row, item, 'columnChange')},// 点击事件,icon点击向父组件传递对应的字段信息handleClick(row, item) {this.setItemAndValue(this.$parent, row, item, 'columnClick')},// 失去焦点事件,icon点击向父组件传递对应的字段信息onBlur(row, item) {this.setItemAndValue(this.$parent, row, item, 'onBlur')},/*** @function setItemAndValue 向父组件传递相应的字段和值* @param {Object} parent 父组件原型* @param {Object} item 字段信息* @param {*} value 值* @param {String} functionType 函数类型*/setItemAndValue(parent, row, item, functionType) {if (parent && parent[functionType]) {parent[functionType](row, item)} else {if (parent.$parent) {this.setItemAndValue(parent.$parent, row, item, functionType)}}},// 格式化formatter(row, item) {// render优先级最高if (item.render) {return item.render(row, row[item.prop])}if (row[item.prop] === null ||row[item.prop] === undefined ||row[item.prop] === '') {// value为0或者false还是照样原来显示return '--'}let value = row[item.prop]if (this.format) {if (this.formatColumns.length > 0 &&this.formatColumns.includes(item.prop)) {// 指定自定义格式化的字段return this.format(row, item, row[item.prop])} else {// 未指定的往下走value = this.format(row, item, row[item.prop])}}if (isNumber(value)) {if (item.keepDecimals || item.keepDecimals === 0) {// 保留小数位value = keepDecimals(value, item.keepDecimals, item.division)}if (item.formatThousand) {value = moneyFormat(value, item.division) // 千分位}if (item.unit) {// 是否带单位,如万value = value + item.unit}}return value},/*** 列拖拽*/columnDrop() {// 页面多个表格 取到对应表格dom元素let wrapperClass = '.el-table__header-wrapper'if (this.tableSign) {const elClass = this.$parent.$el.getAttribute('class')if (!elClass.includes(this.tableSign)) {this.$parent.$el.setAttribute('class', `${elClass} ${this.tableSign}`)}wrapperClass = `.${this.tableSign} ${wrapperClass}`}const wrapperTr = document.querySelector(`${wrapperClass} tr`)this.sortable = Sortable.create(wrapperTr, {animation: 100, // 过渡动画delay: 0, // 延迟多久可以拖动onEnd: (evt) => {if (evt.oldIndex === evt.newIndex) returnconst overviewColumns = [...this.schemas]const visbleColumns = overviewColumns.filter((v) => v.visible) // 显示的列const empty = this.empty // 不在schemas内,并且在动态列之前的列数// 注意:动态列表包含visible为false数据,需要进行特殊筛选处理const oldItem = visbleColumns[evt.oldIndex - empty]const newItem = visbleColumns[evt.newIndex - empty]const realOldIndex = overviewColumns.findIndex((item) => item.prop === oldItem.prop)const realNewIndex = overviewColumns.findIndex((item) => item.prop === newItem.prop)overviewColumns.splice(realOldIndex, 1) // 删除原来位置的数据overviewColumns.splice(realNewIndex, 0, oldItem) // 在新的位置插入该数据this.$emit('changeColumn', overviewColumns)}})}}
}
</script>
<style lang="scss" scoped>
.el-table__row .el-form-item {margin-bottom: 0px !important;
}.el-input,
.el-input.is-disabled,
.el-range-editor.el-input__inner,
.el-date-editor.el-input {width: 100%;
}::v-deep.el-select > .el-input {width: 100%;
}::v-deep.el-input-number .el-input {width: 100%;
}
.el-input-number {width: 100%;
}.dy-router-link {color: #1890ff;display: inline-block;max-width: 100%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;position: relative;&:hover:after {content: '';position: absolute;top: 0;right: 0;bottom: 0;left: 0;border-bottom: 1px solid #1890ff;}
}::v-deep .el-table__row {border: 1px solid #1890ff;.el-table .cell.el-tooltip {display: flex;align-items: center;}
}
</style>

相关文章:

Vue - 基于Element UI封装一个表格动态列组件

1 组件需求背景 在后台管理系统中&#xff0c;表格的使用频率非常高&#xff0c;统一封装表格动态列组件并全局注册使用&#xff0c;可大大提升代码的复用性和可维护性。 2 全局注册 src/plugins/index.js&#xff1a; import columns from ./columns/indexexport default …...

计算机网络:DNS域名解析系统

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…...

java面试:==和equals有什么区别?

在 Java 中&#xff0c;"" 和 "equals" 有着不同的作用&#xff1a; "" 运算符&#xff1a; 在基本数据类型&#xff08;如 int、char 等&#xff09;中&#xff0c;"" 用于比较它们的值是否相等。 在引用类型中&#xff0c;"&q…...

数字人SaaS系统无限生成AI数字人!

市面上数字人软件层出不穷&#xff0c;选择一款适合的数字人软件是成功的第一步&#xff0c;只需要一款软件就解决数字人直播和数字人短视频的制作&#xff0c;青否数字人SaaS系统&#xff08;数字人源码&#xff1a;zhibo175&#xff09;你值得拥有&#xff01; 青否数字人Saa…...

【MySQL】——数据类型及字符集

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…...

Redis cluster集群设置密码

Redis cluster集群设置密码 1 备份数据 # 链接redis集群,执行rdb快照 bgsave # 备份dump.rdb文件 cp /data/redis/cluster/dump.rdb /data/redis/cluster/backup/dump.rdb.202312202 设置密码 必须保证每个节点的密码保持一致&#xff0c;不然 Redirected 的时候会失败 2.1…...

Docker 核心技术

Docker 定义&#xff1a;于 Linux 内核的 Cgroup&#xff0c;Namespace&#xff0c;以及 Union FS 等技术&#xff0c;对进程进行封装隔离&#xff0c;属于操作系统层面的虚拟化技术&#xff0c;由于隔离的进程独立于宿主和其它的隔离的进程&#xff0c;因此也称其为容器Docke…...

15 使用v-model绑定单选框

概述 使用v-model绑定单选框也比较常见&#xff0c;比如性别&#xff0c;要么是男&#xff0c;要么是女。比如单选题&#xff0c;给出多个选择&#xff0c;但是只能选择其中的一个。 在本节课中&#xff0c;我们演示一下这两种常见的用法。 基本用法 我们创建src/component…...

go语言指针变量定义及说明

go语言指针主要需要记住两个特殊符号&#xff0c; 一个是 & 用来获取变量对应的内存地址 另一个是 * 用来获取指针对应的变量值 下面是个最简单的go语言指针说明 package mainimport "fmt"//指针为内存地址func main() {var a string "指针对应的变量&…...

基于“Galera+MariaDB”搭建多主数据库集群的实例

1、什么是多主数据库集群 多主数据库集群是一种数据库集群架构&#xff0c;每个节点都可以接收写入操作和读取操作&#xff0c;并且通过心跳机制同步数据&#xff0c;保证数据一致性和高可用性。因多主数据库集群每个节点都可以承担读写操作&#xff0c;因此它可以充分利用各个…...

arcgis javascript api4.x加载天地图cgs2000坐标系

需求&#xff1a;arcgis javascript api4.x加载天地图cgs2000坐标系 效果&#xff1a; 示例代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…...

算法学习——回溯算法

回溯算法 理论基础回溯法的效率回溯法解决的问题回溯法模板 组合思路回溯法三部曲 代码 组合&#xff08;优化&#xff09;组合总和III思路代码 电话号码的字母组合思路回溯法来解决n个for循环的问题回溯三部曲代码 组合总和思路代码 组合总和II思路代码 理论基础 什么是回溯法…...

C语言—小小圣诞树

这个代码会询问用户输入圣诞树的高度&#xff0c;然后根据输入的高度在控制台上显示相应高度的圣诞树。 #include <stdio.h>int main() {int height, spaces, stars;printf("请输入圣诞树的高度: ");scanf("%d", &height);spaces height - 1;st…...

Android消息公告上下滚动切换轮播实现

自定义控件 通过继承TextSwitcher实现 直接上代码 public class NoticesSwitcher extends TextSwitcher implements ViewSwitcher.ViewFactory {private Context mContext;private List<Notice> mData;private final long DEFAULT_TIME_SWITCH_INTERVAL 1000;//1spri…...

tensorflow入门 自定义模型

前面说了自定义的层&#xff0c;接下来自定义模型&#xff0c;我们以下图为例子 这个模型没啥意义&#xff0c;单纯是为了写代码实现这个模型 首先呢&#xff0c;我们看有几个部分&#xff0c;dense不需要我们实现了&#xff0c;我们就实现Res&#xff0c;为了实现那个*3,我们…...

虚拟机启动 I/O error in “xfs_read_agi+0x95“

1.在选择系统界面按e 进入维护模式 2.找到ro把ro改成 rw init/sysroot/bin/sh 然后按Ctrlx 3.找到坏掉的分区&#xff0c;以nvme0n1p3为例进行修复 xfs_repair -d /dev/nvme0n1p3 4.init 6 重新启动 以下情况 先umount 再修复 则修复成功...

【MYSQL】-库的操作

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …...

网络协议小记

一、TCP/IP协议 作为一个小萌新&#xff0c;当然我无法将tcp/ip协议的大部分江山和盘托出&#xff0c;但是其中很多面试可能问到的知识&#xff0c;我觉得有必要总结一下&#xff01; 首先&#xff0c;在学习tcp/ip协议之前&#xff0c;我们必须搞明白什么是tcp/ip协议。 1、…...

STM32-I2C通讯-AHT20温湿度检测

非常感谢&#xff0c;提供的视频学习 https://www.bilibili.com/video/BV1QN411D7ak/?spm_id_from333.788&vd_source8ca4826038edd44bb618801808a5e076 该文章注意&#xff1a;串口显示中文会乱码&#xff0c;必须选用支持ASCII的串口助手&#xff0c;才能正常显示中文。…...

【机器学习】043_准确率、精确率、召回率

一、定义 在处理偏斜数据集时&#xff0c;通常使用不同的误差度量&#xff0c;而不仅仅是使用分类误差来衡量算法性能。 1. 混淆矩阵的概念 二分类问题的混淆矩阵为2X2矩阵&#xff0c;由四部分组成&#xff1a; 假阴性&#xff08;FN&#xff09;&#xff1a;模型预测为负…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...