Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Hooke
/
hager
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
hookehuyr
2024-11-06 15:54:51 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
ed15f8f0334b2ab735e20c15b08f33b695fab33f
ed15f8f0
1 parent
ff9d9a14
✨ feat(产品相关页面): 新增所有产品显示进行调整
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
236 additions
and
25 deletions
components.d.ts
src/components/accordion/Accordion.vue
src/components/accordion/AccordionItem.vue
src/views/index.vue
src/views/product/detail.vue
src/views/product/index.vue
components.d.ts
View file @
ed15f8f
...
...
@@ -7,6 +7,8 @@ export {}
/* prettier-ignore */
declare
module
'vue'
{
export
interface
GlobalComponents
{
Accordion
:
typeof
import
(
'./src/components/accordion/Accordion.vue'
)[
'default'
]
AccordionItem
:
typeof
import
(
'./src/components/accordion/AccordionItem.vue'
)[
'default'
]
ElBreadcrumb
:
typeof
import
(
'element-ui/lib/breadcrumb'
)[
'default'
]
ElBreadcrumbItem
:
typeof
import
(
'element-ui/lib/breadcrumb-item'
)[
'default'
]
ElCarousel
:
typeof
import
(
'element-ui/lib/carousel'
)[
'default'
]
...
...
src/components/accordion/Accordion.vue
0 → 100644
View file @
ed15f8f
<!--
* @Date: 2024-11-06 14:01:32
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-11-06 14:49:49
* @FilePath: /hager/src/components/accordion/Accordion.vue
* @Description: 文件描述
-->
<template>
<div class="accordion">
<AccordionItem v-for="item in items" :key="item.id" :item="item" style="border-bottom: 1px solid #EBEEF5;" />
</div>
</template>
<script>
import AccordionItem from './AccordionItem.vue';
export default {
name: 'Accordion',
components: {
AccordionItem
},
props: {
items: {
type: Array,
required: true
}
}
};
</script>
<style scoped>
.accordion {
width: 100%;
max-width: 600px;
margin: 0 auto;
}
</style>
src/components/accordion/AccordionItem.vue
0 → 100644
View file @
ed15f8f
<template>
<div class="accordion-item">
<div v-if="hasChildren" class="accordion-header" @click="toggle" :style="item.style">
{{ item.category_name }}
<i v-if="!isOpen" class="el-icon-arrow-right"></i><i v-else class="el-icon-arrow-down"></i>
</div>
<div v-else class="list-item" @click="goToDetail(item)">
{{ item.category_name }}
</div>
<el-collapse-transition>
<div v-if="isOpen || !hasChildren" class="accordion-content">
<p v-if="!hasChildren">{{ item.content }}</p>
<AccordionItem v-for="child in item.children" :key="child.id" :item="child" />
</div>
</el-collapse-transition>
</div>
</template>
<script>
export default {
name: 'AccordionItem',
props: {
item: {
type: Object,
required: true
}
},
data() {
return {
isOpen: false
};
},
computed: {
hasChildren() {
return this.item.children && this.item.children.length > 0;
}
},
methods: {
toggle() {
if (this.hasChildren) {
this.isOpen = !this.isOpen;
}
},
goToDetail (v) { // 跳转产品详情
this.$router.push({
path: '/product/detail',
query: {
id: v.id,
}
});
}
}
};
</script>
<style scoped>
.accordion-item {
/* border-bottom: 1px solid #ccc; */
}
.accordion-header {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
justify-content: space-between;
height: 3rem;
line-height: 1;
background-color: #FFF;
color: #303133;
cursor: pointer;
/* border-bottom: 1px solid #EBEEF5; */
font-size: 0.9rem;
font-weight: 500;
-webkit-transition: border-bottom-color .3s;
transition: border-bottom-color .3s;
outline: 0;
}
.list-item {
font-size: 0.85rem;
line-height: 2;
/* padding: 10px; */
/* background-color: #f0f0f0; */
font-weight: normal;
cursor: default;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
.accordion-content {
padding-left: 0.5rem;
background-color: #fff;
}
</style>
src/views/index.vue
View file @
ed15f8f
<!--
* @Date: 2024-08-27 10:06:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-11-0
4 17:41:28
* @LastEditTime: 2024-11-0
6 15:04:05
* @FilePath: /hager/src/views/index.vue
* @Description: 首页
-->
...
...
@@ -165,7 +165,7 @@
</el-row>
</div>
<div class="more-box" style="margin-top: 3rem;">
<hager-more></hager-more>
<hager-more
@click.native="goToNews"
></hager-more>
</div>
</div>
<hager-box class="box-n">
...
...
src/views/product/detail.vue
View file @
ed15f8f
<!--
* @Date: 2024-09-29 14:26:41
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-11-0
5 10:34:50
* @LastEditTime: 2024-11-0
6 15:34:53
* @FilePath: /hager/src/views/product/detail.vue
* @Description: 文件描述
-->
...
...
@@ -10,7 +10,7 @@
<hager-box>
<div style="margin-top: 1.5rem;">
<el-breadcrumb separator="/">
<el-breadcrumb-item v-if="!is_xs">所有产品</el-breadcrumb-item>
<el-breadcrumb-item v-if="!is_xs"
:to="{ path: '/product/index' }"
>所有产品</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: productPath }">{{ info.parent_name }}</el-breadcrumb-item>
<!-- <el-breadcrumb-item>{{ info.parent_name }}</el-breadcrumb-item> -->
<el-breadcrumb-item :to="{ path: categoryPath }">{{ info.category_name }}</el-breadcrumb-item>
...
...
@@ -184,6 +184,12 @@ export default {
async mounted () {
this.getInfo();
this.getUserInfo();
// 监听 popstate 事件
window.addEventListener('popstate', this.handlePopState);
},
beforeDestroy() {
// 移除事件监听器
window.removeEventListener('popstate', this.handlePopState);
},
watch: {
// 监听路由参数变化时,更新输入框的值
...
...
@@ -194,6 +200,17 @@ export default {
}
},
methods: {
goToMenu (evt) {
// 阻止默认行为
evt.preventDefault();
},
handlePopState(event) {
// 自定义跳转逻辑
console.log('popstate triggered', event);
// 例如:跳转到指定路径
// this.$router.push('/custom-page');
},
async getInfo () {
this.download_list = [{
id: 1,
...
...
src/views/product/index.vue
View file @
ed15f8f
<!--
* @Date: 2024-09-27 16:53:09
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-11-0
4 17:34
:49
* @LastEditTime: 2024-11-0
6 15:52
:49
* @FilePath: /hager/src/views/product/index.vue
* @Description: 文件描述
-->
...
...
@@ -9,11 +9,14 @@
<div class="product-index">
<hager-box>
<div v-if="!is_search" style="margin-top: 1.5rem;">
<el-breadcrumb separator="/">
<el-breadcrumb-item>所有产品</el-breadcrumb-item>
<el-breadcrumb
v-if="!is_all_cate"
separator="/">
<el-breadcrumb-item
:to="{ path: allPath }"
>所有产品</el-breadcrumb-item>
<el-breadcrumb-item v-if="parent_name" :to="{ path: productPath }">{{ parent_name }}</el-breadcrumb-item>
<el-breadcrumb-item>{{ category_name }}</el-breadcrumb-item>
</el-breadcrumb>
<el-breadcrumb v-else separator="/">
<el-breadcrumb-item>所有产品</el-breadcrumb-item>
</el-breadcrumb>
</div>
<hager-h1 v-if="!is_search" :title="category_name" :sub="category_name_en" style="margin: 2rem 0;"></hager-h1>
<hager-h1 v-else :title="'与“' + keyword + '”相关的搜索结果'" :sub="''" style="margin: 2rem 0;"></hager-h1>
...
...
@@ -22,11 +25,12 @@
<div class="product-nav-wrapper">
<div class="product-nav-title">按产品类别查找</div>
<el-input style="margin-bottom: 0.5rem;" placeholder="请输入产品" prefix-icon="el-icon-search" v-model="search_keyword" @change="goToSearch"></el-input>
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse v-
if="!is_all_cate" v-
model="activeNames" @change="handleChange">
<el-collapse-item v-for="(item, index) in cate_list" :key="index" :title="item.category_name" :name="item.category_name">
<div @click="goToDetail(c)" v-for="(c, idx) in item.list" :key="idx" class="p-item">{{ c.product_name }}</div>
</el-collapse-item>
</el-collapse>
<Accordion v-else :items="all_cate_list" />
</div>
</el-col>
<el-col :span="18">
...
...
@@ -58,10 +62,11 @@
import mixin from 'common/mixin';
import hagerBox from '@/components/common/hagerBox';
import hagerH1 from '@/components/common/hagerH1.vue';
import Accordion from '@/components/accordion/Accordion.vue';
import { getProductCateAPI, getProductSearchAPI } from "@/api/hager.js";
export default {
components: { hagerBox, hagerH1 },
components: { hagerBox, hagerH1
, Accordion
},
mixins: [mixin.init],
data () {
return {
...
...
@@ -70,33 +75,54 @@ export default {
activeNames: [],
cate_id: '',
parent_name: '',
category_name: '',
category_name_en: '',
category_name: '
所有产品
',
category_name_en: '
All Products
',
cate_list: [],
product_list: [],
no_product_img: 'https://cdn.ipadbiz.cn/hager/img/no-product-img.png',
is_search: false,
all_cate_list: [],
}
},
async mounted () {
this.getMain();
if (!this.is_all_cate) {
this.getMain();
} else { // 没有ID显示所有产品
this.getAllMain();
}
},
computed: {
allPath () {
return `/product/index?timestamp=${Date.now()}`;
},
productPath () {
return `/product/index?id=${this.cate_id}×tamp=${Date.now()}`;
},
is_all_cate () {
return this.$route.query.id === undefined;
}
},
watch: {
// 监听路由参数变化时,更新输入框的值
'$route.query.id' (val, old) {
if (old !== val) {
this.is_search = false;
this.getMain();
if (val) {
if (old !== val) {
this.is_search = false;
this.getMain();
}
} else {
// 所有产品
this.getAllMain();
}
},
'$route.query.timestamp' (val, old) {
this.is_search = false;
this.getMain();
if (!this.is_all_cate) {
this.getMain();
} else {
// 所有产品
this.getAllMain();
}
},
},
methods: {
...
...
@@ -111,15 +137,29 @@ export default {
}
});
},
async getAllMain () { // 查询所有产品列表数据
this.getCurrentCate();
const { code, data } = await getProductCateAPI({ cid: 0 });
if (code) {
let info = data[0];
this.category_name = '所有产品';
this.category_name_en = 'All Products';
this.product_list = info.list;
this.search_keyword = '';
// 设置页面标题
document.title = '所有产品 | Hager China';
}
},
async getMain () {
const { code, data } = await getProductCateAPI(
{cid: this.$route.query.id });
const { code, data } = await getProductCateAPI({cid: this.$route.query.id });
if (code) {
let info = data[0];
this.parent_name = info.parent_name;
this.category_name = info.category_name;
this.category_name_en = info.category_name_en;
this.product_list = info.list;
console.warn(info.list);
this.search_keyword = '';
// 获取当前类别的内容
this.cate_id = info.category_parent ? info.category_parent : info.id; // 同一个值,在不同层级下名字不一样
...
...
@@ -131,24 +171,43 @@ export default {
async getCurrentCate (cate_id) {
const { code, data } = await getProductCateAPI();
if (code) {
data.forEach((item) => {
if (item.id === cate_id) {
this.cate_list = item.children;
}
})
if (cate_id) {
data.forEach((item) => {
if (item.id === cate_id) {
this.cate_list = item.children;
}
});
} else {
// 所有分类列表
this.all_cate_list = data;
// 重构数据结构配合组件
this.all_cate_list.forEach((item) => {
item.children.forEach((c) => {
c.children = c.list;
c.style = {fontWeight: 'normal', height: '2.5rem'}
c.children.forEach((d) => {
d.category_name = d.product_name
})
})
})
}
}
},
async goToSearch () {
if (this.search_keyword) { // 产品有值时操作
const { code, data } = await getProductSearchAPI({ keyword: this.search_keyword });
if (code) {
console.warn(data);
this.product_list = data;
this.is_search = true;
this.keyword = this.search_keyword;
}
} else { // 清空搜索值,还原
this.getMain();
if (!this.is_all_cate) {
this.getMain();
} else {
// 所有产品
this.getAllMain();
}
this.is_search = false;
this.keyword = '';
}
...
...
Please
register
or
login
to post a comment