index.vue 6.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <template>
  2. <div class="page-container">
  3. <div class="page-header">
  4. <PageTitle title="我的收藏" />
  5. <el-button type="danger" link @click="handleAddCategory"><el-icon><Plus /></el-icon>添加分类</el-button>
  6. </div>
  7. <!-- 分类Tab -->
  8. <StatusTabs v-model="activeCategory" :tabs="categoryTabs" type="pill" />
  9. <!-- 操作栏 -->
  10. <div class="action-bar">
  11. <el-checkbox v-model="selectAll" @change="handleSelectAll">全选</el-checkbox>
  12. <el-button type="danger" link @click="handleBatchAddCart">加入购物车</el-button>
  13. <el-button type="danger" link @click="handleBatchCancel">取消收藏</el-button>
  14. </div>
  15. <!-- 商品列表 -->
  16. <div class="product-grid">
  17. <ProductCard
  18. v-for="(item, index) in productList"
  19. :key="index"
  20. :product="item"
  21. v-model="item.checked"
  22. show-checkbox
  23. show-action
  24. show-add-cart
  25. action-text="取消收藏"
  26. @action="handleCancelCollection(item)"
  27. @add-cart="handleAddCart(item)"
  28. />
  29. </div>
  30. <el-empty v-if="productList.length === 0" description="暂无收藏商品" />
  31. <TablePagination v-if="productList.length > 0" v-model:page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :total="total" @change="handleQuery" />
  32. <!-- 添加分类弹窗 -->
  33. <el-dialog v-model="categoryDialogVisible" title="添加分类" width="400px">
  34. <el-form ref="categoryFormRef" :model="categoryForm" :rules="categoryRules">
  35. <el-form-item prop="name"><el-input v-model="categoryForm.name" placeholder="请输入分类名称" /></el-form-item>
  36. </el-form>
  37. <template #footer>
  38. <el-button @click="categoryDialogVisible = false">取消</el-button>
  39. <el-button type="danger" @click="handleSaveCategory">确定</el-button>
  40. </template>
  41. </el-dialog>
  42. </div>
  43. </template>
  44. <script setup lang="ts">
  45. import { ref, reactive, watch } from 'vue'
  46. import { Plus } from '@element-plus/icons-vue'
  47. import { ElMessage, ElMessageBox, type CheckboxValueType } from 'element-plus'
  48. import { PageTitle, StatusTabs, ProductCard, TablePagination } from '@/components'
  49. const activeCategory = ref('all')
  50. const selectAll = ref(false)
  51. const categoryDialogVisible = ref(false)
  52. const categoryFormRef = ref()
  53. const categoryTabs = ref([
  54. { key: 'all', label: '全部' }, { key: 'computer', label: '电脑办公(2)' }, { key: 'industrial', label: '工业品(2)' },
  55. { key: 'decoration', label: '家装建材(2)' }, { key: 'appliance', label: '家用电器(2)' }, { key: 'digital', label: '数码(2)' }
  56. ])
  57. const categoryForm = reactive({ name: '' })
  58. const categoryRules = { name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }] }
  59. const queryParams = reactive({ pageNum: 1, pageSize: 15 })
  60. const total = ref(100)
  61. const productList = ref([
  62. { id: 1, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '协议价', image: '', checked: false },
  63. { id: 2, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
  64. { id: 3, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
  65. { id: 4, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
  66. { id: 5, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
  67. { id: 6, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
  68. { id: 7, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
  69. { id: 8, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false }
  70. ])
  71. watch(activeCategory, () => { queryParams.pageNum = 1; handleQuery() })
  72. const handleQuery = () => {}
  73. const handleSelectAll = (val: CheckboxValueType) => { productList.value.forEach(item => { item.checked = !!val }) }
  74. const handleAddCategory = () => { categoryForm.name = ''; categoryDialogVisible.value = true }
  75. const handleSaveCategory = async () => { const valid = await categoryFormRef.value?.validate(); if (!valid) return; categoryTabs.value.push({ key: categoryForm.name, label: `${categoryForm.name}(0)` }); ElMessage.success('添加成功'); categoryDialogVisible.value = false }
  76. const handleAddCart = (_item: any) => { ElMessage.success('已加入购物车') }
  77. const handleBatchAddCart = () => { const selected = productList.value.filter(item => item.checked); if (selected.length === 0) { ElMessage.warning('请先选择商品'); return }; ElMessage.success(`已将${selected.length}件商品加入购物车`) }
  78. const handleCancelCollection = (item: any) => { ElMessageBox.confirm('确定要取消收藏该商品吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { const index = productList.value.findIndex(i => i.id === item.id); if (index > -1) productList.value.splice(index, 1); ElMessage.success('已取消收藏') }) }
  79. const handleBatchCancel = () => { const selected = productList.value.filter(item => item.checked); if (selected.length === 0) { ElMessage.warning('请先选择商品'); return }; ElMessageBox.confirm(`确定要取消收藏选中的${selected.length}件商品吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { productList.value = productList.value.filter(item => !item.checked); selectAll.value = false; ElMessage.success('已取消收藏') }) }
  80. </script>
  81. <style scoped lang="scss">
  82. .page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; :deep(.page-title) { margin-bottom: 0; } }
  83. .action-bar { display: flex; align-items: center; gap: 20px; padding: 10px 0; border-bottom: 1px solid #eee; margin-bottom: 15px; }
  84. .product-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; }
  85. </style>