class SpzCustomAiSearch extends SPZ.BaseElement {
constructor(element) {
super(element);
this.apiEndpoint = 'https://saas-ai-api.essa.top/app-api/app/shoplazza/search/';
this.state = {
query: '',
currentPage: 1,
pageSize: 20
};
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.CONTAINER;
}
buildCallback() {
// 初始化翻译
this.shopLocale = "{{ shop.locale }}" || "zh-CN";
this.translations = {
placeholder: "{{ 'search.placeholder' | t }}",
loading: "{{ 'search.loading' | t }}",
noResults: "{{ 'search.no_results' | t }}",
// ... 更多翻译
};
}
mountCallback() {
// 绑定搜索表单事件
const form = this.element.querySelector('#search-form');
if (form) {
form.addEventListener('submit', (e) => this.handleSearch(e));
}
}
async handleSearch(event) {
event.preventDefault();
const searchInput = this.element.querySelector('#search-input');
const query = searchInput.value.trim();
if (!query) {
alert(this.translations.enterKeyword);
return;
}
this.state.query = query;
this.state.currentPage = 1;
await this.performSearch();
}
async performSearch() {
const resultsContainer = this.element.querySelector('#search-results-container');
resultsContainer.innerHTML = `${this.translations.loading}
`;
try {
const response = await fetch(this.apiEndpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: this.state.query,
size: this.state.pageSize,
from: (this.state.currentPage - 1) * this.state.pageSize
})
});
const data = await response.json();
this.renderResults(data);
} catch (error) {
resultsContainer.innerHTML = `${this.translations.error}
`;
}
}
renderResults(data) {
const resultsContainer = this.element.querySelector('#search-results-container');
// 渲染搜索结果...
}
unmountCallback() {
// 清理工作
}
}
SPZ.defineElement('spz-custom-ai-search', SpzCustomAiSearch);
```
### 4. 使用 Lessjs 的优势
1. **性能优化**:Lessjs 基于 Web Components,提供更好的性能
2. **主题集成**:与 Shoplazza 主题深度集成,样式更统一
3. **组件复用**:可以使用 Lessjs 提供的现成组件(轮播图、视频等)
4. **标准化**:遵循 Shoplazza 的开发规范,减少兼容性问题
---
## 与店匠主题的适配
### 1. 样式适配
#### 1.1 使用主题变量
尽可能使用 Shoplazza 主题提供的 CSS 变量:
```css
/* 使用主题颜色变量 */
.ai-search-container {
color: var(--color-text, #333);
background: var(--color-background, #fff);
border-color: var(--color-border, #e0e0e0);
}
/* 使用主题字体变量 */
.ai-search-container {
font-family: var(--font-body-family, sans-serif);
font-size: var(--font-body-size, 14px);
}
```
#### 1.2 响应式设计
遵循 Shoplazza 的响应式断点:
```css
/* 移动端 */
@media (max-width: 749px) {
.ai-search-container {
padding: 10px;
}
}
/* 平板 */
@media (min-width: 750px) and (max-width: 989px) {
.ai-search-container {
padding: 20px;
}
}
/* 桌面端 */
@media (min-width: 990px) {
.ai-search-container {
padding: 30px;
}
}
```
### 2. 功能适配
#### 2.1 使用 Shoplazza 全局对象
在 JavaScript 中,可以使用 Shoplazza 提供的全局对象:
```javascript
// 访问店铺信息
const shopDomain = window.Shopify?.shop || "{{ shop.domain }}";
const shopLocale = window.Shopify?.locale || "{{ shop.locale }}";
// 使用 Shoplazza 的工具函数(如果可用)
if (window.Shoplazza?.utils) {
// 使用工具函数
}
```
#### 2.2 事件处理
遵循 Shoplazza 的事件处理规范:
```javascript
// 使用事件委托,提高性能
document.addEventListener('click', (e) => {
if (e.target.closest('.search-button')) {
handleSearch(e);
}
});
// 避免直接操作 DOM,使用 Lessjs 组件生命周期
```
### 3. 性能优化建议
1. **延迟加载**:非关键资源使用 `defer` 或 `async`
2. **图片优化**:使用 Shoplazza 的图片 CDN 和响应式图片
3. **代码分割**:将大型 JavaScript 拆分为多个模块
4. **缓存策略**:合理使用浏览器缓存和 CDN 缓存
### 4. 测试清单
- [ ] 在不同语言环境下测试多语言显示
- [ ] 在不同设备上测试响应式布局
- [ ] 测试与不同 Shoplazza 主题的兼容性
- [ ] 测试 Lessjs 组件的加载和渲染
- [ ] 测试 API 调用的错误处理
- [ ] 测试页面加载性能
---
## 总结
1. **多语言支持**:使用 Liquid 的 `t` 过滤器和 `shop.locale`,确保所有语言文件完整
2. **Lessjs 集成**:使用 Lessjs 自定义组件提升性能和主题适配
3. **主题适配**:使用主题变量和响应式设计,确保与店匠主题良好集成
遵循以上指南,可以开发出高质量、高性能、多语言支持的 Shoplazza 应用。
---
## 参考资源
- [Lessjs 官方文档](https://lessjs.shoplazza.com/latest/docs/introduction/)
- [Lessjs 自定义组件文档](https://lessjs.shoplazza.com/latest/docs/custom-component/)
- [Shoplazza 开发者文档](https://www.shoplazza.dev/)