According to the time axis, the year or (month data display) can be clicked to switch and dynamically switch data and other functions (with left and right buttons to switch to the first or last button function interaction with one button) with animation effects, etc.
1: demo source code
<!-- -->
<template>
<div>
<div class="ProgressBoxTool" v-if="progressList && progressList.length">
<div class="processBox" @mouseenter="onMouseOver" @mouseleave="onMouseOut">
<div class="left-one">
<div :class="currentClickNumber > 0 ? 'arrow' : 'arrow arrowOpacity'" @click="fnPrev()" v-if="falg">
<!-- <img :src="arrowL" alt="" /> -->
左边
</div>
</div>
<div class="fixedBox" :ref="`fixedBox`">
<div class="centerScroll" :style="
`width:${signleWidth *
progressList.length}px;transform:translate(${scrollResultWidth}px,0);transition:1s;`
">
<div class="signleTab" v-for="(itemP, indexP) in progressList" :key="indexP + 'progress'">
<div class="leftIcon">
<!-- <img class="pregressIcon" :src="icon" alt="" /> -->
<div :class="indexP == active ? 'active' : 'pregressIcon'" @click="btnClid(indexP)">
<div v-show="indexP == active" class="active-img"></div>
<div class="active-title">{
{ itemP.type }}</div>
</div>
</div>
<!-- 最后一个不展示箭头 -->
<!-- <img v-if="progressList.length > indexP + 1" :src="iconArrow" alt="" class="arrowSquare" /> -->
</div>
</div>
</div>
<div class="right-two">
<div :class="noScrollRight ? 'arrow' : 'arrow arrowOpacity'" @click="fnNext(activeName)" v-if="falg">
<!-- <img :src="arrowR" alt="" /> -->
右边
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import arrowL from '@/assets/images/G6Graph/icon2.png';
import arrowR from '@/assets/images/G6Graph/icon3.png';
import icon from '@/assets/images/G6Graph/icon1.png';
import iconArrow from '@/assets/images/G6Graph/icon4.png';
export default {
components: {},
data() {
return {
progressList: [
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2' },
{ type: '1' },
{ type: '2111' }
],
arrowL,
arrowR,
icon,
iconArrow,
currentProgressId: '',
scrollResultWidth: 0, //transform滚动的距离
signleWidth: 134, //单个流程的宽度
activeName: 0,
currentClickNumber: 0,
noScrollRight: true,
falg: false,
active: 0,
};
},
created() {
this.$nextTick(() => {
setTimeout(() => {
this.initgoRightArrow();
});
});
},
methods: {
//初始化判断是否可以向右滚动
initgoRightArrow() {
const currentScrollWidth = this.$refs[`fixedBox`].clientWidth;
const canNumber = Math.floor(currentScrollWidth / this.signleWidth); //可以放下的个数
//如果最后一个流程图标已经展示出来,则停止滚动
if (this.currentClickNumber + canNumber >= this.progressList.length) {
this.noScrollRight = false;
return;
}
},
//点击上一个
fnPrev() {
//如果右点击的次数大于0,才可以左滚
if (this.currentClickNumber > 0) {
this.currentClickNumber -= 1;
this.noScrollRight = true;
this.fnScrollWidth('reduce');
} else {
return false;
}
},
//点击下一个
fnNext() {
const currentScrollWidth = this.$refs[`fixedBox`].clientWidth;
const canNumber = Math.floor(currentScrollWidth / this.signleWidth); //可以放下的个数
//如果最后一个流程图标已经展示出来,则停止滚动
if (this.currentClickNumber + canNumber >= this.progressList.length) {
return;
}
//说明放不下有滚动条
if (this.progressList.length > canNumber) {
this.currentClickNumber += 1;
if (this.currentClickNumber + canNumber >= this.progressList.length) {
this.noScrollRight = false;
}
this.fnScrollWidth('add');
}
},
//translate的宽度
fnScrollWidth(type) {
let result = 0;
if (type === 'reduce') {
result = 134;
} else if (type === 'add') {
result = -134;
} else {
result = 0;
}
this.scrollResultWidth += result;
// console.log(this.scrollResultWidth);
//如果往前点击到第一个数据了 停止继续往前滚动
if (this.scrollResultWidth > 0) {
this.currentClickNumber = 0;
}
},
// 鼠标移入
onMouseOver() {
// console.log('鼠标进来了');
this.falg = true;
},
// 鼠标移出
onMouseOut() {
// console.log('鼠标出去了');
this.falg = false;
},
btnClid(index) {
console.log(index);
if (index > this.active) {
this.fnNext()
this.active = index;
} else {
this.fnPrev()
this.active = index;
}
}
}
};
</script>
<style lang="scss" scoped>
//中间的时间发展部分
.processBox {
width: 1200px;
height: 100px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: pink;
.left-one {
width: 64px;
height: 60px;
}
.right-two {
width: 64px;
height: 60px;
}
.arrow {
width: 60px;
height: 60px;
cursor: pointer;
background-color: red;
}
.active {
width: 134px;
height: 60px;
cursor: pointer;
// background-color: green;
}
.arrowOpacity {
cursor: default;
opacity: 0.4;
}
.fixedBox {
flex: 1;
overflow: hidden;
}
.centerScroll {
// flex: 1;
box-sizing: border-box;
padding: 10px 0;
background-color: #ccc;
background: url('../../assets/images/chronology/jianduan.png') repeat-x;
// white-space: nowrap;
width: calc(100% - 128px);
overflow-x: auto;
.signleTab {
// width: 158px;
position: relative;
display: inline-block;
.leftIcon {
width: 134px;
text-align: center;
cursor: pointer;
// background-color: yellow;
position: relative;
&>.pregressIcon {
width: 134px;
height: 60px;
}
.active-img{
width: 134px;
height: 40px;
background-color: green;
position: absolute;
left: 0px;
top: -11px;
background: url('../../assets/images/chronology/active.png') no-repeat center;
}
.active-title{
width: 134px;
position: absolute;
left: 0px;
top: 28px;
}
}
&>.arrowSquare {
position: absolute;
top: 25px;
right: 0;
}
}
}
}
</style>
2: The entire page source code
<template>
<div class="chromology-home">
<!-- baner -->
<headerImage />
<!-- 时间轴 -->
<div class="time-axis">
<div class="ProgressBoxTool" v-if="progressList && progressList.length && progressList.length <= 9">
<div class="processBox" @mouseenter="onMouseOver" @mouseleave="onMouseOut">
<!-- <div class="left-one">
<div :class="currentClickNumber > 0 ? 'arrow' : 'arrow arrowOpacity'" @click="fnPrev()"
v-if="falg">
左边
</div>
</div> -->
<div class="fixedBox" :ref="`fixedBox`">
<div class="centerScroll" :style="
`width:${signleWidth *
progressList.length}px;transform:translate(${scrollResultWidth}px,0);transition:1s;`
">
<div class="signleTab" v-for="(itemP, indexP) in progressList" :key="indexP + 'progress'">
<div class="leftIcon">
<!-- <img class="pregressIcon" :src="icon" alt="" /> -->
<div :class="indexP == active ? 'active' : 'pregressIcon'" @click="btnClid(indexP)">
<div v-show="indexP == active" class="active-img"></div>
<div class="active-title">{
{ itemP.type }}</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="right-two">
<div :class="noScrollRight ? 'arrow' : 'arrow arrowOpacity'" @click="fnNext(activeName)"
v-if="falg">
右边
</div>
</div> -->
</div>
</div>
<div class="ProgressBoxTool" v-if="progressList && progressList.length && progressList.length > 9">
<div class="processBox" @mouseenter="onMouseOver" @mouseleave="onMouseOut">
<div class="left-one">
<div :class="currentClickNumber > 0 ? 'arrow' : 'arrow arrowOpacity'" @click="fnPrev()" v-if="falg">
<img src="../../assets/images/chronology/left-dom.png" alt="">
</div>
</div>
<div class="fixedBox" :ref="`fixedBox`">
<div class="centerScroll" :style="
`width:${signleWidth *
progressList.length}px;transform:translate(${scrollResultWidth}px,0);transition:1s;`
">
<div class="signleTab" v-for="(itemP, indexP) in progressList" :key="indexP + 'progress'">
<div class="leftIcon">
<!-- <img class="pregressIcon" :src="icon" alt="" /> -->
<div :class="indexP == active ? 'active' : 'pregressIcon'" @click="btnClid(indexP)">
<div v-show="indexP == active" class="active-img"></div>
<div class="active-title">{
{ itemP.type }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="right-two">
<div :class="noScrollRight ? 'arrow' : 'arrow arrowOpacity'" @click="fnNext(activeName)" v-if="falg">
<img src="../../assets/images/chronology/right-dom.png" alt="">
</div>
</div>
</div>
</div>
<div class="axis-body">
<el-button type="primary" @click="btnLeft">回到顶部</el-button>
<el-button type="primary" @click="btnRight">回到底部</el-button>
</div>
</div>
<!-- 数据展示 -->
<div class="chromology-body">
<ul>
<li v-for="ite in progressList[active].children" :key="ite.id">
<div class="left-body">
<div class="body-img">
<img src="../../assets/images/chronology/nongye.png" alt="">
</div>
</div>
<div class="right-body">
<div class="lef-bod">
<div class="lef-img">
<img src="../../assets/images/chronology/11111.png" alt="">
</div>
<div class="lef-text">
{
{ ite.text }}
</div>
</div>
</div>
<div class="all-body">更多 ></div>
</li>
<!-- <li>
<div class="left-body">
<div class="body-img">
<img src="../../assets/images/chronology/nongye.png" alt="">
</div>
</div>
<div class="right-body">
<div class="rit-bod">
<div class="rit-img">
<img src="../../assets/images/chronology/11111.png" alt="">
</div>
<div class="rit-text">1949年9 月宁夏解放,省制与县名未有变更。</div>
</div>
<div class="lef-bod">
<div class="lef-img">
<img src="../../assets/images/chronology/11111.png" alt="">
</div>
<div class="lef-text">1954 年9 月,宁夏省撤销,将额济纳旗、阿拉善旗、 磴口县划入内蒙古自治区,其余各市县划属甘肃省, 设置银川专区、吴忠回族自治州、固原回族自治州。
</div>
</div>
</div>
<div class="all-body">更多 ></div>
</li> -->
</ul>
</div>
</div>
</template>
<script>
import headerImage from '../../components/headerImage';
export default {
components: {
headerImage
},
data() {
return {
progressList: [
{
id: 1,
type: '1991',
children: [
{
id: 1,
text: '极左思想占据主导,农业发展缓慢',
title: '三五计划',
time: 1991,
img: require('../../assets/images/home/111.png')
},
{
id: 2,
text: '中央的集一部署,各级党组织镇导下,对农业六卑世调整',
title: '“七五末”解决温饱',
time: 1991,
img: require('../../assets/images/home/222222.png')
},
{
id: 3,
text: '要实现全区全回生成道情五五”期两墨的南斗日标',
title: '十年规划,温饱到小康',
time: 1991,
img: require('../../assets/images/home/333333.png')
},
{
id: 4,
text: '2001-2005年开品之年,中央型署了西部大开发”路',
title: '西部大开发战略',
time: 1991,
img: require('../../assets/images/home/444444.png')
}
]
},
{
id: 2,
type: '1992',
children: [
{
id: 1,
text: '极左思想占据主导,农业发展缓慢',
title: '三五计划',
time: 1992,
img: require('../../assets/images/home/111.png')
},
{
id: 2,
text: '中央的集一部署,各级党组织镇导下,对农业六卑世调整',
title: '“七五末”解决温饱',
time: 1992,
img: require('../../assets/images/home/222222.png')
},
{
id: 3,
text: '要实现全区全回生成道情五五”期两墨的南斗日标',
title: '十年规划,温饱到小康',
time: 1992,
img: require('../../assets/images/home/333333.png')
},
{
id: 4,
text: '2001-2005年开品之年,中央型署了西部大开发”路',
title: '西部大开发战略',
time: 1992,
img: require('../../assets/images/home/444444.png')
}
]
},
{
id: 3,
type: '1993',
children: [
{
id: 1,
text: '极左思想占据主导,农业发展缓慢',
title: '三五计划',
time: 1993,
img: require('../../assets/images/home/111.png')
},
{
id: 2,
text: '中央的集一部署,各级党组织镇导下,对农业六卑世调整',
title: '“七五末”解决温饱',
time: 1993,
img: require('../../assets/images/home/222222.png')
},
{
id: 3,
text: '要实现全区全回生成道情五五”期两墨的南斗日标',
title: '十年规划,温饱到小康',
time: 1993,
img: require('../../assets/images/home/333333.png')
},
{
id: 4,
text: '2001-2005年开品之年,中央型署了西部大开发”路',
title: '西部大开发战略',
time: 1993,
img: require('../../assets/images/home/444444.png')
}
]
},
{
id: 5,
type: '1995',
children: []
},
{
id: 6,
type: '1996',
children: []
},
{
id: 7,
type: '1997',
children: []
},
{
id: 8,
type: '1998',
children: []
},
{
id: 9,
type: '1999',
children: []
},
{
id: 10,
type: '2000',
children: []
},
{
id: 11,
type: '2001',
children: []
},
{
id: 12,
type: '1999',
children: []
},
{
id: 13,
type: '888',
children: []
},
{
id: 14,
type: '777',
children: []
},
{
id: 15,
type: '6666',
children: []
},
{
id: 16,
type: '5555',
children: []
},
],
currentProgressId: '',
scrollResultWidth: 0, //transform滚动的距离
signleWidth: 134, //单个流程的宽度
activeName: 0,
currentClickNumber: 0,
noScrollRight: true,
falg: false,
active: 0,
}
},
created() {
this.$nextTick(() => {
setTimeout(() => {
this.initgoRightArrow();
});
});
},
methods: {
//初始化判断是否可以向右滚动
initgoRightArrow() {
const currentScrollWidth = this.$refs[`fixedBox`].clientWidth;
const canNumber = Math.floor(currentScrollWidth / this.signleWidth); //可以放下的个数
//如果最后一个流程图标已经展示出来,则停止滚动
if (this.currentClickNumber + canNumber >= this.progressList.length) {
this.noScrollRight = false;
return;
}
},
//点击上一个
fnPrev() {
//如果右点击的次数大于0,才可以左滚
if (this.currentClickNumber > 0) {
this.currentClickNumber -= 1;
// this.active -= 1;
this.noScrollRight = true;
this.fnScrollWidth('reduce');
} else {
return false;
}
},
//点击下一个
fnNext() {
const currentScrollWidth = this.$refs[`fixedBox`].clientWidth;
const canNumber = Math.floor(currentScrollWidth / this.signleWidth); //可以放下的个数
//如果最后一个流程图标已经展示出来,则停止滚动
if (this.currentClickNumber + canNumber >= this.progressList.length) {
return;
}
//说明放不下有滚动条
if (this.progressList.length > canNumber) {
this.currentClickNumber += 1;
// this.active += 1;
if (this.currentClickNumber + canNumber >= this.progressList.length) {
this.noScrollRight = false;
}
this.fnScrollWidth('add');
}
},
//translate的宽度
fnScrollWidth(type) {
let result = 0;
if (type === 'reduce') {
result = 134;
} else if (type === 'add') {
result = -134;
} else {
result = 0;
}
this.scrollResultWidth += result;
},
// 鼠标移入
onMouseOver() {
// console.log('鼠标进来了');
this.falg = true;
},
// 鼠标移出
onMouseOut() {
// console.log('鼠标出去了');
this.falg = false;
},
btnClid(index) {
console.log(index);
if (index > this.active) {
this.fnNext()
this.active = index;
} else {
this.fnPrev()
this.active = index;
}
},
//点击到顶部
btnLeft() {
//改变按钮状态
this.currentClickNumber = 0;
this.noScrollRight = true;
//向顶部滚动的宽度
this.scrollResultWidth = 0;
},
//点击到底部
btnRight() {
//改变按钮状态
this.currentClickNumber = 666;
this.noScrollRight = false;
//向底部滚动的宽度
this.scrollResultWidth = -this.progressList.length * 134 / 2 + 120;
}
}
}
</script>
<style lang="scss" scoped>
.chromology-home {
width: 100%;
/* padding-top: 100px; */
display: flex;
align-items: center;
flex-direction: column;
.time-axis {
width: 100%;
height: 140px;
background-color: #f6f6f2;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.processBox {
width: 1200px;
height: 100px;
display: flex;
align-items: center;
justify-content: space-between;
.left-one {
width: 15px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.right-two {
width: 15px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.arrow {
width: 60px;
height: 60px;
cursor: pointer;
}
.active {
width: 134px;
height: 60px;
cursor: pointer;
// background-color: green;
}
.arrowOpacity {
cursor: default;
opacity: 0.4;
}
.fixedBox {
flex: 1;
overflow: hidden;
}
.centerScroll {
// flex: 1;
box-sizing: border-box;
padding: 10px 0;
background: url('../../assets/images/chronology/jianduan.png') repeat-x;
// white-space: nowrap;
width: calc(100% - 30px);
overflow-x: auto;
.signleTab {
// width: 158px;
position: relative;
display: inline-block;
.leftIcon {
width: 134px;
text-align: center;
cursor: pointer;
// background-color: yellow;
position: relative;
&>.pregressIcon {
width: 134px;
height: 60px;
}
.active-img {
width: 134px;
height: 40px;
position: absolute;
left: 0px;
top: -11px;
background: url('../../assets/images/chronology/active.png') no-repeat center;
}
.active-title {
width: 134px;
position: absolute;
left: 0px;
top: 38px;
}
}
&>.arrowSquare {
position: absolute;
top: 25px;
right: 0;
}
}
}
}
.axis-body {
width: 1200px;
// height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
.chromology-body {
width: 1200px;
height: auto;
ul {
width: 100%;
height: auto;
display: flex;
flex-direction: column;
li {
width: 100%;
height: 380px;
margin: 12px 0px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
.left-body {
width: 80px;
height: 380px;
// background-color: red;
display: flex;
align-items: center;
justify-content: center;
.body-img {
width: 47px;
height: 111px;
img {
width: 100%;
height: 100%;
}
}
}
.right-body {
width: calc(100% - 80px);
height: 100%;
display: flex;
align-items: center;
justify-content: space-around;
flex-wrap: wrap;
.rit-bod {
width: auto;
display: flex;
cursor: pointer;
.rit-img {
width: 52px;
height: 62px;
img {
width: 100%;
height: 100%;
}
}
.rit-text {
width: 400px;
display: flex;
flex-wrap: wrap;
line-height: 28px;
margin: 24px 20px;
}
}
.lef-bod {
// width: 400px;
display: flex;
cursor: pointer;
.lef-img {
width: 52px;
height: 62px;
img {
width: 100%;
height: 100%;
}
}
.lef-text {
width: 400px;
display: flex;
flex-wrap: wrap;
line-height: 28px;
margin: 24px 20px;
}
}
}
.all-body {
width: 80px;
height: 42px;
position: absolute;
right: 0px;
top: 0px;
line-height: 42px;
text-align: center;
cursor: pointer;
font-size: 16px;
font-family: PingFang SC;
font-weight: 400;
color: #ecc99d;
}
.all-body:hover {
color: #e5d1b9;
}
}
li:nth-of-type(odd) {
background: url('../../assets/images/chronology/shendu.png') no-repeat;
}
li:nth-of-type(even) {
background: url('../../assets/images/chronology/qianse.png') no-repeat;
}
}
}
}
//修改element ui按钮样式
::v-deep .el-button--primary {
width: 66px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
color: #B1A086;
// border-color: #C88375;
border: 1px solid #B1A086;
}
::v-deep .el-button--primary:focus,
.el-button--primary:hover {
// border-color: #c6705f;
color: #ab9067;
border: 1px solid #ab9067;
}
</style>
Effect: