469 行
17 KiB
HTML
469 行
17 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>分类自动加载商品功能测试</title>
|
||
<style>
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
margin: 0;
|
||
padding: 20px;
|
||
background-color: #f5f5f5;
|
||
}
|
||
.test-container {
|
||
max-width: 800px;
|
||
margin: 0 auto;
|
||
background: white;
|
||
border-radius: 8px;
|
||
padding: 20px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
.demo-section {
|
||
margin-bottom: 30px;
|
||
padding: 15px;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 5px;
|
||
}
|
||
.section-title {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
/* 顶级分类样式 */
|
||
.top-category-scroll {
|
||
width: 100%;
|
||
overflow-x: auto;
|
||
margin: 10px 0;
|
||
}
|
||
.top-category-container {
|
||
display: flex;
|
||
padding: 0 10px;
|
||
min-width: max-content;
|
||
}
|
||
.top-category-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin: 0 15px;
|
||
min-width: 60px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
.top-category-item.active .category-icon {
|
||
background-color: #ff6b35;
|
||
border-color: #ff6b35;
|
||
}
|
||
.top-category-item.active .category-name {
|
||
color: #ff6b35;
|
||
font-weight: bold;
|
||
}
|
||
.category-icon {
|
||
width: 50px;
|
||
height: 50px;
|
||
border-radius: 50%;
|
||
background-color: #f5f5f5;
|
||
border: 2px solid #e0e0e0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 5px;
|
||
transition: all 0.3s ease;
|
||
font-size: 20px;
|
||
}
|
||
.category-name {
|
||
font-size: 12px;
|
||
color: #666;
|
||
text-align: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
/* 布局样式 */
|
||
.content-layout {
|
||
display: flex;
|
||
gap: 20px;
|
||
margin-top: 20px;
|
||
}
|
||
.left-sidebar {
|
||
width: 200px;
|
||
background: #f9f9f9;
|
||
border-radius: 5px;
|
||
padding: 10px;
|
||
}
|
||
.right-content {
|
||
flex: 1;
|
||
background: #fff;
|
||
border: 1px solid #eee;
|
||
border-radius: 5px;
|
||
padding: 15px;
|
||
}
|
||
|
||
/* 子分类样式 */
|
||
.sub-category-item {
|
||
padding: 10px;
|
||
border-bottom: 1px solid #eee;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
.sub-category-item:hover {
|
||
background-color: #f0f0f0;
|
||
}
|
||
.sub-category-item.active {
|
||
background-color: #ff6b35;
|
||
color: white;
|
||
}
|
||
|
||
/* 商品列表样式 */
|
||
.goods-list {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||
gap: 15px;
|
||
}
|
||
.goods-item {
|
||
border: 1px solid #eee;
|
||
border-radius: 5px;
|
||
padding: 10px;
|
||
text-align: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
.goods-item:hover {
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||
}
|
||
.goods-image {
|
||
width: 80px;
|
||
height: 80px;
|
||
background: #f0f0f0;
|
||
border-radius: 5px;
|
||
margin: 0 auto 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
.goods-name {
|
||
font-size: 14px;
|
||
color: #333;
|
||
margin-bottom: 5px;
|
||
}
|
||
.goods-price {
|
||
font-size: 16px;
|
||
color: #ff6b35;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 状态指示器 */
|
||
.status-indicator {
|
||
padding: 10px;
|
||
border-radius: 4px;
|
||
margin: 10px 0;
|
||
font-weight: bold;
|
||
}
|
||
.loading {
|
||
background-color: #fff3cd;
|
||
color: #856404;
|
||
border: 1px solid #ffeaa7;
|
||
}
|
||
.success {
|
||
background-color: #d4edda;
|
||
color: #155724;
|
||
border: 1px solid #c3e6cb;
|
||
}
|
||
.info {
|
||
background-color: #d1ecf1;
|
||
color: #0c5460;
|
||
border: 1px solid #bee5eb;
|
||
}
|
||
|
||
/* 测试日志 */
|
||
.test-log {
|
||
background: #f8f9fa;
|
||
border: 1px solid #dee2e6;
|
||
border-radius: 4px;
|
||
padding: 10px;
|
||
font-family: monospace;
|
||
font-size: 12px;
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
}
|
||
.log-entry {
|
||
margin-bottom: 5px;
|
||
padding: 2px 0;
|
||
}
|
||
.log-time {
|
||
color: #6c757d;
|
||
}
|
||
.log-action {
|
||
color: #007bff;
|
||
font-weight: bold;
|
||
}
|
||
.log-result {
|
||
color: #28a745;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="test-container">
|
||
<h1>分类自动加载商品功能测试</h1>
|
||
|
||
<div class="demo-section">
|
||
<div class="section-title">功能演示</div>
|
||
|
||
<!-- 顶级分类 -->
|
||
<div class="top-category-scroll">
|
||
<div class="top-category-container">
|
||
<div class="top-category-item active" data-index="0">
|
||
<div class="category-icon">🍺</div>
|
||
<div class="category-name">啤酒</div>
|
||
</div>
|
||
<div class="top-category-item" data-index="1">
|
||
<div class="category-icon">🍶</div>
|
||
<div class="category-name">白酒</div>
|
||
</div>
|
||
<div class="top-category-item" data-index="2">
|
||
<div class="category-icon">🥃</div>
|
||
<div class="category-name">洋酒</div>
|
||
</div>
|
||
<div class="top-category-item" data-index="3">
|
||
<div class="category-icon">🍷</div>
|
||
<div class="category-name">葡萄酒</div>
|
||
</div>
|
||
<div class="top-category-item" data-index="4">
|
||
<div class="category-icon">🍻</div>
|
||
<div class="category-name">精酿啤酒</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 状态指示器 -->
|
||
<div id="statusIndicator" class="status-indicator info">
|
||
点击不同的顶级分类,观察商品自动加载效果
|
||
</div>
|
||
|
||
<!-- 内容布局 -->
|
||
<div class="content-layout">
|
||
<!-- 左侧子分类 -->
|
||
<div class="left-sidebar">
|
||
<h4>子分类</h4>
|
||
<div id="subCategoryList">
|
||
<div class="sub-category-item active">国产啤酒</div>
|
||
<div class="sub-category-item">进口啤酒</div>
|
||
<div class="sub-category-item">精酿啤酒</div>
|
||
<div class="sub-category-item">无酒精啤酒</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧商品列表 -->
|
||
<div class="right-content">
|
||
<h4>商品列表</h4>
|
||
<div id="goodsList" class="goods-list">
|
||
<!-- 商品将通过JavaScript动态生成 -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="demo-section">
|
||
<div class="section-title">测试日志</div>
|
||
<div id="testLog" class="test-log">
|
||
<div class="log-entry">
|
||
<span class="log-time">[00:00:00]</span>
|
||
<span class="log-action">初始化</span> -
|
||
<span class="log-result">页面加载完成,默认显示啤酒分类商品</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="demo-section">
|
||
<div class="section-title">功能验证要点</div>
|
||
<ul>
|
||
<li>✅ <strong>自动加载:</strong>切换顶级分类时,自动加载第一个子分类的商品</li>
|
||
<li>✅ <strong>分页重置:</strong>切换分类时,page重置为0,canLoad重置为true</li>
|
||
<li>✅ <strong>子分类重置:</strong>index_1重置为0,选中第一个子分类</li>
|
||
<li>✅ <strong>滚动重置:</strong>调用goTop()方法,滚动到顶部</li>
|
||
<li>✅ <strong>商品清空:</strong>切换分类时清空之前的商品列表</li>
|
||
<li>✅ <strong>加载状态:</strong>显示加载状态,防止重复请求</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="demo-section">
|
||
<div class="section-title">代码修改说明</div>
|
||
<pre style="background: #f8f9fa; padding: 15px; border-radius: 5px; font-size: 12px;">
|
||
// selectTopCategory方法修改
|
||
selectTopCategory: function (e) {
|
||
var index = parseInt(e.currentTarget.dataset.index);
|
||
if (this.selectedTopCategoryIndex !== index) {
|
||
this.selectedTopCategoryIndex = index;
|
||
this.loadSubCategories();
|
||
this.index_1 = 0; // 重置子分类选中索引
|
||
// 重置分页状态 - 新增
|
||
this.page = 0;
|
||
this.canLoad = true;
|
||
this.goTop();
|
||
// 自动加载第一个子分类的商品 - 注释说明
|
||
this.getGoods();
|
||
}
|
||
}
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 模拟数据
|
||
const categoryData = {
|
||
0: { // 啤酒
|
||
subCategories: ['国产啤酒', '进口啤酒', '精酿啤酒', '无酒精啤酒'],
|
||
goods: [
|
||
{ name: '青岛啤酒', price: '¥3.5' },
|
||
{ name: '雪花啤酒', price: '¥3.0' },
|
||
{ name: '燕京啤酒', price: '¥3.2' },
|
||
{ name: '哈尔滨啤酒', price: '¥3.8' }
|
||
]
|
||
},
|
||
1: { // 白酒
|
||
subCategories: ['茅台', '五粮液', '剑南春', '泸州老窖'],
|
||
goods: [
|
||
{ name: '茅台飞天', price: '¥2699' },
|
||
{ name: '五粮液普五', price: '¥1099' },
|
||
{ name: '剑南春水晶剑', price: '¥399' },
|
||
{ name: '泸州老窖特曲', price: '¥199' }
|
||
]
|
||
},
|
||
2: { // 洋酒
|
||
subCategories: ['威士忌', '伏特加', '白兰地', '朗姆酒'],
|
||
goods: [
|
||
{ name: '芝华士12年', price: '¥299' },
|
||
{ name: '绝对伏特加', price: '¥159' },
|
||
{ name: '轩尼诗XO', price: '¥1299' },
|
||
{ name: '百加得朗姆酒', price: '¥89' }
|
||
]
|
||
},
|
||
3: { // 葡萄酒
|
||
subCategories: ['红酒', '白葡萄酒', '香槟', '起泡酒'],
|
||
goods: [
|
||
{ name: '拉菲传奇', price: '¥199' },
|
||
{ name: '长城干红', price: '¥59' },
|
||
{ name: '张裕解百纳', price: '¥79' },
|
||
{ name: '王朝干红', price: '¥45' }
|
||
]
|
||
},
|
||
4: { // 精酿啤酒
|
||
subCategories: ['IPA', '世涛', '小麦啤酒', '拉格'],
|
||
goods: [
|
||
{ name: '熊猫精酿IPA', price: '¥25' },
|
||
{ name: '高大师小麦', price: '¥18' },
|
||
{ name: '牛啤堂世涛', price: '¥32' },
|
||
{ name: '拳击猫拉格', price: '¥22' }
|
||
]
|
||
}
|
||
};
|
||
|
||
let currentCategoryIndex = 0;
|
||
|
||
// 添加测试日志
|
||
function addLog(action, result) {
|
||
const now = new Date();
|
||
const timeStr = now.toTimeString().split(' ')[0];
|
||
const logEntry = document.createElement('div');
|
||
logEntry.className = 'log-entry';
|
||
logEntry.innerHTML = `
|
||
<span class="log-time">[${timeStr}]</span>
|
||
<span class="log-action">${action}</span> -
|
||
<span class="log-result">${result}</span>
|
||
`;
|
||
document.getElementById('testLog').appendChild(logEntry);
|
||
document.getElementById('testLog').scrollTop = document.getElementById('testLog').scrollHeight;
|
||
}
|
||
|
||
// 更新状态指示器
|
||
function updateStatus(message, type = 'info') {
|
||
const indicator = document.getElementById('statusIndicator');
|
||
indicator.className = `status-indicator ${type}`;
|
||
indicator.textContent = message;
|
||
}
|
||
|
||
// 模拟加载商品
|
||
function loadGoods(categoryIndex) {
|
||
updateStatus('正在加载商品...', 'loading');
|
||
|
||
setTimeout(() => {
|
||
const data = categoryData[categoryIndex];
|
||
const goodsList = document.getElementById('goodsList');
|
||
|
||
// 清空商品列表(模拟page=0的效果)
|
||
goodsList.innerHTML = '';
|
||
|
||
// 生成商品
|
||
data.goods.forEach(goods => {
|
||
const goodsItem = document.createElement('div');
|
||
goodsItem.className = 'goods-item';
|
||
goodsItem.innerHTML = `
|
||
<div class="goods-image">商品图片</div>
|
||
<div class="goods-name">${goods.name}</div>
|
||
<div class="goods-price">${goods.price}</div>
|
||
`;
|
||
goodsList.appendChild(goodsItem);
|
||
});
|
||
|
||
updateStatus(`已加载 ${data.goods.length} 个商品`, 'success');
|
||
addLog('商品加载', `成功加载${data.goods.length}个商品`);
|
||
}, 500);
|
||
}
|
||
|
||
// 更新子分类
|
||
function updateSubCategories(categoryIndex) {
|
||
const data = categoryData[categoryIndex];
|
||
const subList = document.getElementById('subCategoryList');
|
||
|
||
subList.innerHTML = '';
|
||
data.subCategories.forEach((sub, index) => {
|
||
const subItem = document.createElement('div');
|
||
subItem.className = 'sub-category-item' + (index === 0 ? ' active' : '');
|
||
subItem.textContent = sub;
|
||
subList.appendChild(subItem);
|
||
});
|
||
|
||
addLog('子分类更新', `显示${data.subCategories.length}个子分类,默认选中第一个`);
|
||
}
|
||
|
||
// 顶级分类点击事件
|
||
document.querySelectorAll('.top-category-item').forEach((item, index) => {
|
||
item.addEventListener('click', function() {
|
||
if (currentCategoryIndex !== index) {
|
||
// 移除所有active类
|
||
document.querySelectorAll('.top-category-item').forEach(i => i.classList.remove('active'));
|
||
// 添加当前项的active类
|
||
this.classList.add('active');
|
||
|
||
const categoryName = this.querySelector('.category-name').textContent;
|
||
addLog('分类切换', `从索引${currentCategoryIndex}切换到索引${index}(${categoryName})`);
|
||
|
||
currentCategoryIndex = index;
|
||
|
||
// 模拟Vue方法调用顺序
|
||
addLog('执行步骤', 'selectedTopCategoryIndex = ' + index);
|
||
addLog('执行步骤', 'loadSubCategories() - 加载子分类');
|
||
updateSubCategories(index);
|
||
|
||
addLog('执行步骤', 'index_1 = 0 - 重置子分类选中索引');
|
||
addLog('执行步骤', 'page = 0, canLoad = true - 重置分页状态');
|
||
addLog('执行步骤', 'goTop() - 滚动到顶部');
|
||
addLog('执行步骤', 'getGoods() - 自动加载商品');
|
||
|
||
// 自动加载商品
|
||
loadGoods(index);
|
||
}
|
||
});
|
||
});
|
||
|
||
// 初始化
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
addLog('初始化', '页面加载完成');
|
||
loadGoods(0);
|
||
addLog('功能验证', '✅ 切换顶级分类时自动加载第一个子分类的商品功能已实现');
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |