在QML中导入JavaScript资源¶
描述如何在QML文档中导入和使用JavaScript资源
JavaScript 资源 可以被 QML 文档和其他 JavaScript 资源导入。JavaScript 资源可以通过相对或绝对 URL 导入。在相对 URL 的情况下,位置是相对于包含导入的 QML 文档 或 JavaScript 资源 的位置解析的。如果脚本文件无法访问,将会发生错误。如果 JavaScript 需要从网络资源获取,组件的 status
将被设置为“加载中”,直到脚本下载完成。
JavaScript 资源也可以导入 QML 模块和其他 JavaScript 资源。JavaScript 资源中的导入语句的语法与 QML 文档中的导入语句略有不同,下面将详细记录。
从QML文档导入JavaScript资源¶
一个QML文档可以使用以下语法导入JavaScript资源:
import "ResourceURL" as Qualifier
例如:
import "jsfile.js" as Logic
导入的JavaScript资源总是使用“as”关键字进行限定。JavaScript资源的限定符必须以大写字母开头,并且必须是唯一的,因此限定符和JavaScript文件之间总是一对一的映射关系。(这也意味着限定符不能命名为与内置JavaScript对象相同的名称,例如Date
和Math
)。
在导入的JavaScript文件中定义的函数可以通过"Qualifier.functionName(params)"
语法提供给导入的QML文档中定义的对象使用。JavaScript资源中的函数可以接受参数,这些参数的类型可以是任何QML值类型或对象类型,也可以是普通的JavaScript类型。当从QML调用这些函数时,正常的数据类型转换规则将适用于参数和返回值。
JavaScript资源中的导入¶
在QtQuick 2.0
中,增加了支持,允许JavaScript资源导入其他JavaScript资源以及使用标准QML导入语法的变体导入QML类型命名空间(其中所有先前描述的规则和限定条件都适用)。
由于JavaScript资源能够以这种方式在QtQuick 2.0
中导入另一个脚本或QML模块,因此定义了一些额外的语义:
带有导入的脚本不会从导入它的QML文档继承导入(例如,访问Component.errorString将会失败)
没有导入的脚本将从导入它的QML文档继承导入(例如,访问Component.errorString将会成功)
共享脚本(即定义为 .pragma library)不会从任何 QML 文档继承导入,即使它没有导入其他脚本或模块
第一个语义在概念上是正确的,考虑到一个特定的脚本可能会被任意数量的QML文件导入。第二个语义为了向后兼容的目的而保留。第三个语义与当前共享脚本的语义保持不变,但在这里针对新可能出现的情况(脚本导入其他脚本或模块)进行了澄清。
从另一个JavaScript资源导入JavaScript资源¶
一个JavaScript资源可以以下列方式导入另一个:
import * as MathFunctions from "factorial.mjs";
或者:
.import "filename.js" as Qualifier
前者是用于导入ECMAScript模块的标准ECMAScript语法,仅在以mjs
文件扩展名表示的ECMAScript模块内有效。后者是由QML
引擎提供的JavaScript扩展,也可以在非模块中使用。作为被ECMAScript标准取代的扩展,不鼓励使用它。
当以这种方式导入JavaScript文件时,它会带有一个限定符导入。然后,导入脚本中的函数可以通过限定符访问(即,作为Qualifier.functionName(params)
)。
有时希望在导入上下文中使函数可用而无需限定它们。在这种情况下,应使用ECMAScript模块和JavaScript import
语句,而不使用as
限定符。
例如,下面的QML代码左侧调用了script.mjs
中的showCalculations()
,而它又可以调用factorial.mjs
中的factorial()
,因为它已经使用import
包含了factorial.mjs
。
import QtQuick import "script.mjs" as MyScript Item { width: 100; height: 100 MouseArea { anchors.fill: parent onClicked: { MyScript.showCalculations(10) console.log("从QML调用factorial():", MyScript.factorial(10)) } } } // script.mjs import { factorial } from "factorial.mjs" export { factorial } export function showCalculations(value) { console.log( "从script.js调用factorial():", factorial(value)); } // 阶乘.mjs export function factorial(a) { a = parseInt(a); if (a <= 0) return 1; else return a * factorial(a - 1); }
include()
函数在不使用 ECMAScript 模块且不限定导入的情况下,从一个 JavaScript 文件包含另一个文件。它使另一个文件中的所有函数和变量在当前文件的命名空间中可用,但忽略该文件中定义的所有编译指示和导入。这不是一个好主意,因为函数调用不应修改调用者的上下文。
include()
已被弃用,应避免使用。它将在未来的 Qt 版本中被移除。
从JavaScript资源导入QML模块¶
一个JavaScript资源可以以下列方式导入一个QML模块:
.import TypeNamespace MajorVersion.MinorVersion as Qualifier
下面你可以看到一个示例,该示例还展示了如何在javascript中使用从模块导入的QML类型:
.import Qt.test 1.0 as JsQtTest var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3
特别是,这可能有助于访问通过单例类型提供的功能;有关更多信息,请参见QML_SINGLETON
。
默认情况下,您的 JavaScript 资源可以访问导入该资源的组件的所有导入。如果它被声明为无状态库(使用 .pragma library
)或包含显式的 .import
语句,则它无法访问组件的导入。