最新要闻
- 快报:144MB缓存立大功 AMD锐龙7000X3D内存自由:4800都稳赢i9
- 环球观点:AMD RX 7900 XT价格全面雪崩:沦落到RTX 4070 Ti的级别
- 《旷野之息》发售6周年:续作《塞尔达传说:王国之泪》发布新预告
- 当前视点!中国围棋第一人易主!李轩豪超越柯洁 AI立大功
- 环球快讯:vivo推出“手语翻译官”应用:准确率可达80%以上
- 【全球独家】限制儿童支付金额方便了!微信青少年模式升级:一键开启上线
- 三排七座!仰望U8内饰曝光:比亚迪首款百万豪车来了
- 世界热门:刚失败一次后 日本不放弃:新一代运载火箭尝试再度发射
- 热到离谱?首个冲上20℃的北方省会诞生 下周或破30℃
- 欧洲2035年禁售燃油车要黄?德国公然反对!意大利:我也不同意
- 环球精选!登月用!中国新一代载人火箭预计2027年首飞
- 天天即时:《狂飙》“大嫂”高叶上手小米13:女神持机美如画
- 世界微动态丨网友偶遇眼镜王蛇求助 博物杂志:务必远离、打输住院打赢坐牢
- 世界今亮点!Vtuber因直播《霍格沃茨之遗》被骚扰 宣布毕业
- 天天讯息:委员建议研究生招生规模动态扩大:缓解考研难
- 速看:兰博基尼领衔 今年值得期待的7款跑车 买不起还不能看看?
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
每日资讯:详细剖析|袋鼠云数栈前端框架Antd 3.x 升级 4.x 的踩坑之路
袋鼠云数栈从2016年发布第⼀个版本开始,就始终坚持着以技术为核⼼、安全为底线、提效为⽬标、中台为战略的思想,坚定不移地⾛国产化信创路线,不断推进产品功能迭代、技术创新、服务细化和性能升级。
在数栈过去的产品迭代中受限于当前组件的版本,积累了很多待解决的问题,随着新的功能需求不断增加,很多原先的组件以及交互设计需要进行优化。
(资料图片仅供参考)
2月,伴随着数栈 UI5.0 的焕新升级,数栈前端团队一起将组件框架 antd 从 v3.x 升级到了 v4.x,更新组件的 UI,提升产品的交互体验,使数栈产品能够更加灵活地适应未来产品功能迭代的需求。
本文将总结归纳袋鼠云数栈前端框架Antd 从3.x 升级到4.x 的相关步骤,及在这个过程中踩过的坑,解决的问题。
兼容性问题
第三方依赖兼容问题
· React - 最低 v16.9,部分组件使用 hooks 重构 ( react 升级相关文档:https://sourl.cn/6bM4Ep)
· Less - 最低 v3.1.0,建议升级到 less 4.x;
· @ant-design/icons-antd - 不再内置 Icon 组件,请使用独立的包。
对 3.x 的兼容性处理
或许是考虑到部分组件升级的毁坏性,antd4.x 中依然保留了对 3.x 版本的兼容,废弃的组件通过 @ant-design/compatible 保持兼容,例如 Icon、Form。
注意:建议 @ant-design/compatible 仅在升级过程中稍作依赖,升级 4.x 请完全剔除对该过渡包的依赖。
升级步骤
只有一步
@ant-design/codemod-v4 自带升级脚本,会自动替换代码。
# 通过 npx 直接运行npx -p @ant-design/codemod-v4 antd4-codemod apps/xxxx# 或者全局安装# 使用 npmnpm i -g @ant-design/codemod-v4# 或者使用 yarnyarn global add @ant-design/codemod-v4# 运行antd4-codemod src
注意:该命令和脚本只会进行代码替换,不会进行 AntD 的版本升级,需要手动将其升级至4.22.5。
该命令完成的工作: 1. 将 Form 与 Mention 组件通过 @ant-design/compatible 包引入 2. 用新的 @ant-design/icons 替换字符串类型的 icon 属性值 3. 将 Icon 组件 + type =“” 通过 @ant-design/icons 引入 4. 将 v3 LocaleProvider 组件转换成 v4 ConfigProvider 组件 5. 将 Modal.method() 中字符串 icon 属性的调用转换成从 @ant-design/icons 中引入
antd4-codemod
上图这类报错是 Icon 组件自动替换错误,有 2 种处理方式:
· 报错文件的 Icon 比较少的情况,可以直接手动替换该文件中的 Icon 组件,具体替换成 Icon 中的哪个组件可以根据 type 在 Icon 文档中找( Icon文档:https://sourl.cn/neHBVS );
· 下图中是具体报错的节点,可以看到 JSXSpreadAttribute 节点也就是拓展运算符中没有 name 属性,所以把 Icon 组件的拓展运算符改一下再执行替换脚本就可以了。
antd4 问题修复
styled-components
styled-components 依赖需要转换写法。
Icon
不要使用兼容包的 icon。在 3.x 版本中,Icon 会全量引入所有 svg 图标文件,增加了打包产物;在 4.x 版本中,对 Icon 进行了按需加载,将每个 svg 封装成一个组件。
注意:antd 不再内置 Icon 组件,请使用独立的包 @ant-design/icons。
· 使用
import { Icon } from "antd";mport { SmileOutlined } from "@ant-design/icons";const Demo = () => ( } /> );
· 兼容
import { Icon } from "@ant-design/compatible";const Demo = () => ( );
Form
antd Form 从 v3 到 v4:https://sourl.cn/7TiRfp
● Form.create()
在 3.x 中,表单中任意一项的修改,都会导致 Form.create() 包裹的表单重新渲染,造成性能消耗;在 4.x 中,Form.create() 不再使用。如果需要使用 form 的 api,例如 setFieldsValue 等,需要通过 Form.useForm() 创建 Form 实体进行操作。
· 函数组件写法
// antd v4const Demo = () => { const [form] = Form.useForm(); React.useEffect(() => { form.setFieldsValue({ username: "Bamboo", }); }, []); return ( )};
· 如果是 class component,也可以通过 ref 获取
class Demo extends React.Component { formRef = React.createRef(); componentDidMount() { this.formRef.current.setFieldsValue({ username: "Bamboo", }); } render() { return ( ); }}
当我们使用 From.create() 的时候,可能会传入参数,做数据处理,例如:
export const FilterForm: any = Form.create({ onValuesChange: (props, changedValues, allValues) => { const { onChange } = props; onChange(allValues); },})(Filter);
由于 Form.create 的删除,需要放到 < Form> 中。
● getFieldDecorator
在 4.x 中,不在需要 getFieldDecorator 对 Item 进行包裹。注意以下问题:
· 将之前写在 getFieldDecorator 中的 name/rules 等移到属性中;
· 初始化在 form 中处理,避免同名字段冲突问题;
· 关于表单联动的问题,官方提供了 shouldUpdate 方法。
const Demo = () => ( );
● initialValue
· 历史问题
initialValue 从字面意来看,就是初始值 defaultValue,但是可能会有部分同学使用他的时候会误以为 initialValue 等同于 value。造成这样的误解是因为在 3.x 的版本中,一直存在一个很神奇的问题,受控组件的值会跟随 initialValue 改变。
看下面的例子,点击 button 修改 username, input 框的 value 也会随之改变。
const Demo = ({ form: { getFieldDecorator } }) => ( const [username, setUsername] = useState(""); const handleValueChange = () => { setUsername("yuwan"); } return ( {getFieldDecorator("username", { initialValue: username, rules: [{ required: true }], })()} ));const WrappedDemo = Form.create()(Demo);
但当 input 框被编辑过,initialValue 和 input 的绑定效果就消失了,正确的做法应该是通过 setFieldsVlaue 方法去 set 值。
· 4.x 版本的 initialValue
在 4.x,antd 团队已经把这个 bug 给解了,并且一是为了 name 重名问题,二是再次强调其初始值的功能,现在提到 Form 中了。当然,如果继续写在 Form. Item 中也是可以的,但需要注意优先级。
● shouldUpdate
前面有说过,form 表单不再会因为表单内部某个值的改变而重新渲染整个结构,而设有 shouldUpdate 为 true 的 Item,任意变化都会使该 Form. Item 重新渲染。
它会接收 render props,从而允许你对此进行控制。这里稍微注意一下,请勿在设置 shouldUpdate 的外层 Form. Item 上添加 name, 否则,你会得到一个 error。
prev.name !== next.name}> {form => form.getFieldValue("name") === "antd" && ( )}
在使用 shouldUpdate 的时候,需要在第一个 Form.Item 上加上 noStyle,否则就会出现下面这种留白占位的情况。
● validateTrigger
onBlur 时不再修改选中值,且返回 React 原生的 event 对象。如果你在使用兼容包的 Form 且配置了 validateTrigger 为 onBlur ,请改至 onChange 以做兼容。
● validator
在 antd3 时,我们使用 callback 返回报错。但是 antd4 对此做了修改,自定义校验,接收 Promise 作为返回值。示例参考如下:
· antd3 的写法
{getFieldDecorator("specificTime", { rules: [ { required: true, validator: (_, value, callback) => { if (!value || !value.hour || !value.min) { return callback("具体时间不可为空"); } callback(); }, }, ], })( )}
· antd4 的写法
{ if (!value || !value.hour || !value.min) { return Promise.reject("具体时间不可为空"); } return Promise.resolve(); }, }, ]}> )
● validateFields
不再支持 callback,该方法会直接返回一个 Promise,可以通过 then / catch 处理。
this.formRef.validateFields() .then((values) => { onOk({ ...values, id: appInfo.id || "" });}) .catch(({ errorFields }) { this.formRef.scrollToField(errorFields[0].name); })
或者使用 async/await。
try { const values = await validateFields();} catch ({ errorFields }) { scrollToField(errorFields[0].name);}
● validateFieldsAndScroll
该 api 被拆分了,将其拆分为更为独立的 scrollToField 方法。
onFinishFailed = ({ errorFields }) => { form.scrollToField(errorFields[0].name);};
● form.name
在 antd 3.x 版本,绑定字段时,可以采用 . 分割的方式。如:
getFieldDecorator("sideTableParam.primaryKey")getFieldDecorator("sideTableParam.primaryValue")getFieldDecorator("sideTableParam.primaryName")
在最终获取 values 时,antd 3.x 的版本会对字段进行汇总,得到如下:
const values = { sideTableParam: { primaryKey: xxx, primaryValue: xxx, primaryName: xxx, }}
而在 antd 4.x下,会得到如下的 values 结果:
const values = { "sideTableParam.primaryKey": xxx, "sideTableParam.primaryValue": xxx, "sideTableParam.primaryName": xxx,}
· 解决方法
在 antd 4.x 版本传入数组。
name={["sideTableParam", "primaryKey"]}name={["sideTableParam", "primaryValue"]}name={["sideTableParam", "primaryName"]}
使用 setFieldsValue 设置值:
setFieldsValue({ sideTableParam: [ { primaryKey: "xxx", primaryValue: "xxx", primaryName: "xxx", }, ],});
当我们使用 name={["sideTableParam", "primaryKey"]} 方式绑定值的时候,与其关联的 dependencies/getFieldValue 都需要设置为["sideTableParam", "primaryKey"],例如:
{({ getFieldValue }) => { const isShowWebHook = getFieldValue(["alert", "sendTypeList"])?.includes( ALARM_TYPE.DING ); return ( isShowWebHook && RenderFormItem({ item: { label: "WebHook", key: ["alert", "dingWebhook"], component: , rules: [ { required: true, message: "WebHook地址为必填项", }, ], initialValue: taskInfo?.alert?.dingWebhook || "", }, }) ); }}
当我们希望通过 validateFields 拿到的数据是数组时,例如这样:
我们可以设置为这样:
const formItems = keys.map((k: React.Key) => ( this.removeNewTag(k)} /> ));
● Tooltip
Form 支持属性 tooltip,能够在 label 后产生一个问号直接做提示。
● extra
针对于想放置于组件下面内容可以使用 extra 来实现。
系统参数配置 }>
● Form 在数栈的变化
通过这次 UI 升级和 antd 升级之后,Form 表单在数栈中的应用发生了较大的变化,从老版本的 label/component 横向排版改为了纵向改版,在横向空间不⾜的情况下,使⽤上下结构能有效提⾼填写表单的效率。
Select
● rc-select
· 底层重写
• 解决些许历史问题
1)rc-select & rc-select-tree 的 inputValue & searchValue 之争。rc-select-tree 是 rc-select 结合 tree 写的一个组件,相似但又不同,searchValue 就是其中一点,也不是没人提过 issue,只是人的忘性很大,时间长了就忘了、混淆了,导致在 rc-select 中甚至出现了 searchValue 的字样。
2)inputValue 历史问题,this.state.inputValue。
3)onSelect 清空了值,又会被 onChange 赋值回来。
• 模块复用
在新版的 rc-select 中,antd 官方抽取了一个 generator 方法。它主要接收一个 OptionList 的自定义组件用于渲染下拉框部分。这样我们就可以直接复用选择框部分的代码,而自定义 Select 和 TreeSelect 对应的列表或者树形结构了。
● labelInValue
在 3.x 版本为 {key: string, label: ReactNode}
在 4.x 版本为 {value: string, label: ReactNode}
Table
● fixed
固定列时,文字过长导致错位的问题,被完美解决了。
· 历史原因
3.x 中对 table fixed 的实现,是写了两个 table, 顶层 fixed 的是一个,底层滚动的是一个,这样出现这种错位的问题就很好理解了。
要解决也不是没有办法,可以在特定的节点去测算表格列的高度,但是这个行为会导致重排,影响性能问题。
· 解决方案
4.x 中,table fixed 不在通过两个 table 来实现,他使用了一个 position 的新特性:position: sticky;
元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block (最近块级祖先 nearest block-level ancestor),包括 table-related 元素,基于 top、right、bottom 和 left 的值进行偏移,偏移值不会影响任何其他元素的位置。
优点:
• 根据正常文档流进行定位
• 相对最近滚动祖先 & 最近块级祖先进行偏移
缺点:
• 不兼容 <= IE11
解决了使用 absolute | fixed 脱离文档流无法撑开高度的问题,也不再需要对高度进行测量。
● table.checkbox
· 问题描述
升级后,checkbox 宽度被挤压了。
· 解决方案
通过在 rowSelection 中设置 columnWidth 和 fixed 解决。
const rowSelection = { fixed: true, columnWidth: 45, selectedRowKeys, onChange: this.onSelectChange,};
● 渲染条件
antd4 Table 对渲染条件进行了优化,对 props 进行“浅比较”,如果没有变化不会触发 render。
● 类名更改
.ant-table-content 更改为 .ant-table-container
.ant-form-explain 更改为 .ant-form-item-explain
● dataIndex 修改
在 antd3.0 的时候,我们采用 user.userName 能够读到嵌套的属性。
{ title: "账号", dataIndex: "user.userName", key: "userName", width: 200,}
antd4.0 对此做了修改,同 Form 的 name。
{ title: "账号", dataIndex: ["user", "userName"], key: "userName", width: 200,}
● table pagination showSizeChanger
· 问题描述
升级 antd4 后,发现一些表格分页器多了 pageSize 切换的功能,代码中 onChange 又未对 size 做处理,会导致底部分页器 pageSize 和数据对不上,因此需要各自排查 Table 的 pagination 和 Pagination 组件,和请求列表接口的参数。
handleTableChange = (pagination: any) => { this.setState( { current: pagination.current, }, this.search );};search = (projectId?: any) => { const { name, current } = this.state; const { project } = this.props; const params: any = { projectId: projectId || project.id, pageSize: 10, currentPage: current || 1, name: name || undefined, removeAdmin: true, }; this.loadUsers(params);};
antd4.0 对此做了修改,同 Form 的 name。
`共${total}条`, total: users.totalCount, current, pageSize, }} onChange={this.handleTableChange} style={{ height: tableScrollHeight }} loading={this.state.loading} columns={this.initColumns()} dataSource={users.data} scroll={{ x: 1100, y: tableScrollHeight }}/>handleTableChange = (pagination: any) => { this.setState( { current: pagination.current, pageSize: pagination.pageSize, }, this.search );};search = (projectId?: any) => { const { name, current, pageSize } = this.state; const { project } = this.props; const params: any = { projectId: projectId || project.id, pageSize, currentPage: current || 1, name: name || undefined, removeAdmin: true, }; this.loadUsers(params);};另外,一些同学在 Table 中既写了 onChange,也写了 onShowSizeChange,这个时候要注意,当切换页码条数的时候两个方法都会触发,onShowSizeChange 先触发,onChange 后触发,这个时候如果 onChange 内未对 pageSize 做处理可能导致切页失败,看下面代码就明白了,写的时候稍微注意一下即可。
● table sorter columnKey
· 问题描述
表格中如果要对表格某一字段进行排序需要在 columns item 里设置 sorter 字段,然后在 onChange 里拿到 sorter 对象进行参数处理,再请求数据。
需要注意的是,很多用到了 sorter.columnKey 来进行判断,容易出现问题,sorter.columnKey === columns item.key,如果未设置 key,那么获取到的 columnKey 就为空,导致搜索失效,要么设置 key,再进行获取。同理, sorter.field === columns item.dataIndex,设置 dataIndex,通过 sorter.field 进行获取,两者都可以。
columns={ [ { title: "创建时间", dataIndex: "gmtCreate1", key: "aa", sorter: true, render(n: any, record: any) { return DateTime.formatDateTime(record.gmtCreate); } }, ... ]}onChange={(pagination: any, filters: any, sorter: any) { console.log(pagination, "--pagination"); console.log(filters, "--filters"); console.log(sorter, "--sorter");}}
● Table 在数栈的变化
通过这次 UI 升级和 antd 升级之后,表格在数栈中的应用发生了较大的变化,减⼩了表格默认⾼度,增加⼀屏可浏览的数据数量。
Tree
Tree 组件取消 value 属性,现在只需要添加 key 属性即可。
特别注意, 此问题会导致功能出问题,需要重点关注!!!
在项目中经常在 TreeItem 中增加参数,如:< TreeItem value={value} data={data} >。在拖拽等回调中就可以通过 nodeData.props.data 的方式获取到 data 的值。但在 antd4 中,获取参数的数据结构发生了改变,原先直接通过 props 点出来的不行了。
· 有两种方式取值:
1)不使用props。直接采用 nodeData.data 的方式,也可以直接拿到。
2)继续使用 props。在antd4中,还是可以通过 props 找到参数,只不过 antd 会把所有参数使用 data 进行包裹,就需要改成 nodeData.props.data.data。
· 新版数据结构如下:
· drag
拖拽节点位置的确定与 3.x 相比进行了变更,官网并没有说明。具体如下图:
左侧为 3.x,右侧为 4.x。在3.x版本,只要把节点拖拽成目标节点的上中下,即代表着目标节点的同级上方,子集,同级下方;
在 4.x 版本,是根据当前拖拽节点与目标节点的相对位置进行确定最终的拖拽结果。
当拖拽节点处于目标节点的下方,且相对左侧对齐的位置趋近于零,则最终的位置为目标节点的同级下方。
当拖拽节点处于目标节点的下方,且相对左侧一个缩近的位置,则最终的位置为目标节点的子集。
当拖拽节点处于目标节点的上方,且相对左侧对齐的位置趋近于零,则最终的位置为目标节点的同级上方。
Pagination
Pagination自 4.1.0 版本起,会默认将 showSizeChanger 参数设置为 true ,因而在数据条数超过50时,pageSize 切换器会默认显示。这个变化同样适用于 Table 组件,可通过 showSizeChanger: false 关闭。
如果 size 属性值为 small,则删除 size 属性。
Drawer
当我们在 Drawer 上 设置了 getContainer={false} 属性之后,Drawer 会添加上 .ant-drawer-inline 的类名导致我们 position: fixed 失效。
Button
在 antd 3.0 中危险按钮采用 type。
使用如下:涉及改动点 type、dangr 属性。
Tabs
使标签页不被选中。
// 3.xactiveKey={undefined}// 4.xactiveKey={null}
总结
该篇文章详细讲解了数栈前端团队如何从 antd3 升级到 antd4 的详细步骤,以及团队在实践过程中发现的一些问题和对应的解决方案,为后续产品的开发体验打了基础,也提供了一种更好的交互体验。
未来数栈前端团队将会持续关注产品体验以及开发中的技术痛点,以开发更好的产品为导向,助力业务发展。《数据治理行业实践白皮书》下载地址:https://fs80.cn/380a4b
想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szbky
同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:30537511,项目地址:https://github.com/DTStack
-
-
-
天天讯息:VSCode官方的配置同步方案
目录前言VSCodeSettingsSync和SettingsSync插件有什么关系?开启SettingsSync功能Merge还是Replace?同步...
来源:
-
每日资讯:详细剖析|袋鼠云数栈前端框架Antd 3.x 升级 4.x 的踩坑之路
记录--手摸手带你撸一个拖拽效果
天天讯息:VSCode官方的配置同步方案
快报:144MB缓存立大功 AMD锐龙7000X3D内存自由:4800都稳赢i9
环球观点:AMD RX 7900 XT价格全面雪崩:沦落到RTX 4070 Ti的级别
《旷野之息》发售6周年:续作《塞尔达传说:王国之泪》发布新预告
当前视点!中国围棋第一人易主!李轩豪超越柯洁 AI立大功
环球快讯:vivo推出“手语翻译官”应用:准确率可达80%以上
网络通信——TCP “三次握手“、“四次挥手“ 详解
PHP语言在线代码运行编译工具推荐
今日报丨JavaScript 回调函数属于闭包?
全球快看:ChatGPT开放API,上来就干到最低价,可以人手一个ChatGPT了
全球新动态:Spring事务使用注意事项
【全球独家】限制儿童支付金额方便了!微信青少年模式升级:一键开启上线
三排七座!仰望U8内饰曝光:比亚迪首款百万豪车来了
世界热门:刚失败一次后 日本不放弃:新一代运载火箭尝试再度发射
热到离谱?首个冲上20℃的北方省会诞生 下周或破30℃
欧洲2035年禁售燃油车要黄?德国公然反对!意大利:我也不同意
环球精选!登月用!中国新一代载人火箭预计2027年首飞
天天即时:《狂飙》“大嫂”高叶上手小米13:女神持机美如画
全球观速讯丨火山引擎 DataTester:A/B 实验如何实现人群智能化定向?
环球快资讯丨Redis分布式锁常见坑点分析
世界今日讯!eas里客户端保存,提交里增加校验规则和必填
访问者模式
世界微动态丨网友偶遇眼镜王蛇求助 博物杂志:务必远离、打输住院打赢坐牢
世界今亮点!Vtuber因直播《霍格沃茨之遗》被骚扰 宣布毕业
天天讯息:委员建议研究生招生规模动态扩大:缓解考研难
全球聚焦:收个滴滴Offer:从小伙三面经历,看看需要学点啥?
环球热资讯!Study for Go! Chapter one - Type
环球最新:手写模拟Spring底层原理-Bean的创建与获取
速看:兰博基尼领衔 今年值得期待的7款跑车 买不起还不能看看?
女子试用期被辞退 现场给HR普法:金句频出网友点赞称解气
每日聚焦:靠ChatGPT年入百万!合法还不限学历专业:一般人我不告诉他(doge)
全球新消息丨韩系车日子不好过!起亚狮铂拓界限时优惠:降3万还给大礼包
zip文件结构
头条:与时俱进推动智慧城市建设,智慧管网监测加强城市治理能力
全球视讯!Java项目集成工作流activiti,会签
简单介绍Python中如何给字典设置默认值
播报:LG:三星QD OLED电视更容易烧屏
世界聚焦:掏耳朵怎么就这么爽!
今日视点:不只全面屏!努比亚Z50 Ultra后摄惊艳:黄金镜皇组合
男子月薪3千相亲角“反向相亲”气到大妈 大爷理解:靠颜值吃饭
每日热文:吴京+杰森斯坦森主演!《巨齿鲨2》暑期上映 国内有望同步
环球视点!ffmpeg视频上传及压缩Linux配置篇下
世界快资讯:【Avalonia】【跨平台】关于Prism项目模块化在Linux下路径问题
浙大揭秘吃鱼为什么会变聪明 网友:告诉老默 我想吃鱼了
上海消保委提醒谨慎购买威马汽车:经营异常、消极应对投诉
特斯拉将放弃稀土材料 中国公司无惧:目前没有东西替代
即时:B站两款自研游戏将上线 CEO陈睿:能挣钱的游戏只剩下两种
《生化危机4:重制版》新演示/截图 里昂拯救黑丝碍事梨
焦点日报:配置资源管理Secret和ConfigMap
环球视点!Windows故障转移群集 和 SQLServer AlwaysOn 搭建教程
(数据库系统概论|王珊)第九章关系查询处理和关系优化-第一节:查询处理
全球速递!视频上传及压缩SpringBoot篇上
世界热门:el-input 使用 回车键会刷新页面的问题
全球最强!传音260W快充手机将亮相:10分钟内充满
性能对标奔驰大G 比亚迪“F品牌”首车曝光:够硬够强
世界快消息!传欧盟准备批准微软收购动视-暴雪
当前报道:女司机“神操作”:100来公里高速连撞4次 竟甩锅路太窄
世界视讯!又一大作优化翻车!《卧龙:苍天陨落》RTX 4090依旧闪退
12GB+256GB到手仅2699元!Redmi K60正式开启降价
温州特斯拉事故驾驶员家属发声:记不清车辆失控场景 妻子去世自责
环球时讯:中国航天员遇到外星人怎么办?载人航天总师:积极交流 星际合作
焦点要闻:漫威等好莱坞大片中国市场遇冷:大家不爱看了 不符合国人审美、文化观
550元 富士发布Instax Mini 12拍立得相机 支持APP存照片
环球即时:卷成白菜价!致态TiPlus 7100固态硬盘新史低:1TB仅549元
环球头条:马斯克10万亿美元“改造地球”背景下!特斯拉电机要完全不用稀土:专家回应有可能
读Java性能权威指南(第2版)笔记07_即时编译器上
今头条!天问二号任务已获得国家批准立项:要从小行星2016 HO3采样返回
实现 Vue 折叠面板组件
委员:996制度是导致就业难、生育率低的重大原因
当前播报:电商价格战开打!京东百亿补贴上线:全场包邮 买贵双倍赔
特斯拉未来要狂暴降价:就靠这改变世界?其实都被骗了!
世界快资讯:豆瓣8.9分!韩国拼体格真人秀在欧美爆红
暗黑三国风!《卧龙:苍天陨落》正式上线:298元 GTX 1650就能玩
3.3 数据结构 时间复杂度 和空间复杂度 计算
环球简讯:004. html篇之《标签分类和嵌套》
天天动态:星巴克国内最大对手!瑞幸咖啡财报:年收入首次突破百亿
硬件狗狗3.3新版发布:跑分排行 实时PK
【环球热闻】使用ansible部署服务到k8s
专家:双休制度很难被改变 可以试试“做四休三”
【当前独家】同样是PCIe 5.0 SSD:Intel、AMD跑分竟不一样!差距达30%
世界观焦点:大熊猫为什么近期扎堆回国?美日等国养不起“国宝”了吗?完全是误解
当前速讯:女子称因准点下班试用期第3天被辞退:还被领导一顿痛骂
全球聚焦:R数据分析:做量性研究的必备“家伙什”-furniture包介绍
003. html篇之《表单》
全球即时:Codeforces 1774 G Segment Covering 题解 (观察性质,倍增)
【全球播资讯】Feign踩坑源码分析 -- 请求参数分号变逗号
【全球快播报】火箭弹电子版领取处>>
视讯!完美还原!玩家用虚幻5复刻《狂飙》高启强老家:桌上还有孙子兵法
《龙马精神》4月上映!69岁成龙再跳120米高摩天轮 本人直言小事情
天天快资讯:C++面经(持续更新)
今亮点!实验楼(规则)怪谈
热推荐:电视剧《三体》豆瓣评分上涨 于和伟:《三体》涨分像涨工资
热门看点:《卧龙:苍天陨落》今晚零点正式解锁!乱世三国冒险即将开启
前沿资讯!口感醇正!熊猫精酿好时光皮尔森啤酒好价:2.8元/听
即时:中国科技公司:让老外开眼了
完爆H.265!优酷用上H.266编解码:最便宜手机放视频也丝般顺滑
世界今头条!搭建两台web服务器基于HAProxy实现负载均衡
焦点短讯!路飞-day5——git 多分支开发、git远程仓库、ssh方式连接远程仓库、协同开发、冲突解决、线上分支合并、远程仓库回滚