【React】精选5题

第1题:简述下 React 的生命周期?每个生命周期都做了什么?

在这里插入图片描述

React 组件的生命周期可以分为三个阶段:挂载阶段、更新阶段和卸载阶段。每个生命周期方法都有特定的目的和功能。

  1. 挂载阶段:

    • constructor:组件的构造函数,在组件被创建时调用,用于初始化状态和绑定方法。
    • static getDerivedStateFromProps:在组件实例化和每次接收新的 props 时被调用,用于根据新的 props 更新状态。
    • render:根据组件的状态和属性返回 JSX 元素。
    • componentDidMount:在组件被挂载到 DOM 后立即调用,可以进行异步数据获取、订阅事件等操作。
  2. 更新阶段:

    • static getDerivedStateFromProps:在接收到新的 props 或 state 时被调用,用于根据新的 props 或 state 更新状态。
    • shouldComponentUpdate:在组件更新前被调用,用于控制组件是否需要重新渲染,默认返回 true。
    • render:根据组件的状态和属性返回 JSX 元素。
    • getSnapshotBeforeUpdate:在 render 方法之后、更新 DOM 之前被调用,用于获取更新前的 DOM 快照。
    • componentDidUpdate:在组件更新后被调用,可以进行 DOM 操作或发送网络请求等操作。
  3. 卸载阶段:

    • componentWillUnmount:在组件被卸载前调用,可以进行清理操作,如取消订阅、清除定时器等。

除了上述生命周期方法,还有一些其他的生命周期方法,如错误边界相关的 componentDidCatch 方法,用于捕获子组件中的错误。

需要注意的是,由于 React Hooks 的引入,部分生命周期方法已经不再推荐使用。可以使用 useEffect Hook 来代替 componentDidMount、componentDidUpdate 和 componentWillUnmount。

具体介绍

render()

render() 方法是 class 组件中唯一必须实现的方法。当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一:

  • React 元素。
    通常通过 JSX 创建。例如,<div /> 会被 React 渲染为 DOM 节点,<MyComponent />会被 React 渲染为自定义组件,无论是 <div /> 还是 <MyComponent /> 均为 React 元素。
  • 数组或 fragments。 使得 render 方法可以返回多个元素。欲了解更多详细信息,请参阅 fragments 文档。
  • Portals。可以渲染子节点到不同的 DOM 子树中。欲了解更多详细信息,请参阅有关 portals 的文档
  • 字符串或数值类型。它们在 DOM 中会被渲染为文本节点
  • 布尔类型或 null。什么都不渲染。(主要用于支持返回 test && 的模式,其中 test 为布尔类型。)
    render() 函数应该为纯函数,这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。

如需与浏览器进行交互,请在 componentDidMount() 或其他生命周期方法中执行你的操作。保持 render() 为纯函数,可以使组件更容易思考。

constructor()

如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。

在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
通常,在 React 中,构造函数仅用于以下两种情况:
通过给 this.state 赋值对象来初始化内部 state。

  • 为事件处理函数绑定实例
  • 在 constructor() 函数中不要调用 setState() 方法。如果你的组件需要使用内部 state,请直接在构造函数中为 this.state 赋值初始 state。

只能在构造函数中直接为 this.state 赋值。如需在其他方法中赋值,你应使用 this.setState() 替代。

要避免在构造函数中引入任何副作用或订阅。如遇到此场景,请将对应的操作放置在 componentDidMount 中。

componentDidMount()

componentDidMount() 会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。

这个方法是比较适合添加订阅的地方。如果添加了订阅,请不要忘记在 componentWillUnmount() 里取消订阅

你可以在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render() 两次调用的情况下,用户也不会看到中间状态。请谨慎使用该模式,因为它会导致性能问题。通常,你应该在 constructor() 中初始化 state。如果你的渲染依赖于 DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理。

componentDidUpdate()

componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。

当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。

componentDidUpdate(prevProps) {// 典型用法(不要忘记比较 props):if (this.props.userID !== prevProps.userID) {this.fetchData(this.props.userID);}
}

你也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。不要将 props “镜像”给 state,请考虑直接使用 props。 欲了解更多有关内容,请参阅为什么 props 复制给 state 会产生 bug。

如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。

componentWillUnmount()

componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。

componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

shouldComponentUpdate()

根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下,你应该遵循默认行为。

当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。返回值默认为 true。首次渲染或使用 forceUpdate() 时不会调用该方法。

此方法仅作为性能优化的方式而存在。不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。你应该考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()。PureComponent 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。

如果你一定要手动编写此函数,可以将 this.props 与 nextProps 以及 this.state 与nextState 进行比较,并返回 false 以告知 React 可以跳过更新。请注意,返回 false 并不会阻止子组件在 state 更改时重新渲染。

我们不建议在 shouldComponentUpdate() 中进行深层比较或使用 JSON.stringify()。这样非常影响效率,且会损害性能。

目前,如果 shouldComponentUpdate() 返回 false,则不会调用 UNSAFE_componentWillUpdate(),render() 和 componentDidUpdate()。后续版本,React 可能会将 shouldComponentUpdate 视为提示而不是严格的指令,并且,当返回 false 时,仍可能导致组件重新渲染。

static getDerivedStateFromProps()

getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。

此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。例如,实现 组件可能很方便,该组件会比较当前组件与下一组件,以决定针对哪些组件进行转场动画。

派生状态会导致代码冗余,并使组件难以维护。 确保你已熟悉这些简单的替代方案:

如果你需要执行副作用(例如,数据提取或动画)以响应 props 中的更改,请改用 componentDidUpdate。
如果只想在 prop 更改时重新计算某些数据,请使用 memoization helper 代替。
如果你想在 prop 更改时“重置”某些 state,请考虑使组件完全受控或使用 key 使组件完全不受控代替。
此方法无权访问组件实例。如果你需要,可以通过提取组件 props 的纯函数及 class 之外的状态,在getDerivedStateFromProps()和其他 class 方法之间重用代码。

请注意,不管原因是什么,都会在每次渲染前触发此方法。这与 UNSAFE_componentWillReceiveProps 形成对比,后者仅在父组件重新渲染时触发,而不是在内部调用 setState 时。

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期方法的任何返回值将作为参数传递给 componentDidUpdate()。

此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。

应返回 snapshot 的值(或 null)。

Error boundaries

Error boundaries 是 React 组件,它会在其子组件树中的任何位置捕获 JavaScript 错误,并记录这些错误,展示降级 UI 而不是崩溃的组件树。Error boundaries 组件会捕获在渲染期间,在生命周期方法以及其整个树的构造函数中发生的错误。

如果 class 组件定义了生命周期方法 static getDerivedStateFromError() 或 componentDidCatch() 中的任何一个(或两者),它就成为了 Error boundaries。通过生命周期更新 state 可让组件捕获树中未处理的 JavaScript 错误并展示降级 UI。

仅使用 Error boundaries 组件来从意外异常中恢复的情况;不要将它们用于流程控制。

static getDerivedStateFromError()

此生命周期会在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 state。

componentDidCatch()

此生命周期在后代组件抛出错误后被调用。 它接收两个参数:

error —— 抛出的错误。
info —— 带有 componentStack key 的对象,其中包含有关组件引发错误的栈信息。
componentDidCatch() 会在“提交”阶段被调用,因此允许执行副作用。 它应该用于记录错误之类的情况。

React 的开发和生产构建版本在 componentDidCatch() 的方式上有轻微差别。

在开发模式下,错误会冒泡至 window,这意味着任何 window.onerror 或 window.addEventListener(‘error’, callback) 会中断这些已经被 componentDidCatch() 捕获的错误。

相反,在生产模式下,错误不会冒泡,这意味着任何根错误处理器只会接受那些没有显式地被 componentDidCatch() 捕获的错误。

第2题:React 错误边界是什么?

React 错误边界(Error Boundaries)是 React 组件中的一种特殊组件,用于捕获并处理子组件在渲染过程中抛出的 JavaScript 错误,以防止整个应用程序崩溃。

当一个错误边界组件包裹在子组件中时,它会监视子组件的渲染过程。如果子组件在渲染期间抛出了 JavaScript 错误(包括在生命周期方法、构造函数或渲染方法中的错误),错误边界组件会捕获该错误并显示备用的 UI,而不是导致整个应用程序崩溃。

错误边界组件是通过定义特定的生命周期方法 componentDidCatch(error, info) 来实现的。当子组件抛出错误时,React 会调用错误边界组件的 componentDidCatch 方法,并将错误信息和错误堆栈作为参数传递给该方法。在 componentDidCatch 方法中,你可以选择如何处理错误,例如显示错误信息或记录错误。

要创建一个错误边界组件,你可以定义一个继承自 React.Component 的类,并实现 componentDidCatch 方法。下面是一个简单的错误边界组件的示例:

class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}componentDidCatch(error, info) {this.setState({ hasError: true });// 在这里可以处理错误,例如显示错误信息或记录错误console.error(error);}render() {if (this.state.hasError) {// 显示备用的 UIreturn <div>Oops, something went wrong.</div>;}return this.props.children;}
}

在你的应用程序中,你可以将错误边界组件包裹在其他组件中,以捕获并处理错误。例如:

<ErrorBoundary><MyComponent />
</ErrorBoundary>

在这个示例中,如果 MyComponent 抛出了错误,错误边界组件 ErrorBoundary 将会捕获错误并显示备用的 UI。

需要注意的是,错误边界组件只能捕获其子组件的错误,而不能捕获其自身的错误或其他同级组件的错误。

第3题:为什么不能直接使用 this.state 改变数据?

在 React 中,不能直接使用 this.state 来改变组件的状态数据,而是应该使用 setState 方法。

主要原因是为了保证 React 组件的可预测性和性能优化。直接修改 this.state 的值会绕过 React 的状态更新机制,导致 React 无法感知到状态的变化,从而无法触发组件的重新渲染。这样可能会导致组件的 UI 不会正确地更新,且可能引发其他潜在的问题。

相反,React 提供了 setState 方法来更新组件的状态。setState 方法接收一个对象或一个函数作为参数,用于更新组件的状态。React 会将新的状态合并到当前状态中,并触发组件的重新渲染。通过 setState 方法更新状态,React 能够正确地跟踪状态的变化,并在必要时重新渲染组件。

此外,setState 方法是异步的,React 会对多次连续的状态更新进行批处理,以提高性能。如果需要在状态更新后执行某些操作,可以将回调函数作为 setState 方法的第二个参数,或者使用 componentDidUpdate 生命周期方法。

总结起来,使用 setState 方法来更新状态可以确保 React 正确地跟踪状态的变化,并触发组件的重新渲染,以保证组件的可预测性和性能优化。

第4题:React 中如果绑定事件使用匿名函数有什么影响?

在 React 中,如果使用匿名函数来绑定事件,会有一些影响。每当组件重新渲染时,匿名函数会被重新创建,这意味着每次渲染时都会生成一个新的函数实例。这可能会导致性能问题,特别是在具有大量子组件的情况下。

由于每个函数实例都被认为是一个新的引用,React 在进行虚拟 DOM 比较时会认为事件处理程序已经发生了变化。这将导致 React 重新渲染组件和子组件,即使实际上事件处理程序的功能没有发生任何变化。

为了避免这个问题,最好使用具名函数来定义事件处理程序,并将其作为属性传递给组件。这样,在组件重新渲染时,React 将会识别到事件处理程序是同一个引用,并且不会触发不必要的重新渲染。

class Demo {render() {return <button onClick={(e) => {alert('我点击了按钮')}}>按钮</button>}
}

这样的写法,因为使用的是匿名函数,所以组件每次都会认为是一个新的 props,不会使用缓存优化,在性能上会有一定的损耗。

第5题:React 的事件代理机制是什么?

React 的事件代理机制是指在顶层使用单一的事件监听器来处理所有的事件,并通过事件冒泡机制将事件传递给正确的组件进行处理。这种机制可以提高性能并减少内存占用。

在 React 中,你可以通过将事件处理程序绑定到组件的属性上来使用事件代理。例如,你可以将一个名为 onClick 的事件处理程序绑定到一个按钮组件上:

<button onClick={handleClick}>Click me</button>

在上面的示例中,handleClick 是一个具名函数,它将作为 onClick 属性传递给按钮组件。当按钮被点击时,React 将会在顶层监听到该事件,并将事件传递给 handleClick 函数进行处理。

在事件处理程序中,你可以访问事件对象,使用 event 参数来获取相关信息,例如:

function handleClick(event) {console.log('Button clicked!');console.log('Event:', event);
}

通过事件对象,你可以获取事件的类型、目标元素等信息,并执行相应的操作。

需要注意的是,React 使用合成事件来包装原生事件,并提供了一些额外的功能,如跨浏览器兼容性和性能优化。因此,你可以放心地使用 React 的事件代理机制来处理事件,而无需直接操作原生事件。
当使用 React 进行事件处理时,React 会利用事件代理机制来处理事件。事件代理是指将事件绑定到父元素上,然后通过冒泡机制将事件传递给子元素。这样做的好处是可以减少事件处理函数的数量,提高性能。

class ParentComponent extends React.Component {handleClick = (event) => {console.log('点击了子元素', event.target);}render() {return (<div onClick={this.handleClick}><ChildComponent /></div>);}
}class ChildComponent extends React.Component {render() {return <button>点击我</button>;}
}

在上面的例子中,ParentComponent 是父组件,ChildComponent 是子组件。当点击子组件中的按钮时,实际上是触发了父组件中的点击事件处理函数 handleClick。通过事件代理,我们可以在父组件中处理子组件的事件,这样可以更方便地管理和控制事件。

handleClick 函数中,我们可以通过 event.target 来获取触发事件的具体元素,这里就是子组件中的按钮。

需要注意的是,事件代理只对合成事件有效,而不适用于原生事件。因此,如果你需要在 React 中使用原生事件,需要使用 addEventListener 方法来手动绑定事件。

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

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

相关文章

6个高清图片素材网站,免费下载,值得推荐~

关于图片素材网站&#xff0c;我一直都在推荐这几个&#xff0c;免费下载&#xff0c;可商用&#xff0c;建议收藏起来~ 菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx 网站主要是为新手设计师提供免费素材的&#xff0c;素材的质量都很高&#xff0c;类别也很多&a…

Git移除commit过的大文件

前言&#xff1a;在提交推送本地更改至仓库时&#xff0c;误将大文件给提交了&#xff0c;导致push时报错文件过大&#xff0c;因此需要将已经commit的大文件移除后再push 若已知要删除的文件或文件夹路径&#xff0c;则可以从第4步开始 1.对仓库进行gc操作 $ git gc 2.查询…

23款奔驰S400豪华型升级后排电动腿托系统,提升后排乘坐舒适性

奔驰S400L后排座椅是不带腿托和脚托的&#xff0c;也没有一键躺平功能&#xff0c;相对于奔驰S级高配车型上配置的右边老板位座椅&#xff0c;舒适性就差强了一些。

【基于Spark的电影推荐系统】环境准备

概览 本科毕设做过电影推荐系统&#xff0c;但当时的推荐算法只有一个&#xff0c;现在已经忘记大部分了&#xff0c;当时也没有记录&#xff0c;因此写这个博客重新来记录一下。此外&#xff0c;技术栈由于快秋招原因来不及做过多的部分&#xff0c;因此只实现简单的功能&…

从零开始 Spring Cloud 7:Gateway

从零开始 Spring Cloud 7&#xff1a;Gateway 图源&#xff1a;laiketui.com Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关&#xff0c;它旨…

ICC2删除所有电源的方法

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f;知识星球入口 remove_pg_patterns -all remove_pg_strategies -all remove_pg_strategy_via_rules -all remove_pg_via_master_rules -all remove_pg_regions -all remove_routes -net_types {p…

网安周报 | 银行业成为开源软件供应链攻击的目标

网安周报是棱镜七彩推出的安全资讯专栏&#xff0c;旨在通过展示一周内发生的与开源安全、软件供应链安全相关攻击事件&#xff0c;让用户了解开源及软件供应链威胁&#xff0c;提高对安全的重视&#xff0c;做好防御措施。 1、银行业成为开源软件供应链攻击的目标 网络安全研…

微服务入门---SpringCloud(二)

微服务入门---SpringCloud&#xff08;二&#xff09; 1.Nacos配置管理1.1.统一配置管理1.1.1.在nacos中添加配置文件1.1.2.从微服务拉取配置 1.2.配置热更新1.2.1.方式一1.2.2.方式二 1.3.配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置…

vue2+wangEditor5富文本编辑器(图片视频自定义上传七牛云/服务器)

1、安装使用 安装 yarn add wangeditor/editor # 或者 npm install wangeditor/editor --save yarn add wangeditor/editor-for-vue # 或者 npm install wangeditor/editor-for-vue --save在main.js中引入样式 import wangeditor/editor/dist/css/style.css在使用编辑器的页…

Android 截图功能实现

Android 截图功能实现 简介效果图功能实现1. 截取当前可见范围屏幕2. 截取当前可见范围屏幕&#xff08;不包含状态栏&#xff09;3. 截取某个控件4. 截取ScrollView5. 长截图6. 截屏动画效果7. 显示截屏结果&#xff0c;自动消失6. 完整代码 简介 在Android应用中开发截图功能…

顺序表的实现

文章目录 1.概念及结构 2.接口实现 3.数组相关oj题 4.顺序表的问题及思考 文章内容 1.概念及结构 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序…

【物理】模拟粒子在电场和磁场中的轨迹研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码实现 &#x1f4a5;1 概述 模拟粒子在电场和磁场中的轨迹研究是物理学中的一个重要研究领域&#xff0c;涉及到电磁场、粒子运动、轨迹分析等多个方面。在这个研究中&…

Python爬虫实例之淘宝商品页面爬取(api接口)

可以使用Python中的requests和BeautifulSoup库来进行网页爬取和数据提取。以下是一个简单的示例&#xff1a; import requests from bs4 import BeautifulSoupdef get_product_data(url):# 发送GET请求&#xff0c;获取网页内容headers {User-Agent: Mozilla/5.0 (Windows NT…

【Spring框架】Spring读取与存储综合练习

练习 在 Spring 项⽬中&#xff0c;通过 main ⽅法获取到 Controller 类&#xff0c;调⽤ Controller ⾥⾯通过注⼊的⽅式调⽤ Service 类&#xff0c;Service 再通过注⼊的⽅式获取到 Repository 类&#xff0c;Repository 类⾥⾯有⼀个⽅法构建⼀个 User 对象&#xff0c;返…

抖音账号矩阵系统开发源码

一、技术自研框架开发背景&#xff1a; 抖音账号矩阵系统是一种基于数据分析和管理的全新平台&#xff0c;能够帮助用户更好地管理、扩展和营销抖音账号。 部分源码分享&#xff1a; ic function indexAction() { //面包屑 $breadcrumbs [ [tit…

虚拟机 RHEL8 安装 MySQL 8.0.34

目录 安装步骤一、清除所有残留的旧MySQL二、安装MySQL 报错问题1. 提示未找到匹配的参数&#xff1a; mysql-community-server2. 公钥问题 安装步骤 一、清除所有残留的旧MySQL 1. 关闭MySQL [rootlocalhost /]# service mysqld stop Redirecting to /bin/systemctl stop …

【导入外部jar包到maven项目中--亲测可行】

若项目为springweb项目&#xff0c;则先将jar放到WEB-INF/lib 目录下选中对应的jar包&#xff0c;右键选项 add-lirrary &#xff1b;成功加入之后的jar包是一个项目的目录结构&#xff1a; 至此&#xff0c;项目能够正常运行&#xff0c;在代码周也能够进行导包 转折点&…

一文谈谈Git

"And if forever lasts till now Alright" 为什么要有git&#xff1f; 想象一下&#xff0c;现如今你的老师同时叫你和张三&#xff0c;各自写一份下半年的学习计划交给他。 可是你的老师是一个极其"较真"的人&#xff0c;发现你俩写的学习计划太"水&…

QT:当登录成功时,关闭登录界面,跳转到新的界面中

1> 继续完善登录框&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;跳转到新的界面中 widget.h #include "widget.h" //#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent)//, ui(new Ui::Widget) {//ui->setu…

使用python部署chineseocr_lite

使用python部署chineseocr_lite 简介安装报错解决python调用结果 简介 项目地址&#xff1a;https://github.com/DayBreak-u/chineseocr_lite chineseocr_lite 是一个开源项目&#xff0c;用来实现中文的文字识别&#xff0c;支持竖排文字识别、繁体识别&#xff0c;总模型只…