跳到主要内容

买家 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会员或企业收货地址新增、编辑弹窗
AppEmptyPC 列表、区块和表格的空状态
AppPaginationPC 列表分页
AuthHeader登录、注册、找回密码、收银台等全屏页面头部
CartStep购物车、结算流程步骤
LoginDialog保留当前页面上下文的登录弹窗宿主
LoginForm登录页和登录弹窗复用的登录表单
MobileAreaInput手机区号与号码输入
NewcomerCouponDialog新人券结果弹窗
NewcomerCouponOffer首页新人券领取入口和加载流程
OrderCancelDialog订单取消及退款信息弹窗
PricePC 商品价格、积分和划线价展示

该清单只表示当前源码存在的端内组件,不代表它们是跨端公共 API。

Price

价格展示统一使用 Price,避免页面重复实现负号、币种、小数位和积分组合:

<script setup lang="ts">
import Price from "@/components/Price.vue";
</script>

<template>
<Price :price="goods.goods_price" :point="goods.point" />
</template>

主要输入包括 pricepointcurrencySymbolcolorsizeneglineThrough。组件会把非有限价格安全回退为 0.00,但业务接口仍应提供正确金额类型;展示兜底不能代替数据校验。

空状态与分页

列表页组合使用 AppEmptyAppPagination

<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_nopage_sizedata_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 组件

  1. 只被一个页面使用时,优先放在该页面业务目录附近。
  2. 被多个 PC 页面复用时放入 apps/pc/src/components
  3. 当前端继续采用直接文件导入,不自行增加与其他端不一致的隐式全局注册。
  4. 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 桌面布局为主,不能用移动端截图代替桌面验收。