De acuerdo con el eje de tiempo, se puede hacer clic en el año o (visualización de datos mensuales) para cambiar y cambiar dinámicamente datos y otras funciones (con los botones izquierdo y derecho para cambiar con un clic a la primera o última interacción de la función del botón) con efectos de animación. etc.
1: código fuente de demostración
<!-- -->
<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: el código fuente completo de la página
<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>
Efecto: