导航
电话
咨询
地图
顶部
本文旨在深入探讨React中Refs、DOM组件以及Ref转发(Ref Forwarding)机制,特别是澄清在React文档中“DOM组件”一词的含义及其与类组件实例的区别。我们将解析Refs如何用于访问DOM节点或组件实例,以及Ref转发在跨组件层级传递Refs时的重要作用,并提供示例代码以加深理解。
在React应用开发中,我们通常通过声明式的方式来构建用户界面。然而,在某些特定场景下,我们需要直接与底层DOM节点或React组件实例进行交互,例如管理焦点、触发动画、集成第三方DOM库等。React提供了Refs(引用)机制来满足这些需求。
Refs允许我们获取对React元素背后DOM节点或组件实例的直接引用。它们是逃离React声明式范式的“后门”,应谨慎使用,仅在必要时才采用。
在React的语境中,当文档提到“DOM组件”时,它通常指的是原生的HTML元素,例如, , 等。我们可以直接将Refs附加到这些DOM组件上,React会将该Ref指向对应的DOM节点。例如,如果我们有一个简单的按钮:import React, { useRef, useEffect } from 'react'; function MyButton() { const buttonRef = useRef(null); useEffect(() => { if (buttonRef.current) { console.log('按钮DOM节点:', buttonRef.current); buttonRef.current.focus(); // 直接操作DOM } }, []); return ( 点击我 ); }在这个例子中,buttonRef直接引用了这个DOM元素。 Ref转发(Ref Forwarding)机制 当Refs需要从父组件传递到一个自定义的子组件,并最终指向该子组件内部的某个DOM节点或另一个组件实例时,就需要使用Ref转发。这是因为默认情况下,自定义的函数组件或类组件不会将Refs直接传递给其内部的子元素。 为什么需要Ref转发? 考虑以下场景:一个父组件需要获取子组件内部的某个DOM元素的引用。如果子组件是一个函数组件,它没有实例,因此Ref无法直接附加到它上面。如果子组件是一个类组件,Ref会指向该类组件的实例,而不是其内部的DOM元素。为了让父组件能够“穿透”子组件,直接访问到子组件内部的特定元素,Ref转发应运而生。 Ref转发的实现 React提供了React.forwardRef函数来实现Ref转发。它接收一个渲染函数作为参数,这个渲染函数会接收props和ref作为参数。import React, { useRef, useEffect } from 'react'; // 假设我们有一个FancyButton组件,它是一个函数组件 const FancyButton = React.forwardRef((props, ref) => ( {props.children} )); function ParentComponent() { const buttonRef = useRef(null); useEffect(() => { if (buttonRef.current) { console.log('FancyButton内部的DOM节点:', buttonRef.current); buttonRef.current.focus(); } }, []); return ( 提交 ); }在这个例子中,ParentComponent将buttonRef传递给FancyButton。通过React.forwardRef,FancyButton能够接收到这个ref,并将其附加到它内部的元素上。最终,buttonRef.current将指向FancyButton内部的实际DOM 节点。 Ref转发到类组件实例 React文档中提到:“Ref转发不仅限于DOM组件。你也可以将Refs转发给类组件实例。” 这句话的含义是: “DOM组件” 在这里指的是Ref最终指向的原生HTML元素。 “类组件实例” 指的是Ref转发的最终目标可以是自定义的类组件的实例,而不仅仅是原生DOM元素。 这意味着,当我们将Ref转发到一个自定义的类组件时,该Ref将持有该类组件的实例,而非其内部的某个DOM节点。通过这个实例,我们可以调用类组件内部定义的方法或访问其属性。 考虑以下示例,一个父组件需要访问子类组件的实例:import React, { useRef, useEffect } from 'react'; // 子类组件 class ClassComponent extends React.Component { focusInput() { console.log('ClassComponent: 内部方法被调用'); // 假设这里有一个内部的input,我们可以通过内部ref来操作它 // this.internalInputRef.current.focus(); } render() { // innerRef是父组件通过forwardRef传递过来的ref return ( ); } } // 使用React.forwardRef将ref转发到ClassComponent const Input = React.forwardRef(function (props, ref) { // 注意:这里将父组件传递的ref作为props(innerRef)传递给ClassComponent // 这样ClassComponent就可以将这个ref附加到它内部的DOM元素上 return ; }); function App() { const classComponentRef = useRef(null); // 这个ref将指向ClassComponent的实例 useEffect(() => { if (classComponentRef.current) { console.log('获取到的Ref指向:', classComponentRef.current); // 如果ref指向ClassComponent的实例,我们可以调用其方法 // 注意:上面的ClassComponent将innerRef附加到了input上, // 所以classComponentRef.current将是input的DOM节点。 // 如果要获取ClassComponent的实例,ClassComponent需要将它自身的实例暴露出来, // 或者forwardRef直接返回ClassComponent本身(不推荐,通常用于DOM节点)。 // 为了演示获取类组件实例,我们需要稍微修改ClassComponent和forwardRef的用法: // ClassComponent的render方法不将ref附加到DOM,而是forwardRef直接返回ClassComponent // 如下面的修正: } }, []); const handleFocus = () => { if (classComponentRef.current) { // 假设ClassComponent内部有一个方法可以触发焦点 // 如果ref指向DOM节点,可以直接调用focus() classComponentRef.current.focus(); } }; return ( Ref转发到类组件内部的DOM节点 {}} /> 聚焦输入框 在这种情况下,classComponentRef.current 将指向 ClassComponent 内部的 zuojiankuohaophpcninputyoujiankuohaophpcn DOM节点。 ); } // 修正:如果Ref要指向类组件实例,而不是其内部DOM, // forwardRef的第二个参数(ref)不应直接传递给内部DOM元素。 // 而是ClassComponent本身需要被包装,并且ref指向ClassComponent的实例。 // 然而,React推荐Ref转发的最终目标是DOM节点。 // 如果确实需要访问类组件实例,通常直接将ref附加到类组件上即可, // 但这不涉及forwardRef。forwardRef主要是为了将ref“穿透”一个组件。 // 重新理解原文档的意图: // "Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too." // 这句话的重点在于,通过forwardRef,你可以将ref传递给一个子组件, // 这个子组件可以是最终渲染DOM的组件(如FancyButton), // 也可以是另一个自定义的类组件。当ref最终到达一个类组件时, // 如果你将这个ref直接附加到该类组件的*实例*上(而不是它内部的DOM), // 那么这个ref就会指向该类组件的实例。 // 但通常,forwardRef的目的是为了访问子组件内部的DOM节点。 // 让我们用一个更清晰的例子来演示如果ref直接指向类组件实例: class ChildClassComponent extends React.Component { sayHello() { console.log('Hello from ChildClassComponent instance!'); } render() { return 我是子类组件; } } // 如果一个父组件直接使用ChildClassComponent,ref会指向其实例 function ParentWithClassInstanceRef() { const childRef = useRef(null); useEffect(() => { if (childRef.current) { console.log('Ref指向类组件实例:', childRef.current); childRef.current.sayHello(); // 调用实例方法 } }, []); return ; } // forwardRef的场景通常是:父组件 -> 函数组件 (forwardRef) -> 类组件 (被包装) -> DOM // 例如: const ForwardedClassComponentWrapper = React.forwardRef((props, ref) => { // ref在这里会指向ClassComponent的实例 return ; // 这里innerRef仍然指向DOM // 如果要让ref指向ClassComponent实例,ClassComponent本身不应该有innerRef, // 而是forwardRef直接返回ClassComponent,但这不符合forwardRef的典型用法。 // 更准确的理解是: // forwardRef可以把ref传递给一个子组件,这个子组件可以是函数组件,也可以是类组件。 // 如果子组件是类组件,并且你把ref直接附加到这个类组件上(而不是它的内部DOM), // 那么ref就会指向这个类组件的实例。 // 让我们调整ClassComponent的示例,使其Ref真正指向类组件实例 }); // 最终示例:Ref转发到类组件内部的DOM元素 // 这是最常见且推荐的forwardRef用法 function TutorialApp() { const inputRef = useRef(null); useEffect(() => { if (inputRef.current) { console.log('通过Ref转发获取到输入框DOM节点:', inputRef.current); inputRef.current.focus(); } }, []); return ( Ref转发到类组件内部的DOM元素 通过 React.forwardRef,我们可以将父组件的 Ref 传递给一个中间组件(这里是 InputWrapper), 然后由这个中间组件将 Ref 进一步传递给其内部的类组件 ClassComponent, 最终 ClassComponent 将这个 Ref 附加到它所渲染的 zuojiankuohaophpcninputyoujiankuohaophpcn DOM 元素上。 这样,父组件的 Ref 就可以直接访问到最深层的 DOM 节点。 {}} /> inputRef.current && inputRef.current.select()}> 选中输入框内容 ); } export default TutorialApp;在上面的 Input 组件的例子中,React.forwardRef 接收到的 ref 被作为 innerRef prop 传递给 ClassComponent。ClassComponent 随后将这个 innerRef 附加到它渲染的 元素上。因此,当你在 App 组件中访问 inputRef.current 时,你实际上得到的是 元素的 DOM 节点,而不是 ClassComponent 的实例。 如果真的需要获取 ClassComponent 的实例,而不是它内部的 DOM 节点,那么 ClassComponent 应该是一个直接的子组件,并且 ref 直接附加到它上面(不通过 forwardRef 穿透)。forwardRef 的主要目的是为了穿透组件层级,访问到内部的 DOM 节点。 总结一下文档的含义: “Ref转发不限于DOM组件(即直接将Ref指向原生HTML元素)。你也可以将Refs转发给类组件实例。” 这句话的深层含义是: forwardRef 可以让你将一个Ref从父组件传递下去,最终指向一个原生的DOM元素(这是最常见的用法)。 forwardRef 也可以让你将一个Ref从父组件传递下去,最终指向一个子类组件的实例。这通常发生在子组件本身就是一个类组件,并且你希望通过Ref获取到该类组件的实例,以便调用其方法或访问其内部状态(尽管这通常被认为是反模式,应优先使用props和state)。 注意事项与最佳实践 Refs的滥用: 避免过度使用Refs。在大多数情况下,通过props和state进行数据流管理是更推荐的React范式。Refs主要用于那些无法通过声明式方式实现的场景。 Refs与函数组件: 函数组件默认没有实例,因此不能直接附加Refs。必须使用React.forwardRef才能将Refs传递给函数组件,并由其转发到内部的DOM节点或类组件。 Refs的生命周期: Refs在组件挂载后才可用,在组件卸载时变为null。 Refs的类型: 当Ref指向DOM元素时,ref.current是DOM节点;当Ref指向类组件时,ref.current是类组件的实例。 结论 Refs是React中一个强大的工具,用于直接访问DOM节点或组件实例。Ref转发机制,通过React.forwardRef,解决了Refs在组件层级间传递的问题,使得父组件能够“穿透”子组件,访问到深层级的DOM元素或类组件实例。理解“DOM组件”在文档中的具体语境以及Ref转发的灵活性,对于编写健壮和高效的React应用至关重要。正确地使用Refs和Ref转发,能够帮助我们处理复杂的交互和集成需求,同时保持React应用的声明式特性。
例如,如果我们有一个简单的按钮:
import React, { useRef, useEffect } from 'react'; function MyButton() { const buttonRef = useRef(null); useEffect(() => { if (buttonRef.current) { console.log('按钮DOM节点:', buttonRef.current); buttonRef.current.focus(); // 直接操作DOM } }, []); return ( 点击我 ); }
在这个例子中,buttonRef直接引用了这个DOM元素。
当Refs需要从父组件传递到一个自定义的子组件,并最终指向该子组件内部的某个DOM节点或另一个组件实例时,就需要使用Ref转发。这是因为默认情况下,自定义的函数组件或类组件不会将Refs直接传递给其内部的子元素。
考虑以下场景:一个父组件需要获取子组件内部的某个DOM元素的引用。如果子组件是一个函数组件,它没有实例,因此Ref无法直接附加到它上面。如果子组件是一个类组件,Ref会指向该类组件的实例,而不是其内部的DOM元素。为了让父组件能够“穿透”子组件,直接访问到子组件内部的特定元素,Ref转发应运而生。
React提供了React.forwardRef函数来实现Ref转发。它接收一个渲染函数作为参数,这个渲染函数会接收props和ref作为参数。
import React, { useRef, useEffect } from 'react'; // 假设我们有一个FancyButton组件,它是一个函数组件 const FancyButton = React.forwardRef((props, ref) => ( {props.children} )); function ParentComponent() { const buttonRef = useRef(null); useEffect(() => { if (buttonRef.current) { console.log('FancyButton内部的DOM节点:', buttonRef.current); buttonRef.current.focus(); } }, []); return ( 提交 ); }
在这个例子中,ParentComponent将buttonRef传递给FancyButton。通过React.forwardRef,FancyButton能够接收到这个ref,并将其附加到它内部的元素上。最终,buttonRef.current将指向FancyButton内部的实际DOM 节点。
React文档中提到:“Ref转发不仅限于DOM组件。你也可以将Refs转发给类组件实例。” 这句话的含义是:
这意味着,当我们将Ref转发到一个自定义的类组件时,该Ref将持有该类组件的实例,而非其内部的某个DOM节点。通过这个实例,我们可以调用类组件内部定义的方法或访问其属性。
考虑以下示例,一个父组件需要访问子类组件的实例:
import React, { useRef, useEffect } from 'react'; // 子类组件 class ClassComponent extends React.Component { focusInput() { console.log('ClassComponent: 内部方法被调用'); // 假设这里有一个内部的input,我们可以通过内部ref来操作它 // this.internalInputRef.current.focus(); } render() { // innerRef是父组件通过forwardRef传递过来的ref return ( ); } } // 使用React.forwardRef将ref转发到ClassComponent const Input = React.forwardRef(function (props, ref) { // 注意:这里将父组件传递的ref作为props(innerRef)传递给ClassComponent // 这样ClassComponent就可以将这个ref附加到它内部的DOM元素上 return ; }); function App() { const classComponentRef = useRef(null); // 这个ref将指向ClassComponent的实例 useEffect(() => { if (classComponentRef.current) { console.log('获取到的Ref指向:', classComponentRef.current); // 如果ref指向ClassComponent的实例,我们可以调用其方法 // 注意:上面的ClassComponent将innerRef附加到了input上, // 所以classComponentRef.current将是input的DOM节点。 // 如果要获取ClassComponent的实例,ClassComponent需要将它自身的实例暴露出来, // 或者forwardRef直接返回ClassComponent本身(不推荐,通常用于DOM节点)。 // 为了演示获取类组件实例,我们需要稍微修改ClassComponent和forwardRef的用法: // ClassComponent的render方法不将ref附加到DOM,而是forwardRef直接返回ClassComponent // 如下面的修正: } }, []); const handleFocus = () => { if (classComponentRef.current) { // 假设ClassComponent内部有一个方法可以触发焦点 // 如果ref指向DOM节点,可以直接调用focus() classComponentRef.current.focus(); } }; return ( Ref转发到类组件内部的DOM节点 {}} /> 聚焦输入框 在这种情况下,classComponentRef.current 将指向 ClassComponent 内部的 zuojiankuohaophpcninputyoujiankuohaophpcn DOM节点。 ); } // 修正:如果Ref要指向类组件实例,而不是其内部DOM, // forwardRef的第二个参数(ref)不应直接传递给内部DOM元素。 // 而是ClassComponent本身需要被包装,并且ref指向ClassComponent的实例。 // 然而,React推荐Ref转发的最终目标是DOM节点。 // 如果确实需要访问类组件实例,通常直接将ref附加到类组件上即可, // 但这不涉及forwardRef。forwardRef主要是为了将ref“穿透”一个组件。 // 重新理解原文档的意图: // "Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too." // 这句话的重点在于,通过forwardRef,你可以将ref传递给一个子组件, // 这个子组件可以是最终渲染DOM的组件(如FancyButton), // 也可以是另一个自定义的类组件。当ref最终到达一个类组件时, // 如果你将这个ref直接附加到该类组件的*实例*上(而不是它内部的DOM), // 那么这个ref就会指向该类组件的实例。 // 但通常,forwardRef的目的是为了访问子组件内部的DOM节点。 // 让我们用一个更清晰的例子来演示如果ref直接指向类组件实例: class ChildClassComponent extends React.Component { sayHello() { console.log('Hello from ChildClassComponent instance!'); } render() { return 我是子类组件; } } // 如果一个父组件直接使用ChildClassComponent,ref会指向其实例 function ParentWithClassInstanceRef() { const childRef = useRef(null); useEffect(() => { if (childRef.current) { console.log('Ref指向类组件实例:', childRef.current); childRef.current.sayHello(); // 调用实例方法 } }, []); return ; } // forwardRef的场景通常是:父组件 -> 函数组件 (forwardRef) -> 类组件 (被包装) -> DOM // 例如: const ForwardedClassComponentWrapper = React.forwardRef((props, ref) => { // ref在这里会指向ClassComponent的实例 return ; // 这里innerRef仍然指向DOM // 如果要让ref指向ClassComponent实例,ClassComponent本身不应该有innerRef, // 而是forwardRef直接返回ClassComponent,但这不符合forwardRef的典型用法。 // 更准确的理解是: // forwardRef可以把ref传递给一个子组件,这个子组件可以是函数组件,也可以是类组件。 // 如果子组件是类组件,并且你把ref直接附加到这个类组件上(而不是它的内部DOM), // 那么ref就会指向这个类组件的实例。 // 让我们调整ClassComponent的示例,使其Ref真正指向类组件实例 }); // 最终示例:Ref转发到类组件内部的DOM元素 // 这是最常见且推荐的forwardRef用法 function TutorialApp() { const inputRef = useRef(null); useEffect(() => { if (inputRef.current) { console.log('通过Ref转发获取到输入框DOM节点:', inputRef.current); inputRef.current.focus(); } }, []); return ( Ref转发到类组件内部的DOM元素 通过 React.forwardRef,我们可以将父组件的 Ref 传递给一个中间组件(这里是 InputWrapper), 然后由这个中间组件将 Ref 进一步传递给其内部的类组件 ClassComponent, 最终 ClassComponent 将这个 Ref 附加到它所渲染的 zuojiankuohaophpcninputyoujiankuohaophpcn DOM 元素上。 这样,父组件的 Ref 就可以直接访问到最深层的 DOM 节点。 {}} /> inputRef.current && inputRef.current.select()}> 选中输入框内容 ); } export default TutorialApp;
在这种情况下,classComponentRef.current 将指向 ClassComponent 内部的 zuojiankuohaophpcninputyoujiankuohaophpcn DOM节点。
classComponentRef.current
ClassComponent
zuojiankuohaophpcninputyoujiankuohaophpcn
我是子类组件
通过 React.forwardRef,我们可以将父组件的 Ref 传递给一个中间组件(这里是 InputWrapper), 然后由这个中间组件将 Ref 进一步传递给其内部的类组件 ClassComponent, 最终 ClassComponent 将这个 Ref 附加到它所渲染的 zuojiankuohaophpcninputyoujiankuohaophpcn DOM 元素上。 这样,父组件的 Ref 就可以直接访问到最深层的 DOM 节点。
React.forwardRef
InputWrapper
在上面的 Input 组件的例子中,React.forwardRef 接收到的 ref 被作为 innerRef prop 传递给 ClassComponent。ClassComponent 随后将这个 innerRef 附加到它渲染的 元素上。因此,当你在 App 组件中访问 inputRef.current 时,你实际上得到的是 元素的 DOM 节点,而不是 ClassComponent 的实例。
如果真的需要获取 ClassComponent 的实例,而不是它内部的 DOM 节点,那么 ClassComponent 应该是一个直接的子组件,并且 ref 直接附加到它上面(不通过 forwardRef 穿透)。forwardRef 的主要目的是为了穿透组件层级,访问到内部的 DOM 节点。
总结一下文档的含义: “Ref转发不限于DOM组件(即直接将Ref指向原生HTML元素)。你也可以将Refs转发给类组件实例。” 这句话的深层含义是:
Refs是React中一个强大的工具,用于直接访问DOM节点或组件实例。Ref转发机制,通过React.forwardRef,解决了Refs在组件层级间传递的问题,使得父组件能够“穿透”子组件,访问到深层级的DOM元素或类组件实例。理解“DOM组件”在文档中的具体语境以及Ref转发的灵活性,对于编写健壮和高效的React应用至关重要。正确地使用Refs和Ref转发,能够帮助我们处理复杂的交互和集成需求,同时保持React应用的声明式特性。
# app # html # 工具 # 文档 # 区别 # 是一个 # 为什么 # input # 自定义 # 子类 # 而不是 # NULL # 我们可以 # 这句话 # 到它 # dom # react # 输入框 # 有一个 # 应用开发 # html元素
相关栏目: 【 行业资讯 】 【 网络运营 】 【 GEO优化 】 【 营销推广 】 【 SEO优化 】 【 技术教程 】 【 代码知识 】 【 AI推广 】
相关推荐: Win11怎么关闭通知中心_Windows11系统通知与专注助手设置 Windows10任务栏图标变成白色文件_Win10重建图标缓存修复方法 How to Properly Use NumPy in VS Code Win11怎么关闭系统提示音_Windows11声音方案设为无声教程 php下载安装包怎么选_threadsafe与nts版本差异【解答】 php订单日志怎么在swoole写_php协程swoole写订单日志教程【教程】 Go 语言标准库为何不提供泛型 Contains 方法:设计哲学与类型系统约束 如何使用Golang实现聊天室消息存档_存储聊天记录到文件 php查询数据怎么导出csv_查询结果转csv文件保存【操作】 Mac如何调整Dock栏大小和位置_Mac程序坞个性化设置 Win11键盘快捷键大全_Windows 11常用高效快捷键汇总【技巧】 如何在Golang中实现CI/CD流水线自动化测试_Golang持续集成测试执行方法 MAC的“接续互通”功能无法使用怎么办_MAC检查蓝牙、Wi-Fi和相同Apple ID登录 如何使用Golang配置安全开发环境_防止敏感信息泄露 c++如何获取map中所有的键_C++遍历键值对提取所有key的方法 Win11怎么关闭搜索历史_Win11清除任务栏搜索记录【隐私】 新手学PHP架构总混淆概念咋办_重点梳理【教程】 windows系统如何安装cab更新补丁_windows手动安装更新包教程 Python数据抓取合法性_合规说明【指导】 Windows10如何更改鼠标图标_Win10鼠标属性指针浏览 Win11怎么自动隐藏任务栏_Win11全屏显示设置【美化】 Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】 Mac版Final Cut Pro入门_Mac视频剪辑基础操作【教程】 mac本地php环境如何开启curl_curl扩展启用与测试步骤详解【汇总】 Win10怎么创建桌面快捷方式 Win10为应用创建快捷方式【步骤】 如何在Golang中优化文件读写性能_使用缓冲和并发处理 Win10电脑怎么设置休眠快捷键_Windows10电源按钮功能定义 Go 中 defer 在 goroutine 内部不生效的原因与执行时机详解 Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】 Windows10电脑怎么设置自动连接WiFi_Win10无线网络属性勾选 php增删改查需要哪些扩展_开启mysqli或pdo扩展方法【说明】 如何使用Golang优化模块引入路径_Golanggo mod tidy清理与优化方法 Win10怎样卸载iTunes_Win10卸载iTunes步骤【步骤】 Windows10系统怎么查看CPU核心数_Win10逻辑处理器数量查看 Win10怎样安装PPT模板_Win10安装PPT模板教程【步骤】 如何使用Golang实现Web表单数据绑定_自动映射字段到结构体 Windows 11如何查看系统激活密钥_Windows 11使用CMD或PowerShell命令找回Product Key Win11怎么卸载Photos应用_Win11卸载Photos应用方法【教程】 Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言 Win11怎么设置默认PDF阅读器 Win11修改PDF打开方式【步骤】 Windows11如何设置专注助手_Windows11专注助手使用攻略【技巧】 php8.4如何调用com组件_php8.4windows下com操作指南【教程】 如何用::实现工具类方法调用_php静态工具类设计技巧【技巧】 如何在 Go 结构体中正确初始化 map 字段 MAC怎么解压RAR格式文件_MAC第三方解压工具安装与压缩包管理【教程】 Win11怎么清理C盘系统错误报告_Win11清理系统错误报告技巧【教程】 Windows10蓝屏SYSTEM_SERVICE_EXCEPTION_Win10驱动冲突排查 c# Task.ConfigureAwait(true) 在什么场景下是必须的 Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置 Win11怎么开启游戏模式_Windows11优化游戏帧数设置指南
赣ICP备2024031479号