Commit 551bbb4c by wusiyi

feat: 官网2.0样式优化

parent a7e95afc
......@@ -34,7 +34,6 @@
"vue-router": "^3.5.3",
"vue-seamless-scroll": "^1.1.23",
"vue-selecto": "~1.10.1",
"vue-slick-carousel": "^1.0.6",
"vuedraggable": "~2.23.2",
"vuex": "^3.4.0",
"vxe-table": "~3.3.12",
......@@ -18756,21 +18755,6 @@
"vue": "*"
}
},
"node_modules/vue-slick-carousel": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/vue-slick-carousel/-/vue-slick-carousel-1.0.6.tgz",
"integrity": "sha512-1CN/hpWC8m1U/eO7Kuc71jntJqdg6Z/ieLji21OPfQUhs8ZYnnGhQSu1covpa3IyuovM9T5puPCVgexs3DDF5A==",
"dependencies": {
"enquire.js": "2.1.6",
"json2mq": "0.2.0",
"lodash.assign": "^4.2.0",
"lodash.debounce": "^4.0.8",
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"resize-observer-polyfill": "1.5.1",
"vue": "^2.6.10"
}
},
"node_modules/vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
......
......@@ -34,7 +34,6 @@
"vue-router": "^3.5.3",
"vue-seamless-scroll": "^1.1.23",
"vue-selecto": "~1.10.1",
"vue-slick-carousel": "^1.0.6",
"vuedraggable": "~2.23.2",
"vuex": "^3.4.0",
"vxe-table": "~3.3.12",
......
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 24 24">
<g fill="none">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<path fill="#d28f0f" d="M20 17.5a1.5 1.5 0 0 1 .144 2.993L20 20.5H4a1.5 1.5 0 0 1-.144-2.993L4 17.5zm0-7a1.5 1.5 0 0 1 0 3H4a1.5 1.5 0 0 1 0-3zm0-7a1.5 1.5 0 0 1 0 3H4a1.5 1.5 0 1 1 0-3z" />
</g>
</svg>
\ No newline at end of file
<template>
<div class="header-nav-mobile">
<div class="header-nav-mobile_trigger">
<a class="nav-icon icon-menu" href="javascript:;" @click="toggleShow"></a>
<Icon
@click.native="toggleShow"
icon="typcn:th-menu"
color="var(--primary-color)"
width="20"
height="20" />
<!-- <a class="nav-icon icon-menu" href="javascript:;" @click="toggleShow"></a> -->
</div>
<div @click="goHome" class="header-nav-mobile_logo">
<img src="../assets/logo.png" style="height: 40px" />
......@@ -101,6 +107,7 @@
</template>
<script>
import { mapMutations } from 'vuex'
import { Icon } from '@iconify/vue2'
import productionSvg from '../assets/images/home/production.svg'
import customSvg from '../assets/images/home/custom.svg'
import supplyChainSvg from '../assets/images/home/earth.svg'
......@@ -112,6 +119,9 @@ export default {
inject: {
scrollParent: 'scrollParent',
},
components: {
Icon,
},
data() {
return {
showing: false,
......@@ -291,19 +301,6 @@ export default {
flex: 1;
}
.nav-icon {
width: 25px;
height: 25px;
display: block;
}
.icon-menu {
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
background-image: url(../assets/mobile.svg);
}
.header-nav-mobile-enter-active,
.header-nav-mobile-leave-active {
transition: 0.3s;
......
......@@ -62,6 +62,8 @@ import {
BreadcrumbItem,
Breadcrumb,
Popconfirm,
Timeline,
TimelineItem,
} from 'element-ui'
Vue.prototype.$ELEMENT = { size: 'mini' }
......@@ -103,6 +105,8 @@ Vue.use(Tabs)
Vue.use(Breadcrumb)
Vue.use(BreadcrumbItem)
Vue.use(Popconfirm)
Vue.use(Timeline)
Vue.use(TimelineItem)
Vue.prototype.$alert = MessageBox.alert
Vue.prototype.$message = (message) =>
typeof message === 'string'
......
......@@ -87,7 +87,7 @@
</div>
</div>
</div>
<div class="bg-colorBg w-full flex flex-col m-auto mt-20 py-20">
<div class="bg-colorBg w-full flex flex-col m-auto mt-20 py-10">
<h2 class="text-center">发展历程</h2>
<timeline />
</div>
......
......@@ -16,53 +16,41 @@
</div>
</div>
</div>
<VueSlickCarousel
v-bind="settings"
ref="slick"
@beforeChange="beforeChange">
<div v-for="(item, index) in timelineItems" :key="index">
<div class="timeline-cards-container" ref="cardsContainer">
<div
class="timeline-cards-wrapper"
:style="{ transform: `translateX(${translateX}px)` }">
<div
class="timeline-card p-10 h-80 w-104 shadow-xl rounded-lg cursor-pointer"
:class="{ 'timeline-card-current': currentIndex === index }">
<div class="w-full text-gray-600 font-semibold text-2xl">
{{ item.title }}
</div>
<div class="bg-gray-200 mt-3 h-px" />
v-for="(item, index) in timelineItems"
:key="index"
class="timeline-card-item"
ref="cardItems">
<div
v-for="(content, index) in item.content"
:key="index"
class="card-content text-gray-600 relative pt-5 pl-5">
{{ content }}
class="timeline-card p-10 h-80 w-104 shadow-xl rounded-lg cursor-pointer"
:class="{ 'timeline-card-current': currentIndex === index }"
@click="selectTime(index)">
<div class="w-full text-gray-600 font-semibold text-2xl">
{{ item.title }}
</div>
<div class="bg-gray-200 mt-3 h-px" />
<el-timeline class="mt-5">
<el-timeline-item
v-for="(content, index) in item.content"
:key="index"
color="var(--el-color-primary-light-3)">
{{ content }}
</el-timeline-item>
</el-timeline>
</div>
</div>
</div>
</VueSlickCarousel>
</div>
</div>
</template>
<script>
// vue-slick 组件中文文档: https://www.cnblogs.com/isylar/p/11103570.html
// vue-slick 组件官方文档: https://gs-shop.github.io/vue-slick-carousel/#/
import VueSlickCarousel from 'vue-slick-carousel'
import 'vue-slick-carousel/dist/vue-slick-carousel.css'
// optional style for arrows & dots
import 'vue-slick-carousel/dist/vue-slick-carousel-theme.css'
export default {
components: {
VueSlickCarousel,
},
data() {
return {
// VueSlickCarousel 设置
settings: {
arrows: false,
dots: false,
centerMode: true,
focusOnSelect: true,
infinite: true, // 这里使用false会导致后半内容无法居中
slidesToShow: 3,
autoplay: false,
},
timelineItems: [
{
title: '2022年',
......@@ -82,31 +70,78 @@ export default {
},
],
currentIndex: 0,
translateX: 0,
cardGap: 80, // gap-20 = 5rem = 80px
}
},
methods: {
selectTime(index) {
this.currentIndex = index
this.$refs.slick.goTo(index)
this.centerCard(index)
},
beforeChange(oldindex, index) {
this.currentIndex = index
this.centerCard(index)
},
centerCard(index) {
this.$nextTick(() => {
if (!this.$refs.cardsContainer || !this.$refs.cardItems) {
return
}
const container = this.$refs.cardsContainer
const containerWidth = container.offsetWidth
const cardItems = this.$refs.cardItems
if (!cardItems || cardItems.length === 0) {
return
}
// 获取第一个卡片的宽度(所有卡片宽度相同)
const cardWidth = cardItems[0].offsetWidth
const cardGap = this.cardGap
// 计算目标卡片的位置
// 每个卡片的位置 = index * (cardWidth + cardGap)
const targetCardLeft = index * (cardWidth + cardGap)
// 计算需要移动的距离,使目标卡片居中
// 容器中心位置 = containerWidth / 2
// 目标卡片中心位置 = targetCardLeft + cardWidth / 2
// translateX = 容器中心 - 目标卡片中心
const containerCenter = containerWidth / 2
const targetCardCenter = targetCardLeft + cardWidth / 2
this.translateX = containerCenter - targetCardCenter
})
},
},
created() {
this.currentIndex = this.timelineItems.length - 1
},
mounted() {
// 初始化时居中显示当前卡片
this.centerCard(this.currentIndex)
// 监听窗口大小变化,重新计算位置
this.handleResize = () => {
this.centerCard(this.currentIndex)
}
window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
// 清理事件监听器
if (this.handleResize) {
window.removeEventListener('resize', this.handleResize)
}
},
watch: {
currentIndex(newIndex) {
this.centerCard(newIndex)
},
},
}
</script>
<style scoped lang="scss">
::v-deep .slick-list {
overflow: visible !important;
}
::v-deep .slick-slide {
outline: none; /* 防止点击时出现默认 outline 导致“深色”闪烁感 */
}
.timeline-dot {
width: 20px;
height: 20px;
......@@ -128,6 +163,31 @@ export default {
background-color: var(--light-color);
}
.timeline-cards-container {
width: 100%;
overflow-x: hidden;
overflow-y: visible;
position: relative;
padding: 10px 0 50px 0;
}
.timeline-cards-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform;
}
.timeline-card-item {
flex-shrink: 0;
margin-right: 80px; // gap-20 = 5rem = 80px
&:last-child {
margin-right: 0;
}
}
.timeline-card {
border: 1px solid transparent;
background-image: linear-gradient(
......@@ -149,17 +209,7 @@ export default {
border-color: rgba(153, 151, 148, 0.548);
}
.card-content {
&::before {
background-color: var(--primary-color);
border-radius: 50%;
position: absolute;
left: 5px;
top: 30px;
content: '';
width: 6px;
height: 6px;
box-shadow: 0 0 0 5px var(--shadow-color);
}
::v-deep .el-timeline-item__tail {
border-left: 1px solid var(--el-color-primary-light-5) !important;
}
</style>
......@@ -41,7 +41,7 @@
</div>
</div>
<div class="h-full py-10" ref="tabsSection">
<div class="pb-10 w-1/2 m-auto flex justify-center items-center gap-20">
<div class="pt-10 w-full m-auto flex justify-center items-center gap-20">
<div
class="product-tabs-item w-52 font-semibold text-gray-500 flex flex-col items-center gap-2 cursor-pointer"
:class="{ active: activeTab === item.key }"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment