自定义模板与自定义代码区块的区别
- 自定义模板用你自己的标记替换现有区块的渲染,并把该区块自身的数据交给你(Header 的标题和商品数量、Summary 的总额等等)。它不会添加任何新内容;它只是为一个区块重新设计样式。
- **自定义代码**区块则是在购物车的任意位置添加一个新区块,内容为任意 HTML 或 React。
使用自定义模板
- 在编辑器中选择一个区块并打开其 Code 标签页。
- 编辑默认模板。自定义模板仅支持 JSX(HTML 或 JSX 的选择仅限于自定义代码区块)。
- 点击 Compile。编译会去除类型并转译 JSX,因此它能捕获语法错误。类型错误不会阻止编译——编辑器会在你输入时以内联方式标记它们,并提供可自动补全区块 props 的同款 IntelliSense。
- 启用模板,让购物车使用它替代内置渲染。
- Reset to default 可随时恢复该区块的原始模板。
用 AI 编写模板
- 编译规则(单一表达式、无
export default、无导入) - 该区块接收的确切 props,与编辑器 IntelliSense 显示的一致
- 编辑器强制执行的锁定函数签名
- 区块特定规则(货币格式、需要接线的处理函数、无障碍要求)
- 一个填空部分,供你粘贴当前模板并描述想要的改动
提示词是针对每个区块定制的。Copy AI prompt 按钮只出现在支持自定义模板的区块上。
你的模板替换了什么
你保留的内容:区块在购物车中的位置、其可见性开关、其设置(这些设置仍会作为你接收的 props 的数据来源)、购物车的自定义 CSS 面板,以及内置的加载骨架屏。
最后一项常让人意外。区块会在到达你的模板之前检查购物车是否仍在加载,所以内置骨架屏会在加载期间渲染,而你的模板只在购物车就绪后运行。你不必构建加载状态。
模板内部可用的内容
- 你有五个 hooks 可用:
useState、useEffect、useMemo、useRef和useCallback。外加Fragment,用于<>…</>。 - **没有导入。**你不能
import任何东西,作用域内也没有React对象,所以没有React.useReducer,也没有React.Children。如果某个 hook 不在上面的列表中,它就不可用。 - **props 是只读的。**修改 prop 不会有任何用处。要更改购物车,请使用区块提供的处理函数 props(
onClose、increment、selectPlan等),而不要直接写入 props。 - 可以访问
window,所以当区块的 props 无法满足需求时,模板可以通过window.aftersell.cart调用 Cart SDK。
所有区块通用的约定
- **
*Htmlprops 是已消毒的富文本。**用dangerouslySetInnerHTML渲染它们。它们已经过购物车的消毒器处理,{{total_price}}之类的商家令牌也已被解析。 - **以
string形式到达的价格已经按商店的货币格式格式化好了。**以number形式的价格以分为单位。每个区块只会给你其中一种,各区块的表格会说明是哪一种。 - **在模板内部
isLoading始终为false。**区块会渲染其内置骨架屏,并且只在购物车加载完成后才调用你的模板,所以传入这个 prop 是为了完整性,而不是让你基于它做分支。
少数区块在某些状态下完全不渲染任何内容,所以你的模板永远不会收到空数据。Rewards 模板永远不会看到空的
milestones,Subscription upgrade 模板永远不会看到为 null 的 view。每个区块的参考都会注明适用之处,这样你就可以跳过空状态分支。为自定义模板设置样式
两个类名家族
所以
cart-internal-header__title 是让标题看起来像内置标题的原因,而 cart-external-header__title 才是当你想改变其外观时应该抓取的把手。
小改动:保留两个类名
cart-external-* 挂钩的自定义 CSS 重新设置样式。
重构:去掉两个类名
cart-internal-* 是因为内置 CSS 是为内置 DOM 编写的。**在重构后的标记上保留这些类,你就会继承一些假设了你已不再拥有的元素的布局规则:期望不同子元素的 flex 容器、针对已移动元素的间距、相对于已删除元素的定位。这通常表现为你自己的 CSS “不起作用”,实际上是内置规则赢了。
为你构建的内容设置样式有两种方式:
方式 1:你自己的类名加自定义 CSS
.header 或 .title 这样的类就有可能与购物车自身的类、其他应用的模板或未来的区块发生冲突。
方式 2:内联样式
:hover 或其他伪类,没有媒体查询,也无法跨区块复用。一旦你需要其中任何一项,就改用方式 1。
选择一种方式
购物车渲染在 shadow root 中,所以你主题的样式表无法触及其内部。自定义模板的样式必须来自购物车自己的 Custom CSS 面板或内联样式,而不是来自你的主题。参阅自定义 CSS。
模板失败时
由于区块会静默消失而不是明显报错,发布前请务必在预览中检查模板。如果某个区块不见了,先打开浏览器控制台。
有两点值得防范,因为假设相反情况的模板都会崩溃:
- **可为 null 的 props。**许多 props 在正常情况下就是
null(没有 logo 时的logoUrl、没有图片时的imageUrl、单变体产品上的variantTitle)。使用前请先检查。 - 可能为空的数组。
discountTags和discountCodes大多数时候都是[]。
限制
- **自定义模板是显示层面的覆盖。**要对购物车运行逻辑(订阅事件、添加商品、响应变化),请使用自定义脚本和 Cart SDK。
- **几乎所有区块都支持自定义模板。**例外是承载 Shopify 自有支付按钮的 Express payments 区块,以及 Cart items 容器本身,不过其中的 Product 行支持自定义模板。
- **模板不能改变区块的根本功能。**它改变的是区块数据的呈现方式,而不是数据或其背后的行为。
每个区块的 props
自定义代码区块是唯一添加标记而非替换区块渲染的界面,所以它的 props 有所不同:整个购物车,外加一个加入购物车操作。参阅自定义代码区块 → Props。