uni-spec
移动端页面开发规范。开发 UI 界面时使用
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Menu
移动端页面开发规范。开发 UI 界面时使用
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Basé sur la classification professionnelle SOC
| name | uni-spec |
| description | 移动端页面开发规范。开发 UI 界面时使用 |
| compatibility | Uni-app + UnoCSS |
| metadata | {"version":"1.0"} |
uni-spec 负责页面开发规范、样式规范、通用页面约定tm-ui-components 负责 tm-ui 组件参数/事件/插槽/ref 与源码映射.agents/skills/tm-ui-components/references/components/*.md, 涉及行为差异再核对 src/uni_modules/tm-ui/components/$ref、$computed 等);vue 相关的类型和 API 如 ref、computed 等都无需导入,直接使用即可,因为 vite.config.mts 配置了自动导入 AutoImport[ ] 代表的是值时中间有空格,例如: const arr = [ 1, 2, 3 ];、const arr = [ ];,{ } 也同理;函数定义和调用时参数统一换行,vue 组件属性也统一换行pnpm typecheck;tsconfig_tc.json 才是正确的类型检查配置,tsconfig.json 只是为了编辑器提示tm-form-item 组件中如果不需要校验必填则必须添加 :required="false" 属性, 否则会默认校验必填, 例:<!-- 编码 -->
<tm-form-item
label="编码"
name="code"
:required="false"
>
<CustomInput
v-model="usr_input.code"
placeholder="请输入 编码"
></CustomInput>
</tm-form-item>
dayjs - 处理日期时间, 可直接使用, 无需引入decimal.js - 处理精确小数计算, 金额计算, 可直接使用, 无需引入numeral - 数字格式化, 可直接使用, 无需引入uno.config.ts 和 uno_uni.config.ts 中通过 UnoCSS presetIcons 注册了 iconfont collection,会自动读取 src/assets/iconfont/{icon_name}.svgun-i="iconfont-图标名" 挂在 view / text 等普通节点上,不要再写成 image + src,也不要用 new URL(...svg, import.meta.url) 去手动引资源un-text="[#f08b6a]"、un-w="5"、un-h="5"image 标签src/pages/product/Detail.vue 的收藏按钮写法<view
un-i="iconfont-favorite_service"
un-w="5"
un-h="5"
un-text="[#f08b6a]"
></view>
detail 这类富文本字段, 在当前仓库里通常保存的是 oss/tmpfile 附件 id, 不是 html 正文getDownloadUrl({ id, inline: "1" }) 拿到下载地址, 再用 uni.request 拉取 html 字符串tm-html 渲染拉取回来的 html 内容, 可参考 src/pages/product/Detail.vue<view
v-if="detail_html"
>
<tm-html
:value="detail_html"
></tm-html>
</view>
async function loadDetailHtml(
detail?: string,
) {
detail_html = "";
if (!detail) {
return;
}
const url = getDownloadUrl({
id: detail,
inline: "1",
});
const res = await uni.request({
url,
method: "GET",
});
detail_html = typeof res.data === "string"
? res.data
: String(res.data || "");
}
onLoad 生命周期钩子接收页面跳转传递的参数,禁止使用 getCurrentPages() 方式获取参数onLoad 的回调参数 query 包含页面 URL 中的查询参数initFrame())都应放在 onLoad 内部调用,而非直接在 setup 中调用onLoad(async (query?: AnyObject) => {
const some_param = query?.some_param;
if (some_param) {
search.some_field = decodeURIComponent(some_param);
}
await initFrame();
});
let inited = $ref(false); 标记是否初始化完成, 避免在初始化前触发表单变更事件is_form_hydrating 则表示表单是否正在数据回填watch 中必须区分初始化回填和用户编辑; 初始化阶段不要自动回写派生字段, 避免首屏展示值与数据库值不一致, 或用户未编辑就隐式改库:page-inited="inited"; 在初始化完成前隐藏 placeholder, 避免先出现空提示再被默认值或缓存值覆盖watch(
() => dyn_page_field_input,
() => {
if (!inited || is_form_hydrating) {
return;
}
// 处理表单变更逻辑
},
{
deep: true,
},
);
CustomInput 的 type="decimal" / type="number" 主要控制键盘或原生输入类型, 不会自动把 v-model 转成 Decimal / numberDecimal 实例时必须显式传 :is-decimal="true"; 需要数字时传 :is-number="true"lte、gt、eq 等 Decimal 方法, 状态就必须保持 Decimal, 不要只写 type="decimal"CustomInput 默认 isHideZero=true, 如果 0 需要在输入框里真实展示出来, 要补上 :is-hide-zero="false"<CustomInput
v-model="recharge_amount"
type="decimal"
:is-decimal="true"
inputmode="decimal"
:is-hide-zero="false"
placeholder="请输入充值金额"
></CustomInput>
uni.$emit / uni.$on, 事件名统一写成页面路径语义, 例如 "/pages/order/List:refresh"、"/pages/product/List:category_id_selected"uni.$off 一次同名监听, 销毁时再 uni.$off, 避免页面反复进入后重复注册onLoad / onUnload 中完成初始化和解绑; 被 tab 页直接 import 复用的“页面型组件”可以使用 onMounted / onUnmountedref 触发刷新, 统一暴露 refresh() 方法给外部调用const refresh_event_name = "/pages/order/List:refresh";
onLoad(async () => {
uni.$off(refresh_event_name, onPageRefresh);
uni.$on(refresh_event_name, onPageRefresh);
await initFrame();
});
onUnload(() => {
uni.$off(refresh_event_name, onPageRefresh);
});
async function initOrRefresh() {
if (!inited) {
await initFrame();
} else {
await onRefresh();
}
}
defineExpose({
refresh: initOrRefresh,
});
src/assets/style/common.scss:
--font-size: 32rpx,约等于 16px--font-size-sm: 28rpx,约等于 14pxun-text="数字" 时,不要把数字直接当成移动端常规字号;在当前 UnoCSS 配置下可近似理解为 数字 * 4 = px,例如 un-text="6" 约等于 24px,对普通列表正文通常明显偏大un-text="4" 左右un-text="3.5" 或接近 14px 的大小un-text="4.5" 到 un-text="5",除非是页面主标题,不要轻易使用 un-text="6" 及以上gray-200、gray-400、gray-700、red-500,尽量避免随手写零散十六进制颜色un-text="[#24324a]"gray-400gray-500 或 gray-600gray-700,不要用过浅灰色影响可读性<!-- ❌ 正文过大, 颜色也不够规范 -->
<view
un-text="6 [#24324a]"
un-font="700"
>
今日食堂菜单
</view>
<!-- ✅ 更接近当前 uni 仓库的移动端字号基线 -->
<view
un-text="5 gray-700"
un-font="700"
>
今日食堂菜单
</view>
<view
un-text="4 gray-700"
>
午餐 A: 红烧排骨 + 清炒时蔬 + 紫菜蛋花汤
</view>
<view
un-text="3.5 gray-500"
>
限时供应, 售完即止
</view>
将冗长的 class 拆分为语义化属性:
<!-- ❌ 传统方式 -->
<tm-button class="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono py-2 px-4 rounded border-2">
Button
</tm-button>
<!-- ✅ Attributify -->
<tm-button
un-bg="blue-400 hover:blue-500"
un-text="sm white"
un-font="mono"
un-p="y-2 x-4"
un-border="2 rounded"
>
Button
</tm-button>
~当属性名与值相同时使用:
<!-- border border-red → un-border="~ red" -->
<tm-button
un-border="~ red"
>
Button
</tm-button>
<!-- flex flex-col → un-flex="~ col" -->
<view
un-flex="~ col"
></view>
无参数工具类直接作为属性:
<view
un-rounded
un-truncate
un-italic
></view>
text-sm text-white → un-text="sm white"~:flex flex-col → un-flex="~ col"rounded → un-roundedsolid/颜色, 必须先用 0 清零其它边框: un-border="0 b-1 solid [#f0f2f5]", 不要写成 un-border="b-1 solid [#f0f2f5]"由 unplugin-auto-import 自动生成,无需手动维护。配置在 vite.config.mts 的 AutoImport({imports:[]}) 中
src/typings/auto-imports.d.ts 中的变量可直接使用:
// 如 dayjs、ref、computed 等
const now = dayjs().format('YYYY-MM-DD');
src/typings/uni.d.ts 中定义:const res = await uni.navigateTo({
url: "/pages/index/index",
});
src/typings/components2.d.ts 中的组件可直接在模板中使用:
<tm-button>Click Me</tm-button>
Create, analyze, proofread, and modify Office documents (.docx, .xlsx, .pptx) using the officecli CLI tool. Use when the user wants to create, inspect, check formatting, find issues, add charts, or modify Office documents.
tm-ui 组件 API 与源码定位。仅在需要核对某个 tm 组件的 props、events、slots、ref 方法或源码路径时使用;不要用于通用页面开发、样式规范或业务逻辑问题
创建新业务模块时使用
数据库建表规范。创建新表 SQL 时必须遵循;SQL 建完后必须继续阅读 table-config skill 来生成 {mod}.ts 配置
系统字典和业务字典配置。SQL 中有 dict: 或 dictbiz: 标注的字段时使用
仅在代码已写完、需要查库验证数据写入结果时使用。不要用于探索数据库结构或代替阅读代码