在 QML 中导入 JavaScript 资源

JavaScript 资源可以由 QML 文档和其他 JavaScript 资源导入。JavaScript 资源可以通过相对或绝对 URL 进行导入。在相对 URL 的情况下,位置是基于包含导入的 QML 文档JavaScript 资源 解析的。如果脚本文件不可访问,将发生错误。如果需要从网络资源获取 JavaScript,则组件的 status 会被设置为 "Loading",直到脚本下载完成。

JavaScript 资源还可以导入 QML 模块和其他 JavaScript 资源。与在 QML 文档内导入语句的语法略有不同,文档对这一问题有详细说明。

从 QML 文档导入 JavaScript 资源

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

import "ResourceURL" as Qualifier

例如

import "jsfile.js" as Logic

导入的 JavaScript 资源始终使用 "as" 关键字进行限定。JavaScript 资源的限定符必须以大写字母开头,并且必须是唯一的,因此限定符与 JavaScript 文件之间存在一对一映射。(这也意味着限定符不能与内置 JavaScript 对象(如 DateMath)同名)。

在导入的 JavaScript 文件中定义的函数可以通过 "Qualifier.functionName(params)" 语法在导入的 QML 文档中的对象中调用。JavaScript 资源中的函数可以接受任何 QML 值类型或对象类型的参数,以及常规 JavaScript 类型。当从 QML 调用此类函数时,将应用常规的 数据类型转换规则 至参数和返回值。

JavaScript 资源内的导入

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

由于在 QtQuick 2.0 中 JavaScript 资源可以以这种方式导入其他脚本或 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模块导入的语法,并且仅在标记为具有mjs文件扩展名的ECMAScript模块中使用。后者是由QML引擎提供的JavaScript扩展,也可以与非模块一起使用。作为被ECMAScript标准取代的扩展,不建议使用。

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

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

例如,下面的QML代码左端在script.mjs中调用showCalculations(),而script.mjs随后可以调用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("Call factorial() from QML:",
                MyScript.factorial(10))
        }
    }
}
// script.mjs
import { factorial } from "factorial.mjs"
export { factorial }

export function showCalculations(value) {
    console.log(
        "Call factorial() from script.js:",
        factorial(value));
}
// factorial.mjs
export function factorial(a) {
    a = parseInt(a);
    if (a <= 0)
        return 1;
    else
        return a * factorial(a - 1);
}

Qt.include()函数从一个文件中包含一个JavaScript文件而无需使用ECMAScript模块且不需要限定导入。它将其他文件中所有函数和变量都可用于当前文件的命名空间,但忽略在该文件中定义的所有指令和导入。这不是一个好的主意,因为函数调用永远不应该修改调用者的环境。

Qt.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语句,则它无法访问该组件的导入。

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

另请参阅在QML中定义JavaScript资源

© 2024Qt公司有限公司。本文档中的文档贡献的版权归其所有者。本文件中的文档是在自由软件基金会发布的GNU自由文档许可协议版本1.3的条款下授予的。Qt和相应的标志是芬兰和/或世界其他地区的The Qt Company Ltd.的商标。所有其他商标均为其所有者的财产。