Flutter笔记:Web支持原理与实践

举报
jcLee95 发表于 2023/12/22 14:17:22 2023/12/22
【摘要】 Flutter Web支持原理与实践
Flutter笔记
Web支持原理与实践

作者李俊才 (jcLee95)https://blog.csdn.net/qq_28550263

邮箱 :291148484@163.com

CSDN:https://blog.csdn.net/qq_28550263/article/details/135037756

华为开发者社区:https://bbs.huaweicloud.com/blogs/418443



==基础篇==

1. 概述

FlutterWeb支持使得开发者可以使用同一代码库来构建适用于iOSAndroid和浏览器的应用程序。这是基于Dart的可移植性、Web平台的能力和Flutter框架的灵活性。开发者可以将已有的用Dart编写的Flutter代码编译成Web体验,因为Flutter框架对于Web来说只是另一个设备目标。

web-arch.png

为了在Web上支持FlutterFlutter 的核心绘图层是在标准浏览器API之上实现的,这包括将Dart编译为JavaScript(而不是移动应用程序所用的ARM机器代码)。通过结合使用DOMCanvasWebAssemblyFlutter能够在现代浏览器中提供便携、高质量且性能优异的用户体验。Flutter的核心绘图层完全用Dart实现,并使用Dart的优化JavaScript编译器将Flutter核心、框架以及您的应用程序编译成一个可以部署到任何Web服务器的单一、精简的源文件。

FlutterWeb支持在以下情况下最为有价值:

  1. 使用Flutter构建的渐进式Web应用(PWA),提供高质量的PWA,与用户环境集成,包括安装、离线支持和定制的用户体验。
  2. 单页应用程序(SPA),使得复杂的独立Web应用程序,富含图形和交互内容,能够到达广泛设备的终端用户。
  3. 现有的移动应用程序,为现有的Flutter移动应用程序提供基于浏览器的交付模型。

不是每个HTML场景都适合于当前的Flutter。例如,文本丰富、基于流的、静态内容(如博客文章)受益于Web建立的文档中心模型,而不是像Flutter这样的UI框架可以提供的应用中心服务。然而,您可以使用Flutter将交互体验嵌入到这些网站中。

此外,Flutter提供了一系列资源帮助开发者开始使用Flutter构建Web应用,包括如何为现有应用添加Web支持、创建新的包含Web支持的应用、了解不同的Web渲染器(HTMLCanvasKit)、创建响应式Flutter应用、查看常见问题和答案、查看代码示例、查看Flutter Web应用演示、了解如何部署Web应用等。

2. Flutter的Web渲染器

2.1 Flutter的Web的两种渲染器

Flutter Web应用程序的开发和构建过程中,开发者可以在两种不同的渲染器之间选择:HTML渲染器CanvasKit渲染器。这两种渲染器各自具有独特的特点和优势:

(1)HTML渲染器。它利用HTML元素、CSSCanvas元素以及SVG元素的组合进行渲染。相比于CanvasKit渲染器,HTML渲染器的一个显著优点是其较小的下载体积,这使得应用程序更快地加载和启动,尤其是在网络条件较差的环境中;

(2)CanvasKit渲染器。它则提供了与Flutter的移动和桌面版本一致的渲染效果,它通过使用WebGL来渲染Skia绘图命令,提供了更高的小部件密度和更快的性能。但这种性能的提升是以大约增加1.5MB的下载体积为代价的。更多关于CanvasKit的信息可以在其官方网站找到。

2.2 命令行选项

Flutter提供了--web-renderer命令行选项,允许开发者在运行或构建Web应用时选择使用哪种渲染器。这个选项接受以下几个值:

  • auto(默认值):这个选项会根据运行环境自动选择渲染器。例如,在移动设备的浏览器中运行时,它会选择HTML渲染器,而在桌面浏览器中则会选择CanvasKit渲染器。
  • html:这个选项会强制应用使用HTML渲染器,无论运行环境如何。
  • canvaskit:选择这个选项将使应用始终使用CanvasKit渲染器。

这个标志可以与flutter runflutter build命令一起使用。例如,如果希望在Chrome浏览器中使用HTML渲染器运行应用,可以使用以下命令:

flutter run -d chrome --web-renderer html

同样,如果想要在构建Web应用时使用CanvasKit渲染器,可以使用如下命令:

flutter build web --web-renderer canvaskit

通过这些选项,开发者可以根据自己的需求和目标用户群体的特点,灵活选择最适合的Web渲染器。

2.3 运行时配置

要在运行时覆盖Web渲染器,需要:

  • 使用auto选项构建应用程序。

  • 准备一个带有renderer属性设置为"canvaskit""html"的配置对象。

  • 将该对象传递给Flutter Web应用程序初始化engineInitializer.initializeEngine(configuration);脚本中的方法。

    <body>
      <script>
    // 设置一个标志,表示是否使用 HTML 渲染
    let useHtml = true;
    
    // 添加一个事件监听器,以在页面完全加载后执行代码
    window.addEventListener('load', function(ev) {
      // 调用 _flutter.loader.loadEntrypoint 函数,加载入口点信息
      _flutter.loader.loadEntrypoint({
        // 配置 Service Worker,指定 Service Worker 的版本
        serviceWorker: {
          serviceWorkerVersion: serviceWorkerVersion, // serviceWorkerVersion 可能在其他地方定义
        },
        // 当入口点加载完成时执行的回调函数
        onEntrypointLoaded: function(engineInitializer) {
          // 创建一个配置对象,用于初始化引擎
          let config = {
            renderer: useHtml ? "html" : "canvaskit", // 根据 useHtml 的值选择渲染器类型
          };
    
          // 使用引擎初始化器初始化引擎,并在完成后执行回调
          engineInitializer.initializeEngine(config).then(function(appRunner) {
            // 运行应用程序
            appRunner.runApp();
          });
        }
      });
    });
      </script>
    </body>
    

注意:从Flutter 3.7.0开始,设置window.flutterWebRenderer(以前版本中使用的方法)会在JS控制台中显示一个反对通知。有关更多信息,请查看 自定义web应用程序初始化

2.4 选择哪个选项

  • 如果您在移动浏览器上优化下载大小,在桌面浏览器上优化性能,请选择auto选项(默认)。
  • 如果您在桌面和移动浏览器上都优先考虑下载大小而不是性能,请选择html选项。
  • 如果您在桌面和移动浏览器上都优先考虑性能和像素完美的一致性,请选择canvaskit选项。

这些选择依赖于具体需求,例如应用的性能要求、目标用户的设备类型以及对下载大小的敏感度。

2.5 一些示例

  • 使用默认渲染器选项 ( auto) 在 Chrome 中运行:
flutter run -d chrome
  • 使用默认(自动)选项在发布模式下构建您的应用程序:
flutter build web --release
  • 仅使用 CanvasKit 渲染器在发布模式下构建您的应用程序:
flutter build web --web-renderer canvaskit --release
  • 使用 HTML 渲染器在配置文件模式下运行您的应用程序:
flutter run -d chrome --web-renderer html --profile

==实践篇==

3. Flutter Web 应用初始化

3.1 初始化过程

Flutter提供了一个定制Web应用初始化过程的机制,允许开发者在不同阶段自定义行为。这一过程主要涉及以下几个阶段:

(1)加载入口脚本:这一阶段会获取main.dart.js脚本并初始化服务工作线程;

(2)初始化Flutter引擎:在此阶段,FlutterWeb引擎会下载所需资源,如资产、字体和CanvasKit

(3)运行应用程序:准备好DOM并运行Flutter应用。

这个初始化过程使用flutter.js文件中提供的_flutter.loader JavaScript API实现,它允许在CSS中显示加载指示器、基于条件阻止应用加载或等待用户按下按钮后再显示应用。

注:前面我们已经说过,Flutter Web并不直接基于DOM构建UI,而是使用自己的渲染引擎来绘制UI。这里的准备DOM不同于传统Web使用DOM表示UI元素,而是起到一个容器的作用,用来承载Flutter引擎渲染出的UI界面。

开始

默认情况下,由flutter create命令生成的index.html文件包含一个脚本标签,该标签调用flutter.js文件中的loadEntrypoint

<html>
  <head>
    <!-- ... -->
    <script src="flutter.js" defer></script>
  </head>
  <body>
    <script>
// 添加一个事件监听器,等待页面完全加载后执行回调函数
window.addEventListener('load', function (ev) {
  // 在页面加载完成后,执行以下代码

  // 下载 main.dart.js 入口文件,并初始化 Flutter 引擎
  _flutter.loader.loadEntrypoint({
    // 配置 Service Worker,指定 Service Worker 的版本
    serviceWorker: {
      // serviceWorkerVersion 可能在其他地方定义
      serviceWorkerVersion: serviceWorkerVersion, 
    },
    // 当入口点加载完成时执行的回调函数,接收一个引擎初始化器参数
    onEntrypointLoaded: async function(engineInitializer) {
      // 使用初始化器初始化 Flutter 引擎,并将结果赋给 appRunner
      let appRunner = await engineInitializer.initializeEngine();

      // 运行 Flutter 应用程序
      await appRunner.runApp();
    }
  });
});
    </script>
  </body>
</html>

loadEntrypoint函数一旦服务工作线程初始化并且main.dart.js入口点被浏览器下载并运行,就会调用onEntrypointLoaded回调。onEntrypointLoaded回调接收一个引擎初始化对象作为唯一参数,用于设置运行时配置并启动Flutter Web引擎。

定制Web应用初始化

开发者可以在应用初始化的每个阶段进行定制。loadEntrypoint方法接受以下参数:

以下是关于 loadEntrypoint 方法的参数的描述:

参数名称 描述
entrypointUrl Flutter应用入口点的URL,默认为"main.dart.js"
onEntrypointLoaded 当引擎准备好初始化时调用的回调函数。
serviceWorker flutter_service_worker.js 加载器的配置。

通过这些参数,开发者可以定制 Flutter Web 应用程序的初始化过程。例如,可以指定不同的入口点 URL,配置 Service Worker 加载器的行为,并在引擎准备好初始化时执行自定义的操作。这些参数允许开发者更灵活地控制应用程序的初始化行为。

引擎配置

Flutter 3.7.0开始,可以通过initializeEngine方法使用一个简单的JavaScript对象来配置Flutter Web引擎的多个运行时选项。

显示进度指示器

在初始化过程中,可以使用每个阶段提供的钩子来更新DOM,从而向应用用户提供反馈。

3.3 升级旧项目

如果您的项目是在Flutter 2.10或更早版本中创建的,可以通过运行flutter create命令来使用最新的初始化模板创建一个新的index.html文件。

这些信息概述了如何在Flutter Web应用的初始化过程中进行自定义设置。更多详细信息和指导,请参考原始文档。

4. 构建并发布 Web 应用程序

4.1 软件要求与安装

4.1.1 Flutter SDK 安装

对于Flutter SDK的安装,首先需要访问Flutter官方网站以下载最新版本的SDK。根据使用的操作系统(Windows, MacOS, Linux),选择合适的下载包。

完成下载后,将文件解压到指定目录,例如Windows用户可能会选择C:\src\flutter,而MacOSLinux用户可能会选择~/flutter

接下来,关键步骤是将Flutter目录添加到系统环境变量中。Windows用户需要更新PATH环境变量,而MacOSLinux用户则需要修改.bash_profile.zshrc文件。

最后,运行flutter doctor命令来检查并确认所有必要的依赖项都已正确安装。更详细的安装步骤可以通过访问Flutter SDK安装指南获得。

4.1.2 Chrome浏览器要求

Flutter Web开发中,Chrome浏览器扮演着关键角色,因为它不仅提供了一个运行和测试Flutter Web应用的平台,还因其先进的功能和性能优化而被广泛使用。要安装Chrome浏览器,用户需要访问Google Chrome网站并选择适合自己操作系统的版本进行下载。安装过程通常非常简单,适用于所有主流操作系统。安装完成后,确保浏览器保持最新状态,以确保Flutter Web应用可以充分利用Chrome的最新特性和优化。

4.1.3 IDE和插件安装

对于开发Flutter应用,有几种IDE可供选择:

(1)Visual Studio CodeVisual Studio Code是一种轻量级的编辑器,支持丰富的插件,包括专门为FlutterDart设计的插件;

(2)Android StudioAndroid Studio提供了一个更集成化的开发体验,它包含了模拟器管理和性能分析等工具。IntelliJ IDEAJetBrains提供的另一种选择,它为习惯于JetBrains工具的开发者提供了类似Android Studio的集成开发环境。无论选择哪种IDE,安装FlutterDart都是必要的步骤。这可以通过在IDE的插件市场中搜索并安装这些插件来实现。安装完成后,重启IDE以激活插件,这将为Flutter应用开发提供语言支持、代码补全、调试、运行和热重载等功能。

4.2 创建带Web支持的新项目

4.2.1 设置Flutter环境

要为Web应用开发设置Flutter环境,首先需要确保已安装最新版本的Flutter SDK。在命令行中运行以下命令可以实现这一目标:

flutter channel stable
flutter upgrade

这些命令会将Flutter SDK切换到稳定版本,并升级到最新版本。由于这个过程可能会耗时,特别是在网络连接较慢的情况下,因此需要耐心等待。完成后,运行flutter doctor命令来验证所有必要的组件都已正确安装并配置。

4.2.2 配置Flutter设备

为了在Web上运行和测试Flutter应用,需要确保Flutter环境能够识别Chrome设备。可以通过在命令行执行以下命令来进行验证:

flutter devices

如果配置正确,这个命令将列出所有已连接的设备,包括Chrome浏览器。这意味着Flutter可以通过Chrome来运行和调试Web应用。在使用IDE(如Visual Studio CodeAndroid Studio)时,应该能够在设备下拉菜单中看到Chrome选项。

4.2.3 通过IDE创建新项目

IDE中创建一个新的Flutter项目通常非常直观。以Visual Studio Code为例,首先打开IDE,然后选择创建新项目的选项。在创建过程中,确保选中了包括Web支持的项目模板。这将自动为项目创建iOSAndroid、桌面以及Web版本。创建完成后,项目结构中将包含专门为Web开发而设置的文件和目录。

4.2.4 使用命令行创建项目

对于偏好使用命令行的开发者,可以通过一系列命令来创建支持WebFlutter项目。首先,使用以下命令创建一个新项目:

flutter create my_app

my_app替换为项目名称。这个命令创建一个新的Flutter项目,包括Web支持。接着,使用cd命令进入项目目录:

cd my_app

在项目目录中,运行以下命令以在Chrome浏览器中启动应用:

flutter run -d chrome

如果没有其他设备连接,-d chrome参数是可选的。这个命令会使用Flutter的开发编译器在Chrome浏览器中启动应用程序。

4.3 运行和构建Flutter Web应用

4.3.1 在Chrome中运行应用

要在Chrome中运行Flutter Web应用,首先打开命令行工具,并导航到项目的根目录。然后,执行以下命令:

flutter run -d chrome

这个命令将启动Chrome浏览器,并在其中加载Flutter应用。如果项目是正确配置的,应用应该会自动在浏览器中打开。对于调试,Flutter提供了多种工具和选项。例如,可以使用--debug标志来启动应用,这将允许在IDE或命令行中进行实时调试。还可以利用Chrome的内置开发者工具进行性能分析和错误检测。这些工具对于优化应用性能和界面表现非常有用。

4.3.2 构建发布版本

当应用开发完成并准备发布时,可以通过以下命令来构建用于生产环境的版本:

flutter build web

这个命令会使用dart2js工具将Dart代码转换为JavaScript代码,这对于在Web上运行Flutter应用是必需的。dart2js的作用是优化应用的性能,确保它能够快速、高效地在浏览器中运行。构建过程完成后,会在项目的build/web目录下生成一系列文件,包括main.dart.js文件和其他资源。这些文件可以被部署到任何标准的Web服务器上,以供用户访问。

4.3.3 选择Web渲染器

Flutter提供了两种渲染器供Web应用使用:HTMLCanvasKit

1.HTML渲染器

HTML渲染器使用标准的Web技术来渲染组件,适用于大多数简单应用,并且对较旧的浏览器有更好的兼容性。

flutter run -d chrome --web-renderer html

chrome_x5ASWN3RFG.png

2.CanvasKit渲染器

CanvasKit渲染器则使用WebAssemblyWebGL来提供更高性能的渲染,适合对图形和动画要求较高的应用。可以通过以下命令来选择不同的渲染器:

flutter run -d chrome --web-renderer canvaskit

chrome_HIKB2bhuZ5.png

选择哪种渲染器取决于应用的具体需求和目标用户的浏览器类型。一般来说,HTML渲染器对性能要求不高的应用更合适,而CanvasKit渲染器则适用于需要高性能渲染的复杂应用。开发者应根据自己的应用特性和用户群体来做出选择。

4.4 更新现有Flutter项目

4.4.1 添加Web支持的命令

对于已有的Flutter项目,若希望添加Web支持,可以通过一系列简单的命令来实现。首先,确保当前位于项目的根目录,然后执行以下命令:

flutter create --platforms web .

这个命令的作用是为现有项目添加Web支持。它会创建所有必需的Web相关文件和目录,同时保留已有的移动或桌面平台代码。这一步骤对于将传统的Flutter应用扩展到Web平台是必要的。

4.4.2 项目结构变化

执行上述命令后,项目的目录结构会发生一些变化。最显著的变化是在项目的根目录下会新增一个web文件夹。这个web文件夹包含了Web应用所需的特定资源和HTML模板。例如,index.html文件作为Web应用的入口点,以及一些初始的配置文件和图标资源

4.5 部署Flutter Web应用到Ubuntu服务器

4.5.1 配置Nginx服务器

部署Flutter Web应用到Ubuntu服务器通常涉及到设置和配置Nginx服务器,这是一种高性能的HTTP和反向代理服务器。以下是在Ubuntu服务器上安装和配置Nginx的步骤:

  1. 安装Nginx:

    • 首先,打开Ubuntu的终端或SSH连接到远程服务器。

    • 运行以下命令以安装Nginx

      sudo apt update
      sudo apt install nginx
      
    • 这些命令会首先更新系统的软件包列表,然后安装Nginx

  2. 配置Nginx:

    • 安装完成后,配置Nginx以托管Flutter Web应用程序。首先,进入Nginx的站点配置目录:

      cd /etc/nginx/sites-available
      
    • 创建一个新的配置文件,例如flutter_app,使用文本编辑器打开它:

      sudo nano flutter_app
      
    • 在这个文件中,配置一个新的server块,指定监听端口(通常是80),server_name(可以是域名或IP地址),以及root指向Flutter应用的构建输出目录(例如/var/www/flutter_app/build/web)。

      server {
          listen 80; # 监听的端口号
          server_name example.com; # 你的域名
      
          location / {
              root /var/www/flutter_app/build/web; # 构建项目的根目录
              try_files $uri $uri/ =404;
          }
      }
      
    • 保存并关闭文件。

  3. 激活网站配置:

    • 为了使Nginx使用新的配置文件,需要建立一个到sites-enabled目录的符号链接:

      sudo ln -s /etc/nginx/sites-available/flutter_app /etc/nginx/sites-enabled/
      
    • 这将允许Nginx在启动时加载这个配置。

  4. 检查Nginx配置并重启服务:

    • 在重启Nginx之前,最好检查配置文件是否有语法错误:

      sudo nginx -t
      
    • 如果一切正常,重启Nginx服务以应用更改:

      nginx -s reload
      

      或者:

      sudo systemctl restart nginx
      

通过以上步骤,Nginx服务器应该已经配置好并准备好托管Flutter Web应用程序。确保防火墙设置允许HTTPHTTPS流量,以便用户可以访问应用程序。

4.5.2 为Flutter Web部署准备Ubuntu环境

部署Flutter Web应用到Ubuntu服务器要求特定的系统配置和环境准备。以下是配置Ubuntu环境的关键步骤:

  1. Ubuntu系统的要求:

    • 使用最新的Ubuntu LTS(长期支持)版本是推荐的,例如Ubuntu 20.04 LTS,因为它提供了稳定性和较长时间的支持。

    • 确保系统有足够的资源(如CPU、内存和存储空间)来支持Web服务器和应用程序。具体需求取决于应用程序的大小和预期流量。

    • 保持系统更新,以确保安全性和稳定性。可以通过运行以下命令来更新系统:

      sudo apt update
      sudo apt upgrade
      
  2. 环境配置步骤:

    • 安全配置: 安装防火墙软件,如UFWUncomplicated Firewall),并配置它允许NginxHTTPHTTPS流量。可以通过以下命令启用UFW并允许Nginx流量:

      sudo apt install ufw
      sudo ufw allow 'Nginx Full'
      sudo ufw enable
      
    • 依赖性安装: 确保安装了所有必要的软件和依赖项,包括Nginx(如前所述)、Git(用于版本控制和代码部署)以及其他可能需要的软件。例如,安装Git的命令如下:

      sudo apt install git
      
    • 用户和权限: 为应用程序创建一个新的系统用户,并为其分配适当的权限,以增强安全性。可以使用adduser命令创建新用户,并使用chownchmod命令来管理文件和目录的权限。

    • 部署目录设置: 在服务器上创建一个适当的目录结构来存储Flutter Web应用程序的文件。例如,可以在/var/www/目录下创建一个新目录,并将Flutter构建的输出文件部署到这里。

    • SSL/TLS证书: 如果计划使用HTTPS,需要为域名配置SSL/TLS证书。可以使用Let’s Encrypt提供的免费证书。

      chrome_8JmChlnPRW

      安装Certbot和它的Nginx插件,然后按照提示为你的域名生成证书。

      sudo apt install certbot python3-certbot-nginx
      sudo certbot --nginx -d yourdomain.com
      

​ 其中,yourdomain.com表示你的域名。

通过遵循以上步骤,Ubuntu环境将为托管Flutter Web应用程序做好准备,同时确保了系统的安全性和稳定性。

4.5.3 部署和运行Flutter应用

部署Flutter Web应用到Ubuntu服务器包括几个关键步骤,以确保应用的顺利运行和维护。

  1. 详细部署步骤:

    • 构建Flutter应用: 在本地环境中,导航到Flutter项目目录,并执行以下命令来构建Web版本的应用:

      flutter build web
      

      这个命令会创建一个build/web目录,其中包含了应用的所有静态文件。

    • 传输文件到服务器: 使用scp命令或任何FTP客户端将build/web目录中的文件上传到服务器的网站根目录下,例如/var/www/flutter_app/build/web

      scp -r build/web/* username@your_server:/var/www/flutter_app/build/web
      

      使用一些工具往往更加方便,比如在Windows上可以使用WinSCP来向Linux类主机传输文件。但是我个人更加喜欢功能更加强大且跨平台可用的 Terminus,它既可以替代 XShellputty,也具备WinSCP的功能,并且方便管理、且界面舒适,内置多个不同主题风格。

      Termius_7tRGfBaiB4.png

    • 配置服务器: 确保Nginx配置正确指向了Flutter应用的根目录,并且配置了正确的服务器块。如果有更改,请重新启动Nginx以应用新配置:

      nginx -s reload
      
    • 设置权限: 确保所有上传的文件和目录具有正确的权限和所有权,以便Nginx能够访问它们。

  2. 维护和监控:

    • 日志文件监控: 定期检查Nginx的访问和错误日志文件,以了解流量模式和潜在的错误。这些日志通常位于/var/log/nginx/目录下。

    • 使用监控工具: 考虑使用系统监控工具,如htopglances,以监控服务器的资源使用情况。对于更高级的监控,可以使用像 Prometheus 这样的工具配合Grafana进行实时数据可视化。

    • 定期更新: 定期运行系统和软件包更新,以确保安全性和稳定性。使用以下命令可以更新Ubuntu系统和软件:

      sudo apt update
      sudo apt upgrade
      
    • 备份策略: 建立定期备份Web应用程序和服务器配置的流程。可以使用简单的脚本将重要数据复制到安全的备份位置。

    • SSL证书续期: 如果使用Let’s Encrypt SSL证书,确保自动续期配置正确。Certbot通常会安排一个cron作业或systemd定时器来处理这个过程。

通过遵循这些步骤,可以确保Flutter Web应用在Ubuntu服务器上稳定、安全地运行。维护和监控是保持Web应用程序健康运行的重要组成部分,不应被忽视。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。