页面源码开发
大多数页面工作可以在 Design、Inspector 和 AI Command Center 中完成,不需要先学习前端框架。只有在需要精确状态逻辑、自定义事件、复杂样式或可复用 Component 时,才需要进入 Source。
源码技术
Page (.qp) 与 Component (.qpc) 使用 Svelte 5 源码,并支持标准 HTML、CSS 和 TypeScript。Design 与 Source 编辑的是同一份页面内容:在任一模式保存后,另一种模式会读取相同结果。
常见源码能力包括:
- 用
$state保存当前 Page 实例的临时界面状态; - 用 TypeScript 函数处理页面事件;
- 用 props、事件或 callback 连接 Page 与 Component;
- 从
.qp或.qpc通过相对路径导入 App Component; - 使用
@theseus/qp-core与已安装功能包公开的 Component。
<script lang="ts">
let running = $state(false);
function toggleRunning() {
running = !running;
}
</script>
<button onclick={toggleRunning}>
{running ? "停止模拟" : "开始模拟"}
</button>
Component 根与权限
App 自定义 .qpc 以 @theseus/qp-core/Widget 作为唯一可测量根,通过 props 接收业务值,通过事件或 callback 把用户动作交给 Page,并转发 class、style、必要的 DOM 属性、requiredRoles 和 unauthorized。
角色列表为空时所有人可见;多个角色按任意匹配,App Admin 始终匹配。未匹配时,hidden 隐藏整个根,disabled 保留显示但禁止交互。原生 HTML 元素不直接拥有这些 Component 权限属性。界面显示规则不能替代 Object、Query、文件或 Safety 能力自己的授权。
从 .qp 或另一个 .qpc 使用相对路径导入 App Component。功能包 Component 使用其公开模块路径;不要复制功能包内部源码。
Component 目录元数据
App Component 可以在源码开头的 @component 注释中声明 Palette 使用的简介、单一类别和多个 tag:
<!--
@component 显示并选择当前工位的生产日期。
@category input
@tags form, date-time, selection
@insert <ProductionDate label="生产日期" />
-->
@category 只能使用 application、layout、navigation、action、input、data-display、visualization、feedback、overlay、media 或 composition。@tags 最多 8 个,以逗号或空格分隔;每个 tag 使用小写 kebab-case,最长 32 个字符。同一注释中不能重复声明类别、tag 列表或相同 tag。错误的元数据会产生明确的源码检查错误,不会被静默忽略。
可选的单行 @insert 使用普通 QP/Svelte 标记,声明用户从 Palette 拖入组件时生成的初始属性、文字和尺寸。它必须只包含一个与当前组件同名的根组件;不能包含 <script> 或 <style>。@insert 只影响首次插入的源码,不会改变组件的运行时默认行为。没有声明 @insert 的组件继续使用通用空实例。
类别决定 Palette 的默认分组;类别、tag、简介、来源和目录都会参与搜索。筛选时,同一维度内是“任一匹配”,类别、来源、tag 三个维度之间是“同时满足”。
使用 App 能力
页面源码通过 getApp() 使用 App 级 Query、Variable、导航和当前角色。getApp().role 始终是字符串:允许访客且尚未登录时为 Guest,登录后是账号配置的角色。外部服务地址和认证仍应集中放在 Settings → 查询,不要散落到多个 Page。多语言文案通过 @qx/i18n 使用;语言和消息仍在 Settings → 多语言(I18n) 中维护。
需要显示或切换当前操作员时,使用 CurrentUser,并把它放在不会被自身角色规则隐藏的位置:
<script lang="ts">
import CurrentUser from "@theseus/qp-core/CurrentUser";
import { getApp } from "@qx/app";
const app = getApp();
const isGuest = $derived(app.role === "Guest");
</script>
<CurrentUser />
直接比较 app.role 适合调整文案或呈现;共享 Component 权限仍使用 requiredRoles。CurrentUser 只管理 App user,不会切换 Qixin 账号或运行目标账户。
工程边界
- 页面事件只负责界面协调;设备步骤、等待、超时、恢复和安全联锁应放在 Object、QG 或经过审核的 Provider 中。
$state属于当前页面实例,刷新或重新进入页面后会重置。耐久数据应使用明确的 App 或 Object 存储能力。- App 只能使用已安装功能包公开的模块,不要引入项目未管理的外部依赖或复制功能包内部源码。
- 实时标记跟随当前打开文档;Problems 保存最近一次 Build 对已保存工程文件的诊断。交付前必须保存、Build,并在真实运行页或 Player 中验收。