JavaScript resources 可能由 QML 文档和其他 JavaScript 资源导入。JavaScript 资源可以通过相对或绝对 URL 导入。在相对 URL 的情况下,该位置相对于包含导入的 QML documentJavaScript Resource 的位置进行解析。如果脚本文件不可访问,则会发生错误。如果需要从网络资源中获取 JavaScript,则组件的 status 将设置为“正在加载”,直到脚本下载完毕。

JavaScript 资源还可以导入 QML 模块和其他 JavaScript 资源。JavaScript 资源中的 import 语句的语法与 QML 文档中的 import 语句略有不同,下面详细记录了这一点。

5.4.1 从 QML 文档导入 JavaScript 资源

QML 文档可以使用以下语法导入 JavaScript 资源:

  1. //语法
  2. import "ResourceURL" as Qualifier
  3. //示例
  4. import "jsfile.js" as Logic

必须使用 as 关键字进行限定且以大写字母开头,唯一。因此限定符和 JavaScript 文件之间始终存在一对一的映射关系。 (这也意味着限定符不能与内置 JavaScript 对象(如 Date 和 Math)命名相同。

通过“Qualifier.functionName(params)”语法,导入的 JavaScript 文件中定义的函数可用于导入 QML 文档中定义的对象。JavaScript 资源中的函数可以采用参数,其类型可以是任何受支持的 QML 基本类型或对象类型,以及普通的 JavaScript 类型。从 QML 调用此类函数时,通常的数据类型转换规则将适用于参数和返回值。

5.4.2 JavaScript 资源中的导入

QtQuick 2.0 中,添加了支持以允许 JavaScript 资源导入其他 JavaScript 资源以及使用标准 QML 导入语法的变体的 QML 类型命名空间(所有先前描述的规则和限定都适用)。

由于 JavaScript 资源能够在 QtQuick 2.0 中以这种方式导入另一个脚本或 QML 模块,因此定义了一些额外的语义:

  • 带有导入的脚本不会从导入它的 QML 文档继承导入(例如,访问 Component.errorString 将失败)
  • 没有导入的脚本将从导入它的 QML 文档继承导入(例如,访问 Component.errorString 将成功)
  • 共享脚本(即,定义为 .pragma 库)不会从任何 QML 文档继承导入,即使它没有导入其他脚本或模块

第一个语义在概念上是正确的,因为任何数量的 QML 文件都可能导入一个特定的脚本。保留第二个语义是为了向后兼容。第三个语义与共享脚本的当前语义保持不变,但在此处针对新的可能情况(脚本导入其他脚本或模块)进行了澄清。

5.4.2.1 从另一个 JavaScript 资源导入一个 JavaScript 资源

一个 JavaScript 资源可以通过以下方式导入另一个:

  1. import * as MathFunctions from "factorial.mjs";
  2. //或者是
  3. .import "filename.js" as Qualifier

前者是用于导入 ECMAScript 模块的标准 ECMAScript 语法,并且只能在由 mjs 文件扩展名表示的 ECMAScript 模块内工作。后者是 QML 引擎提供的 JavaScript 扩展,也适用于非模块。作为被 ECMAScript 标准取代的扩展,不鼓励使用它。

以这种方式导入 JavaScript 文件时,将使用限定符导入它。 然后可以通过限定符(即,作为 Qualifier.functionName(params))从导入脚本访问该文件中的函数。

有时需要在导入上下文中提供函数而不需要限定它们。 在这种情况下,ECMAScript 模块和 JavaScript 导入语句应该在没有 as 限定符的情况下使用。

例如,左下方的 QML 代码调用 script.mjs 中的 showCalculations(),后者又可以调用 factorial.mjs 中的 factorial(),因为它使用导入包含了 factorial.mjs:

  1. import QtQuick 2.0
  2. import "script.mjs" as MyScript
  3. Item {
  4. width: 100; height: 100
  5. MouseArea {
  6. anchors.fill: parent
  7. onClicked: {
  8. MyScript.showCalculations(10)
  9. console.log("Call factorial() from QML:",
  10. MyScript.factorial(10))
  11. }
  12. }
  13. }
  14. //
  15. // script.mjs
  16. import { factorial } from "factorial.mjs"
  17. export { factorial }
  18. export function showCalculations(value) {
  19. console.log(
  20. "Call factorial() from script.js:",
  21. factorial(value));
  22. }
  23. // factorial.mjs
  24. export function factorial(a) {
  25. a = parseInt(a);
  26. if (a <= 0)
  27. return 1;
  28. else
  29. return a * factorial(a - 1);
  30. }

Qt.include() 函数在不使用 ECMAScript 模块和不限定导入的情况下包含来自另一个的一个 JavaScript 文件。 它使来自其他文件的所有函数和变量在当前文件的命名空间中可用,但忽略该文件中定义的所有编译指示和导入。 这不是一个好主意,因为函数调用永远不应该修改调用者的上下文。Qt.include() 已弃用,应避免使用。它将在 Qt 的未来版本中删除。

5.4.2.2 从 JavaScript 资源导入 QML 模块

JavaScript 资源可以通过以下方式导入 QML 模块:

  1. .import TypeNamespace MajorVersion.MinorVersion as Qualifier

您可以在下面看到一个示例,该示例还展示了如何使用 javascript 中导入的模块中的 QML 类型:

  1. .import Qt.test 1.0 as JsQtTest
  2. var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3

特别是,这对于访问通过单例类型提供的功能可能很有用; 有关更多信息,请参阅 QML_SINGLETON

注意:.import 语法不适用于 WorkerScript 中使用的脚本