Vue如何实现时间轴
该时间轴展示的是每条工程数据的鸟瞰图,照片可多张,利用el-carousel、el-image-viewer插件,走马灯效果,可图片预览;该时间轴每页最多默认展示三条数据,根据后台数据而定,超过三条前端分页处理;
·
效果:
该时间轴每页最多默认展示三条数据,根据后台数据而定,超过三条前端分页处理;
注:
该时间轴展示的是每条工程数据的鸟瞰图,照片可多张,利用el-carousel、el-image-viewer插件,走马灯效果,可图片预览;
组件代码:
<template> <div class="m-timeline-wrap"> <div class="m-time-dot"> <!-- 左 箭头图标 --> <button class="timeLine_left_arrow" @click="leftShiftFn" :disabled="imgIndex == 0" > <img src="../../../assets/images/homePage/arrow-l-b.png" alt="" /> </button> <div :class="['m-dot-box', { active: active === index }]" @click="onClickYear(index)" v-for="(item, index) in yeardata && yeardata.length ? yeardata[this.imgIndex] : []" :key="index" > <!-- 主轴 --> <div class="u-img" v-if="active === index" @click="imageItemFun(item)"> <el-carousel height="126px"> <el-carousel-item v-for="itemImg in item.viewUrl.split(',')" :key="itemImg" > <h3 class="small"><img :src="itemImg" alt="" /></h3> </el-carousel-item> </el-carousel> </div> <p class="u-year">{{ item.viewTime }}</p> <div class="m-dot"> <div class="u-dot"></div> </div> </div> <!-- 右 箭头图标 --> <button class="timeLine_right_arrow" @click="rightShiftFn" :disabled="imgIndex == yeardata.length - 1 || yeardata.length == 0" > <img src="../../../assets/images/homePage/arrow-r-b.png" alt="" /> </button> </div> <div class="wrap"> <!-- <div class="content" @click="showImgViewer"></div> --> <el-image-viewer v-if="imgViewerVisible" :on-close="closeImgViewer" :url-list="imgList" /> </div> </div> </template> <script> export default { name: "HorizonTimeLine", props: { timelineData: { // 时间轴数据 type: Array, required: true, default: () => { return []; }, }, }, watch: { timelineData: { handler(newVal, oldVal) { this.setTime(); // 延时1秒调用方法,等待父组件的传参返回 //默认选中第一条数据 this.active = 0; this.imgIndex=0 }, deep: true, immediate: true, }, }, components: { "el-image-viewer": () => import("element-ui/packages/image/src/image-viewer"), }, data() { return { imgViewerVisible: false, imgList: [ "https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg", "https://fuss10.elemecdn.com/1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg", ], active: 0, yeardata: [], imgIndex: 0, }; }, created() { this.setTime(); // 延时1秒调用方法,等待父组件的传参返回 }, mounted() {}, methods: { getData() { // 使用父组件传过来的数据,进行新的请求 //三等分 取余 const result = this.timelineData.reduce((acc, curr, index) => { if (index % 3 === 0) acc.push([]); acc[Math.floor(index / 3)].push(curr); return acc; }, []); this.yeardata = result; //默认选中每一组的第一条数据 }, setTime() { // 定时器,延时调用方法 let win = this; setTimeout(function () { win.getData(); // 获取数据 }); }, imageItemFun(e) { // 数据处理 this.imgList = e.viewUrl.split(","); this.imgViewerVisible = true; }, // showImgViewer() { // this.imgViewerVisible = true; // const m = (e) => { // e.preventDefault(); // }; // document.body.style.overflow = "hidden"; // document.addEventListener("touchmove", m, false); // 禁止页面滑动 // }, closeImgViewer() { this.imgViewerVisible = false; const m = (e) => { e.preventDefault(); //取消默认事件 }; document.body.style.overflow = "auto"; document.removeEventListener("touchmove", m, true); }, onClickYear(index) { if (this.active !== index) { this.active = index; } }, // 左右切换页码 leftShiftFn() { this.imgIndex--; this.active = 0; this.$emit("changeYearFun", this.active); }, rightShiftFn() { this.imgIndex++; this.active = 0; this.$emit("changeYearFun", this.active); }, }, }; </script> <style lang="less" scoped> @themeColor: #1890ff; @onicon:url ("../../../assets/images/homePage/dot-b-on.png"); @noicon:url ("../../../assets/images/homePage/dot-b.png"); button[disabled] { color: white !important; cursor: not-allowed !important; } .el-image-viewer__wrapper { z-index: 99999 !important; } .content { width: 100%; height: 1500px; background: pink; } .m-timeline-wrap { width: 60%; height: 10px; background: url("../../../assets/images/homePage/bg-line-b.png") no-repeat; background-size: 100%; position: absolute; bottom: 30px; left: 20%; z-index: 9990; .m-time-dot { display: flex; justify-content: space-between; margin-top: 30px; .timeLine_left_arrow { position: relative; bottom: 53px; cursor: pointer; background: rgba(0, 0, 0, 0); border: none; } .timeLine_right_arrow { position: relative; bottom: 53px; cursor: pointer; background: rgba(0, 0, 0, 0); border: none; } .m-dot-box { cursor: pointer; text-align: center; transform: translateY(-56px); // position: relative; .u-year { font-size: 16px; font-weight: 500; color: #77a4c7; transform: translateY(35px); transition: all 0.3s ease; } ::v-deep .u-img { width: 193px; // height: auto; min-height: 126px; position: absolute; bottom: 25px; left: -55px; // border: 1px solid #fff; transform: translateY(-35px); transition: all 1s ease; .el-carousel .el-carousel--horizontal { width: 100%; height: 100% !important; overflow: hidden; .el-carousel__container{ height: 100% !important; } .el-carousel__item .is-active .is-animating{ width: 100%; height: auto; } } .el-carousel__item h3 { color: #475669; font-size: 14px; opacity: 0.75; line-height: 62px; margin: 0; } .el-carousel__item:nth-child(2n) { background-color: #99a9bf; } .el-carousel__item:nth-child(2n + 1) { background-color: #d3dce6; } img { width: 100%; height: 100%; display: block; } } .m-dot { margin: 0 auto; width: 14px; height: 14px; // background: #8dc6f5; background: url("../../../assets/images/homePage/dot-b.png"); background-size: 100%; border-radius: 50%; transition: all 0.3s ease; .u-dot { width: 14px; height: 14px; background: url("../../../assets/images/homePage/dot-b.png"); border-radius: 50%; transition: all 0.3s ease; } } } .m-dot-box:hover { .u-year { color: @themeColor; } .m-dot { .u-dot { // background: @themeColor; background: url("../../../assets/images/homePage/dot-b-on.png"); background-size: 100%; } } } .active { .u-year { transform: scale(1) translateY(45px); // 同时设置多个transform属性只需用空格间隔,执行时从后往前执行! color: @themeColor; } .m-dot { transform: scale(3); .u-dot { transform: scale(0.67); background: url("../../../assets/images/homePage/dot-b-on.png"); background-size: 100%; } } } } } </style>
注意:多张图片是以字符串形式传过来的,需对其进行二次处理,如上
页面 调用:
<body>
<HorizonTimeLine
:timelineData="timelineData"
>
</body>
<script>
//时间节点获取
getTimeNodeList() {
let params = {
keyProjectId: this.projectInfolist?.id,
businessCode: this.$bus.businessCode,
};
$get(getKeyProjectTimeNodeListUrl, params).then((res) => {
this.timelineData = res.data.data;
});
},
</script>
希望对大家有所帮助,如有不妥,多多包涵。。。
更多推荐
已为社区贡献2条内容
所有评论(0)