买家 PC 端组件
买家 PC 端的业务组件位于 apps/pc/src/components。PC 当前没有 components/index.ts barrel,页面按实际文件直接导入;不要套用 Admin/Seller 的 @/components 命名导入方式。
import AppEmpty from "@/components/AppEmpty.vue";
import Price from "@/components/Price.vue";
跨端公共组件仍从 @shop-tnt/components 导入:
import { RegionPicker, SafeHtml, useFeedback } from "@shop-tnt/components";
当前端内组件
| 组件 | 用途 |
|---|---|
AddressEditorDialog | 会员或企业收货地址新增、编辑弹窗 |
AppEmpty | PC 列表、区块和表格的空状态 |
AppPagination | PC 列表分页 |
AuthHeader | 登录、注册、找回密码、收银台等全屏页面头部 |
CartStep | 购物车、结算流程步骤 |
LoginDialog | 保留当前页面上下文的登录弹窗宿主 |
LoginForm | 登录页和登录弹窗复用的登录表单 |
MobileAreaInput | 手机区号与号码输入 |
NewcomerCouponDialog | 新人券结果弹窗 |
NewcomerCouponOffer | 首页新人券领取入口和加载流程 |
OrderCancelDialog | 订单取消及退款信息弹窗 |
Price | PC 商品价格、积分和划线价展示 |
该清单只表示当前源码存在的端内组件,不代表它们是跨端公共 API。
Price
价格展示统一使用 Price,避免页面重复实现负号、币种、小数位和积分组合:
<script setup lang="ts">
import Price from "@/components/Price.vue";
</script>
<template>
<Price :price="goods.goods_price" :point="goods.point" />
</template>
主要输入包括 price、point、currencySymbol、color、size、neg 和 lineThrough。组件会把非有限价格安全回退为 0.00,但业务接口仍应提供正确金额类型;展示兜底不能代替数据校验。
空状态与分页
列表页组合使用 AppEmpty 和 AppPagination:
<AppEmpty v-if="!rows.length" :title="t('暂无数据')" />
<AppPagination
v-else
:current="query.page_no"
:page-size="query.page_size"
:total="total"
@current-change="handlePageChange"
/>
空状态只在请求完成且数据确实为空时展示;加载失败应显示错误和重试入口,不能伪装成“暂无数据”。分页参数应与后端的 page_no、page_size 和 data_total 对齐。
登录页与登录弹窗
LoginForm 同时服务登录页和 LoginDialog。应用根组件只挂载一个 LoginDialog,页面需要弹窗登录时通过 @/composables/useLogin 请求:
import { requestLogin } from "@/composables/useLogin";
const loggedIn = await requestLogin();
if (!loggedIn) return;
不要在业务页面再挂载第二个登录弹窗。PC 路由的 loginMode: 'dialog' 只用于购物车、客服等需要保留上下文的体验;用户直接打开受保护 URL 时仍需有登录页回退。
地址和手机输入
AddressEditorDialog 组合地区、手机和地址校验;MobileAreaInput 在注册、绑定手机、发票等场景复用。调用方应保留后端字段契约,尤其是:
- 国家区号与手机号不能拼成不可逆的展示字符串。
- 地址 ID 和地区 ID 可能是字符串。
- 编辑回显完成前避免让用户提交半初始化表单。
- 关闭后重新打开必须清理旧校验状态和过期异步响应。
订单取消
OrderCancelDialog 负责取消原因和必要退款资料。页面必须从当前订单状态判断是否允许取消,并处理接口失败、重复提交和关闭后重开;不能仅依赖按钮隐藏阻止非法请求。
装修组件不是 PC 端内组件
首页、店铺页和专题页装修渲染来自 @shop-tnt/decor/pc-preview:
import {
DecorPcPreviewBlock,
DecorPcPreviewRenderer,
normalizeBlocks,
} from "@shop-tnt/decor/pc-preview";
不要把装修 Preview 文件复制到 apps/pc/src/components,也不要从 @shop-tnt/decor/editor 引入完整编辑器。
新增 PC 组件
- 只被一个页面使用时,优先放在该页面业务目录附近。
- 被多个 PC 页面复用时放入
apps/pc/src/components。 - 当前端继续采用直接文件导入,不自行增加与其他端不一致的隐式全局注册。
- Admin 或 Seller 出现真实复用后,再评估迁移到
packages/components。
组件使用 PascalCase 文件名、显式 props/emits 和 useTranslate()。PC 业务组件可以依赖 PC store、composable 和 API;一旦提升到共享包,必须移除这些端内依赖并改为 props、emits 或适配器。
验证
只修改 PC 端内组件时执行:
pnpm build:dev:pc
修改共享类型、API、装修或公共组件时执行:
pnpm typecheck
pnpm build:dev
交互验收应覆盖游客与登录用户、空数据、接口失败、直接 URL、弹窗反复打开、长文本和重复点击。PC 站点当前以 1210px 桌面布局为主,不能用移动端截图代替桌面验收。