uni-app 经验分享,从入门到离职(三)——关于 uni-app 生命周期快速了解上手

文章目录

  • 📋前言
    • ⏬关于专栏
  • 🎯什么是生命周期
    • 🧩应用生命周期
      • 📌 关于 App.vue/App.uvue
    • 🧩页面生命周期
      • 📌关于 onShow 与 onLoad 的区别
    • 🧩组件生命周期
  • 📝最后


在这里插入图片描述

📋前言

这篇文章是本专栏 uni-app 基础篇的第三章,通过上一篇文章的基础,我们继续对 uni-app 进行更深一步的了解和学习,这篇文章的主要内容的是讲一下在 uni-app 中的应用生命周期函数,以及关于 App.vue/App.uvue 文件在项目中的作用。

⏬关于专栏

本专栏主要是分享和介绍从零到一学习和使用的 uni-app 的笔记和个人经验。通过个人的学习经验和工作经验来给大家分享关于 uni-app 开发的技巧,以及快速入门的诀窍等等。

专栏主页:uni-app_黛琳ghz的博客-CSDN博客


🎯什么是生命周期

在前端开发中,生命周期通常指的是组件或页面在特定阶段会经历的一系列事件和方法调用的过程。在 uni-app 中,每个页面和组件都有自己的生命周期钩子函数,用于在特定时机执行特定的操作。作为一名前端开发工程师,对于 Vue 的生命周期一定是非常熟悉的,那么我们可以在这个基础上去学习和了解 uni-app 的生命周期,接下来我们一起来看一下。
在这里插入图片描述
uni-app 生命周期包括创建、加载、渲染、更新和销毁等阶段,常见的生命周期钩子函数包括 onLoad、onShow、onReady、onHide、onUnload 等等,它们分别对应着页面或组件在不同阶段需要执行的操作。

🧩应用生命周期

在了解 uni-app 的生命周期之前,我们先了解下什么是应用生命周期。应用生命周期指的是整个应用程序从启动到关闭的整个过程,包括了应用的初始化、运行、暂停、恢复和关闭等阶段。在小程序应用开发中,了解和管理应用的生命周期非常重要,可以在不同的生命周期阶段执行相应的操作,来保证应用的正常运行和用户体验。

应用生命周期通常包括以下几个阶段:

  • 启动(Launch):应用程序被用户启动,开始进行初始化,加载必要的资源和数据。
  • 运行(Running):应用程序处于活动状态,响应用户的操作,处理各种事件和交互。
  • 暂停(Pause):应用程序失去焦点,进入后台运行,可能被其他应用覆盖,此时需要做一些数据保存和状态保持的工作。
  • 恢复(Resume):应用程序重新获得焦点,从后台恢复到前台运行,需要做一些恢复状态和数据的操作。
  • 关闭(Close):应用程序被用户手动关闭,需要释放资源、保存数据等清理工作。

同理,在 uni-app 中,应用生命周期也大致是这个流程,接下来我们一起来看一下。在 uni-app 中支持如下应用生命周期函数:

函数名说明平台兼容
onLaunch当uni-app初始化完成时触发(全局只触发一次),参数为应用启动参数,同uni.getLaunchOptionsSync的返回值所有平台
onShow当uni-app启动,或从后台进入前台显示,参数为应用启动参数,同uni.getLaunchOptionsSync的返回值所有平台
onHide当uni-app从前台进入后台所有平台
onError当uni-app报错时触发app-uvue 不支持
onUniNViewMessage对nvue页面发送的数据进行监听,可参考nvue向vue通讯app-uvue 不支持
onUnhandledRejection对未处理的Promise拒绝事件监听函数app-uvue 不支持
onPageNotFound页面不存在监听函数app-uvue 不支持
onThemeChange监听系统主题变化app-uvue 不支持
onLastPageBackPress最后一个页面按下Android back键,常用于自定义退出app-uvue-android 3.9+
onExit监听应用退出app-uvue-android 3.9+

接下来我可以通过一个代码例子,看一下它们是怎么运行的,首先我们找到项目的 App.vue 文件,默认创建完项目,App.vue 的代码如下图所示。
在这里插入图片描述
接下来我们用下面这段代码进行测试。

<script>export default {onLaunch: function(options) {console.log('App Launch')console.log('应用启动路径:', options.path)},onShow: function(options) {console.log('App Show')console.log('应用启动路径:', options.path)},onHide: function() {console.log('App Hide')}}
</script><style>/*每个页面公共css */
</style>

在这里插入图片描述
我们可以看到控制台输出了项目初始完成,触发了 onLaunch 函数,然后项目启动时,触发了 onShow 函数。接下来我们再看看如何触发 onHide 函数,如下图操作。
在这里插入图片描述
在这里插入图片描述
我们可以看到小程序从前台进入后台这个操作,触发 onHide 函数,如果再回到前台,则会再重新调用 onShow 函数,如下图所示。
在这里插入图片描述
注意这里 onLaunch 函数只能全局触发一次,所以重新返回小程序的时候没有 触发 onLaunch 函数。

📌 关于 App.vue/App.uvue

在uniapp中,App.vue 或 App.uvue 是应用程序的入口文件,是整个应用的父级组件,用于初始化应用程序并提供全局数据和方法。uni-app js 引擎版是 app.vue。uni-app x 是 app.uvue。其中包含 <script><style> 两个主要部分。所有页面都是在App.vue下进行切换的,但 App.vue 本身不是页面,这里不能编写视图元素,也就是没有 <template>

提到生命周期,就不得不提起 App.vue 这个文件。这个文件的作用包括:监听应用生命周期、配置全局样式、配置全局的存储 globalData 。应用生命周期仅可在 App.vue 中监听,在页面监听无效。
在这里插入图片描述
globalData
在 uniapp 中,可以通过 App 实例的 globalData 属性来定义全局数据,该数据可以在应用的任何页面中进行访问和修改。我们可以通过 getApp().globalData 来获取全局数据对象,并进行相应的操作。下面我们可以看一个例子,代码如下。

App.vue 页面。

<script>export default {onLaunch: function(options) {console.log('App Launch')console.log('应用启动路径:', options.path)},onShow: function(options) {console.log('App Show')console.log('应用启动路径:', options.path)},onHide: function() {console.log('App Hide')},globalData: {text: '我是 globalData'}}
</script><style>/*每个页面公共css */
</style>

home.vue 页面。

<template><view class="content"><image class="logo" src="/static/logo.png"></image><view class="text-area"><text class="title">{{title}}</text></view></view>
</template><script>export default {data() {return {// title: 'Hello'title: ''}},onLoad() {this.title = getApp().globalData.textconsole.log(this.title)},methods: {}}
</script><style>.content {display: flex;flex-direction: column;align-items: center;justify-content: center;}.logo {height: 200rpx;width: 200rpx;margin-top: 200rpx;margin-left: auto;margin-right: auto;margin-bottom: 50rpx;}.text-area {display: flex;justify-content: center;}.title {font-size: 36rpx;color: #8f8f94;}
</style>

实现效果。
在这里插入图片描述
全局样式
在 App.vue 中,可以定义一些全局通用样式,例如需要加一个通用的背景色,首屏页面渲染的动画等都可以写在 App.vue 中。

注意如果工程下同时有 vue 和 nvue 文件,全局样式的所有 css 会应用于所有文件,而 nvue 支持的 css 有限,编译器会在控制台报警,提示某些 css 无法在 nvue 中支持。此时需要把 nvue 不支持的 css 写在单独的条件编译里。如:

<style>/* #ifndef APP-PLUS-NVUE */@import './common/uni.css';/* #endif*/
</style>

接下来我们一起来看一下全局样式的使用案例。首先在 App.vue 文件的 style 模块写一个样式,然后在 home.vue 页面使用这个样式,最后在编译器看具体效果。
在这里插入图片描述
实现效果,字体变红了。
在这里插入图片描述


🧩页面生命周期

除了上面介绍的应用生命周期之外,生命周期还包括了页面的生命周期,每个页面都有自己的生命周期函数,用于控制页面的初始化、渲染、销毁等过程。uni-app 页面除支持 Vue 组件生命周期外还支持下方页面生命周期函数。

函数名说明平台差异说明最低版本
onInit监听页面初始化,参数与 onLoad 参数相同,用于接收上个页面传递的数据,参数类型为对象(用于页面传参),触发时机早于 onLoad。百度小程序3.1.0+
onLoad监听页面加载,当该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成,参数为上个页面传递的数据,参数类型为对象(用于页面传参)。--
onShow监听页面显示,每次页面出现在屏幕上都会触发,包括从下级页面返回露出当前页面。--
onReady监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发。--
onHide监听页面隐藏。--
onUnload监听页面卸载。--
onResize监听窗口尺寸变化。App、微信小程序、快手小程序-
onPullDownRefresh监听用户下拉动作,一般用于下拉刷新。--
onReachBottom页面滚动到底部的事件(不是 scroll-view 滚到底),常用于下拉加载下一页数据。--
onTabItemTap点击 tab 时触发,参数为对象。微信小程序、QQ小程序、支付宝小程序、百度小程序、H5、App、快手小程序、京东小程序-
onShareAppMessage用户点击右上角分享。微信小程序、QQ小程序、支付宝小程序、抖音小程序、飞书小程序、快手小程序、京东小程序-
onPageScroll监听页面滚动,参数为对象。nvue 不支持-
onNavigationBarButtonTap监听原生标题栏按钮点击事件,参数为对象。App、H5-
onBackPress监听页面返回,event = {from: backbutton, navigateBack},backbutton 表示来源是左上角返回按钮或 Android 返回键,navigateBack 表示来源是 uni.navigateBack。详见 app、H5、支付宝小程序。--
onNavigationBarSearchInputChanged监听原生标题栏搜索输入框输入内容变化事件。App、H51.6.0+
onNavigationBarSearchInputConfirmed监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。App、H51.6.0+
onNavigationBarSearchInputClicked监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发)。App、H51.6.0+
onShareTimeline监听用户点击右上角转发到朋友圈。微信小程序2.8.1+
onAddToFavorites监听用户点击右上角收藏。微信小程序、QQ小程序2.8.1+

在页面的生命周期函数中,我们可以进行数据操作、组件初始化、事件绑定等操作,从而控制页面的整个生命周期。正确地使用生命周期函数可以提高应用的性能和用户体验,避免出现各种问题。接下来我们一起来看一下页面加载的时序。

首先我们先看一下 onLoad、onReady、onShow 的先后关系,还有页面加载的详细流程。

  • 1️⃣uni-app 框架,首先根据 pages.json 的配置,创建页面。所以原生导航栏是最快显示的。页面背景色也应该在这里配置。

  • 2️⃣根据页面 template 里的组件,创建 dom。

    • 这里的 dom 创建仅包含第一批处理的静态 dom。对于通过 js/uts 更新 data 然后通过 v-for 再创建的列表数据,不在第一批处理。
    • 要注意一个页面静态 dom 元素过多,会影响页面加载速度。在 uni-app x Android 版本上,可能会阻碍页面进入的转场动画。 因为此时,页面转场动画还没有启动。
  • 3️⃣触发 onLoad

    • 此时页面还未显示,没有开始进入的转场动画,页面 dom 还不存在。
    • 所以这里不能直接操作dom(可以修改 data,因为vue框架会等待dom准备后再更新界面);在 app-uvue 中获取当前的activity拿到的是老页面的activity,只能通过页面栈获取activity。
    • onLoad 比较适合的操作是:接受上页的参数,联网取数据,更新data。
    • 手机都是多核的,uni.request或云开发联网,在子线程运行,不会干扰UI线程的入场动画,并行处理可以更快的拿到数据、渲染界面。但onLoad里不适合进行大量同步耗时运算,因为此时转场动画还没开始。
    • 尤其uni-app x 在 Android上,onLoad里的代码(除了联网和加载图片)默认是在UI线程运行的,大量同步耗时计算很容易卡住页面动画不启动。除非开发者显式指定在其他线程运行。
  • 4️⃣转场动画开始,新页面开始进入的转场动画,动画默认耗时 300 ms,可以在路由 API 中调节时长。

  • 5️⃣页面 onReady,第 2 步创建 dom 是虚拟 dom,dom 创建后需要经历一段时间,UI 层才能完成了页面上真实元素的创建,即触发了 onReady。

    • onRead y后,页面元素就可以自由操作了,比如 ref 获取节点。同时首批界面也渲染了。
    • 注意:onReady 和转场动画开始、结束之间,没有必然的先后顺序,完全取决于 dom 的数量和复杂度。
    • 如果元素排版和渲染够快,转场动画刚开始就渲染好了;大多情况下,转场动画走几格就看到了首批渲染内容;如果元素排版和渲染过慢,转场动画结束都没有内容,就会造成白屏。
    • 联网进程从 onLoad 起就在异步获取数据更新 data,如果服务器速度够快,第二批数据也可能在转场动画结束前渲染。
  • 6️⃣转场动画结束。再次强调,5 和 6 的先后顺序不一定,取决于首批 dom 渲染的速度。

📌关于 onShow 与 onLoad 的区别

上面简单介绍了应用生命周期和页面加载时序后,这里我单独拿 onShow 与 onLoad 再来讲一下,在实际开发中,对接接口数据后,获取数据的时刻也非常重要的,以及数据的更新。其中我用到最多的生命周期函数就是这两个,那么这两个生命周期函数的有啥区别,什么时候应该用哪个,接下来我们一起来看一下我在开发中得出的一些拙见。

首先通过上面的介绍,我们可以知道在 uni-app 中,onLoad 和 onShow 是页面生命周期钩子函数,它们在不同的时机被调用,并且适合处理不同类型的逻辑。

  • onLoad: 当页面被加载时调用。适合用来进行页面初始化操作,比如获取页面参数、执行一次性的数据加载等。
  • onShow: 当页面显示时调用。适合用来处理页面每次展示都需要执行的逻辑,比如刷新页面数据、监听页面可见状态等。

具体使用场景举例:

  • 如果你需要在页面加载时进行一次性的数据初始化(比如从后端获取数据),可以将这部分逻辑放在 onLoad 中。

  • 如果你需要在页面每次显示时都执行一些逻辑(比如根据用户操作刷新数据),可以将这部分逻辑放在 onShow 中。

在这里插入图片描述
总的来说,onLoad 适合处理页面初始化相关的操作,而 onShow 则适合处理页面每次展示都需要执行的逻辑。

🧩组件生命周期

uni-app 组件支持的生命周期,与 Vue 标准组件的生命周期相同,也是用于控制组件的初始化、渲染、更新等过程。

函数名说明平台差异说明最低版本
beforeCreate在实例初始化之前被调用。
created在实例创建完成后被立即调用。
beforeMount在挂载开始之前被调用。
mounted挂载到实例上去之后调用。 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用 $nextTick。
beforeUpdate数据更新时调用,发生在虚拟 DOM 打补丁之前。仅H5平台支持
updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。仅H5平台支持
beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用。
destroyedVue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

需要注意的是,组件的生命周期函数并不是一定要全部使用,根据实际需求选择合适的生命周期函数进行操作即可。


📝最后

到此就是本篇文章的全部内容了,这篇文章记录的主要内容的是 uni-app 中的应用生命周期函数,包括应用生命周期、页面生命周期和组件生命周期,除此之外还有关于 App.vue/App.uvue 文件在项目中的作用。这篇文章是博主 uni-app 专栏基础篇的第三篇文章,后续会不断的更新更多关于 uni-app 的干货、实战经验、学习经验,期待你的关注和留言。

总结:通过合理地使用生命周期钩子函数,开发者可以在页面或组件的不同阶段进行数据初始化、页面渲染、事件绑定、资源释放等操作,从而实现更加精细化的控制和优化应用性能。因此,了解和运用 uni-app 生命周期相关的知识在小程序开发中非常重要。
在这里插入图片描述

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

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

相关文章

北朝隋唐文物展亮相广西,文物预防性保护网关保驾护航

一、霸府名都——太原博物馆收藏北朝隋朝文物展 2月1日&#xff0c;广西民族博物馆与太原博物馆携手&#xff0c;盛大开启“霸府名都——太原博物馆北朝隋文物展”。此次新春展览精选了北朝隋唐时期150多件晋阳文物珍品。依据“巍巍雄镇”“惊世古冢”“锦绣名都”三个单元&am…

Web3行业研究逐步加强,“链上数据”缘何成为关注焦点?

据中国电子报报道&#xff0c;近日&#xff0c;由中关村区块链产业联盟指导&#xff0c;中国信息通信研究院牵头&#xff0c;欧科云链控股有限公司参与编写的《全球Web3产业全景与发展趋势研究报告&#xff08;2023年&#xff09;》正式发布。研究报告通过全面追踪国内外Web3产…

图论练习2

内容&#xff1a;路径计数DP&#xff0c;差分约束 最短路计数 题目大意 给一个个点条边的无向无权图&#xff0c;问从出发到其他每个点的最短路有多少条有自环和重边&#xff0c;对答案 解题思路 设边权为1&#xff0c;跑最短路 表示的路径数自环和重边不影…

[office] 怎么样在excel中插入虚线圆圈 #学习方法#微信#知识分享

怎么样在excel中插入虚线圆圈 Excel中可以插入圆形&#xff0c;然后将边框设置为虚线&#xff0c;从而得到虚线圆。 软件版本&#xff1a;Office2007 方法如下&#xff1a; 1.点击插入菜单中的形状&#xff0c;选择椭圆&#xff1a; 2.按下Shift键&#xff0c;同时拖动鼠标…

国产航顺HK32F030M: 超声波测距模块串口通信数据接收与处理

参考代码 /************************************************************************************************** * file usart_async_tx_no_int_rx_rxneint.c * brief 异步串口通信例程, 通过查询TXE标志发送数据,通过RXNE中断接收数据,当中断接收到数据后会将 * …

STL算法(中)

常用排序算法 sort 功能描述&#xff1a; 对容器内元素进行排序 函数原型&#xff1a; sort(iterator beg, iterator end, _Pred) ; // 按值查找元素&#xff0c;找到返回指定位置迭代器&#xff0c;找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 …

感悟笔记——2024年2月5日

今日阅读了一篇挺有深度的文章&#xff0c;主要阐述进入职场后的大部分人&#xff0c;是怎么逐渐沦为螺丝钉的?即使起点巨高的优等生&#xff0c;也不可避免。文章指路&#xff1a; 「优等生思维」正在将你变成「螺丝钉」和「老黄牛」从小到大&#xff0c;我一直都是那个「别…

2024最新版MySQL安装使用指南

2024最新版MySQL安装使用指南 Installation and Usage Guide to the Latest Oracle MySQL in 2024 By JacksonML 1. MySQL简介 MySQL是世界上最受欢迎的开源数据库之一。MySQL属于Oracle&#xff08;甲骨文&#xff09;公司的产品&#xff0c;其具有强大的功能&#xff0c;但…

【QT】opcuaServer 的构建

【QT】opcuaServer 的构建 前言opcuaServer实现测试 前言 在博文【opcua】从编译文件到客户端的收发、断连、节点查询等实现 中&#xff0c;我们已经介绍了如何在QT 中创建opucaClient 。在本期的博文中&#xff0c;我们基于之前的部署环境&#xff0c;介绍一下如何构建opcuaS…

对AI原生应用做“逆向”后,我找到了大多数大模型厂商注定失败的原因

大家好&#xff0c;我是卖萌酱。 在一整个2023年对大模型风风火火的流星赶月之后&#xff0c;大模型的竞逐已经来到了“下半场”。应接不暇推出一个又一个大模型已为GPT的技术神话祛魅&#xff0c;不得不说&#xff0c;2024年的大模型市场将更加关注大模型的应用和商业价值。 …

docker入门教程之将应用程序容器化

将应用程序容器化 在本指南的其余部分中&#xff0c;您将使用在 Node.js 上运行的简单待办事项列表管理器。如果您不熟悉 Node.js&#xff0c;请不要担心。本指南不需要任何 JavaScript 经验。 先决条件 您已安装最新版本的 Docker Desktop。您已经安装了 Git 客户端。您可以…

88 SRC挖掘-拿下CNVD证书开源闭源售卖系统

目录 1&#xff0e;开源系统、闭源系统、售卖系统2&#xff0e;如何寻找上述三类系统并进行安全测试3&#xff0e;如何挑简单的入手最快速度获取证书装x演示案例:某开源逻辑审计配合引擎实现通用某闭源审计或黑盒配合引擎实现通用某售卖审计或黑盒配合引擎实现通用 涉及资源&am…

10s初认识多线程创建四种方法

1 继承Thread类 2 实现Runnable接口 3 实现Callable接口 4 多线程池 1-2两方法 10s学会教程网址&#xff1a; http://t.csdnimg.cn/UPy1r 本文简略提及多线程池 -》提前创建多个线程&#xff0c;放在一个“容器”&#xff0c;用时取出&#xff0c;不用即放回池中 优点-》响应…

博客|基于Springboot的个人博客系统设计与实现(源码+数据库+文档)

个人博客系统目录 目录 基于Springboot的个人博客系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 &#xff08;1&#xff09;用户管理 &#xff08;2&#xff09;文章分类管理 &#xff08;3&#xff09;公告信息管理 &#xff08;4&#…

MySQL查询优化技巧和10个案例展示

优化MySQL查询的实战技巧&#xff1a; **避免使用SELECT ***&#xff1a;只获取需要的列&#xff0c;这样可以减少数据传输量&#xff0c;提高查询效率。使用索引&#xff1a;为查询频繁的列创建索引&#xff0c;可以显著提高查询速度。但请注意&#xff0c;索引并非万能&…

AI新宠Arc浏览器真可以取代Chrome吗?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

缩略图保持加密(TPE)论文

文献: R.Zhao,Y.Zhang,Y.Nan,W.Wen,X.Chai,andR. Lan, “Primitively visually meaningful image encryption: A new paradigm,” Inf. Sci. (Ny), Vol. 613, pp. 628–48, 2022. DOI: 10.1016/j.ins.2022.08.027. (1) 第1行:原始图像 第2行:加密图像 加密的目标: 原始…

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建

前言&#xff1a; 前面的四个章节我们主要讲解了MongoDB的相关基础知识&#xff0c;接下来我们就开始进入使用.NET7操作MongoDB开发一个ToDoList系统实战教程。本章节主要介绍的是如何快熟搭建一个简单明了的后端项目框架。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战…

Flink cdc3.0动态变更表结构——源码解析

文章目录 前言源码解析1. 接收schema变更事件2. 发起schema变更请求3. schema变更请求具体处理4. 广播刷新事件并阻塞5. 处理FlushEvent6. 修改sink端schema 结尾 前言 上一篇Flink cdc3.0同步实例 介绍了最新的一些功能和问题&#xff0c;本篇来看下新功能之一的动态变更表结…

设计模式学习笔记04(小滴课堂)

1.创建基础类&#xff1a; 调用它进行类对象的复制&#xff1a; 但是如果属性都是基本数据类型确实像这样很简单&#xff0c;但是如果属性中也包含复杂的数据类型呢&#xff1f; 再去测试一下&#xff1a; 我们发现person1和person2的list属性值的内容是同步的&#xff0c;这显…