下面是做了一个类似时间线(history事件线)的页面,主要是记录一下log,或者history的操作记录。

主要难点:

(1)一般的插件时间线例如(elementUI中的el-timeline)就是纵向的时间线,如果数据过多的话,就会形成很长一段的下拉样式。

(2)最主要的就是CSS样式调节,(这个真的是头大)

(3)个人审美的不同,反正我做了好几个版本样式,每个人都有自己不同的喜好。

效果图如下:

下面是代码部分:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>首页</title>
		<script src="vue/vue.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="vue/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="elementUI/index.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/jquery_flexslider.js" type="text/javascript" charset="utf-8"></script>
		<link rel="stylesheet" type="text/css" href="elementUI/index.css" />
		<link rel="stylesheet" type="text/css" href="css/index2.css" />
	</head>
	<body>
		<div class="firstShow" id="firstShow">
			<div class="statistics">
				<el-tag>提交:{{statisticsData.sumbit}} 条</el-tag>
				<el-tag color="#c6f6f8" style="color:#30c0d6 ;">通过:{{statisticsData.pass}} 条</el-tag>
				<el-tag type="success">成功:{{statisticsData.success}} 条</el-tag>
				<el-tag color="#f5dbe9" style="color:#d66196 ;">拒绝:{{statisticsData.refuse}} 条</el-tag>
				<el-tag color="#f5f2cb" style="color:#ff7f4c ;">失败:{{statisticsData.fail}} 条</el-tag>
				<el-tag color="	#f5caca" style="color:#ff4343 ;">错误:{{statisticsData.error}} 条</el-tag>
				<el-tag color="	#d3cae6" style="color:#7a64e6 ;">复核:{{statisticsData.recheck}} 条</el-tag>
				<el-tag type="info">其他:{{statisticsData.recheck}} 条</el-tag>
			</div>
			<div class="about-history" id="fzlc">
				<div class="about-history-list wow zoomIn" data-wow-delay=".1s" style="visibility: visible; animation-delay: 0.1s; animation-name: zoomIn;">
					<div class="flex-viewport" style="overflow: hidden; position: relative;">
						<ul class="slides clearfix list" style="width: 2600%; transition-duration: 0s; transform: translate3d(0px, 0px, 0px);">
							<li style="width: 196px; float: left; display: block;" v-for="(activity, index) in activitiesData">
								<div class="item">
									<h3 :style="{'color':`${activity.backgroundColor}`}">
										{{activity.timestamp}}
									</h3>
									<div class="desc">
										<p>{{ activity.name }}</p>
										<p style="display:block;height: 42px;padding-top: 10px;">【{{ activity.content }}】</p>
									</div>
								</div>
							</li>
						</ul>
					</div>
				</div>
			</div>
			<div class="nodata" id="nodata" v-if="noData">
				<span class="noData">
					暂无记录<i class="el-icon-warning-outline"></i>
				</span>
			</div>
		</div>
		<script type="text/javascript">
			var vm = new Vue({
				el: '#firstShow',
				data() {
					return {
						noData: false, // 无数据显示与否 
						/* 操作记录数据 */
						timeLength: '',
						timeliWidth: '',
						index: 0,
						activitiesData: [],

						backgroundColor: '#e2e2e2',

						statisticsData: {
							sumbit: 0, //提交
							pass: 0, //通过
							success: 0, //成功
							refuse: 0, //拒绝
							fail: 0, //失败
							error: 0, //错误
							recheck: 0, //复核
							other: 0, //其他
						}
					};
				},
				methods: {
					/* 登录信息 */
					login() {
						let _this = this;
						axios.get('data/activitiesData.json')
							.then(function(response) {
								// console.log(response.data);
								var code = '0';
								switch (code) {
									case '0':
										for (var i = 0; i < response.data.length; i++) {
											// 添加 单元格是否可以编辑的属性值
											if (response.data[i].name.indexOf('提交') != -1) {
												response.data[i].backgroundColor = '#409EFF';
												_this.statisticsData.sumbit += 1;
											} else if (response.data[i].name.indexOf('通过') != -1) {
												response.data[i].backgroundColor = '#30c0d6';
												_this.statisticsData.pass += 1;
											} else if (response.data[i].name.indexOf('成功') != -1) {
												response.data[i].backgroundColor = '#67C23A';
												_this.statisticsData.success += 1;
											} else if (response.data[i].name.indexOf('拒绝') != -1) {
												response.data[i].backgroundColor = '#d66196';
												_this.statisticsData.refuse += 1;
											} else if (response.data[i].name.indexOf('失败') != -1) {
												response.data[i].backgroundColor = '#ff7f4c';
												_this.statisticsData.fail += 1;
											} else if (response.data[i].name.indexOf('错误') != -1) {
												response.data[i].backgroundColor = '#ff4343';
												_this.statisticsData.error += 1;
											} else if (response.data[i].name.indexOf('复核') != -1) {
												response.data[i].backgroundColor = '#7a64e6';
												_this.statisticsData.recheck += 1;
											} else {
												response.data[i].backgroundColor = '#a0a3aa';
												_this.statisticsData.other += 1;
											}
										}
										vm.activitiesData = response.data;
										console.log(vm.activitiesData);
										break;
									case '99':
										// window.location.href = "../view/error?errorMsg=" + errorMsg;
										window.location.href = 'error.html?errorMsg=' + errorMsg;
										break;
									case '1':
										// window.location.href = "../view/tips?errorMsg=" + errorMsg;
										window.location.href = 'tips.html?errorMsg=' + errorMsg;
										break;
									case '2':
										break;
									default:
										break;
								}

							}).catch(function(error) {
								console.log(error);
							});
					},
					/* ------- 历史记录 -------*/
					/* 初始加载 */
					startTime() {
						$('.about-history-list').flexslider({
							animation: 'slide',
							slideshow: false,
							controlNav: false,
							itemWidth: 196,
							itemMargin: 30,
							animationLoop: false,
							prevText: '<',
							nextText: '>',
							move: 3,
							start: function(slider) {
								console.log(slider);
								$('.flex-prev').attr('style', 'pointer-events: none;opacity: 0.2');
							},
							after: function(slider) {
								console.log(slider);
								if (slider.currentSlide == 0) {
									$('.flex-prev').attr('style', 'pointer-events: none;opacity: 0.2');
								} else if (slider.currentSlide + 1 == slider.pagingCount) {
									$('.flex-next').attr('style', 'pointer-events: none;opacity: 0.2');
								} else {
									$('.flex-prev').attr('style', 'pointer-events: black;opacity: 1');
									$('.flex-next').attr('style', 'pointer-events: black;opacity: 1');
								}
							},
							end: function(slider) {
								console.log(slider);
								$('.flex-next').attr('style', 'pointer-events: none;opacity: 0.2');
							}
						});
					},

				},
				updated() {
					this.startTime();
				},
				mounted() {
					this.login();
				}
			});
		</script>
	</body>
</html>

css样式部分:

html,
body {
	width: 100%;
	height: 100%;
	padding: 0;
	margin: 0;
}

/* 首页时间轴 */
.firstShow {
	width: 90%;
	height: 60%;
	padding: 5% 5%;
}

.firstShow .statistics {
	width: 70%;
	height: 60px;
	line-height: 60px;
	margin-left: 24%;
}

/* 无数据 */
.nodata {
	width: 100%;
	margin: 0 auto;
	padding-top: 20%;
}

.nodata .noData {
	font-size: 64px;
	color: #a9a9a987;
	letter-spacing: 60px;
	display: block;
	text-align: center;
	line-height: 50%;
}

/* about-history */
.about-history {
	height: 80%;
	padding: 64px 20px 0;
}

.about-history-list {
	position: relative;
}

.about-history-list .flex-viewport {
	padding: 0 50px;
}

.about-history-list .flex-viewport:before {
	position: absolute;
	top: 50%;
	right: 0;
	left: 0;
	border-top: 1px solid #C7C7C7;
	content: '';
}

.about-history-list .slides li {
	position: relative;
	width: 196px;
	height: 470px;
	margin-right: 28px;
}

.about-history-list .slides li .item {
	position: absolute;
	right: -32px;
	bottom: 0;
	left: -32px;
	min-height: 152px;
	padding: 44px 0 0 0;
	background-color: #fff;
	border: 1px solid #e2e2e2;
	-webkit-transition: all .2s ease;
	-moz-transition: all .2s ease;
	-ms-transition: all .2s ease;
	-o-transition: all .2s ease;
	transition: all .2s ease;
}

.about-history-list .slides li .item:hover:before {
	position: absolute;
	top: -49px;
	left: 50%;
	width: 20px;
	height: 20px;
	overflow: hidden;
	margin-left: -10px;
	-webkit-border-radius: 100%;
	-moz-border-radius: 100%;
	border-radius: 100%;
	background-color: rgba(0, 170, 255, 0.6);
	content: '';
}

.about-history-list .slides li .item:before {
	position: absolute;
	top: -49px;
	left: 50%;
	width: 20px;
	height: 20px;
	overflow: hidden;
	margin-left: -10px;
	-webkit-border-radius: 100%;
	-moz-border-radius: 100%;
	border-radius: 100%;
	background-color: rgba(185, 185, 185, 0.6);
	content: '';
}

.about-history-list .slides li .item:after {
	position: absolute;
	top: -45px;
	left: 50%;
	width: 12px;
	height: 12px;
	overflow: hidden;
	margin-left: -6px;
	-webkit-border-radius: 100%;
	-moz-border-radius: 100%;
	border-radius: 100%;
	background-color: #7a7a7a;
	content: '';
}

.about-history-list .slides li .item:hover:after {
	position: absolute;
	top: -45px;
	left: 50%;
	width: 12px;
	height: 12px;
	overflow: hidden;
	margin-left: -6px;
	-webkit-border-radius: 100%;
	-moz-border-radius: 100%;
	border-radius: 100%;
	background-color: #0095df;
	content: '';
}

.about-history-list .slides li:nth-child(even) .item {
	top: 0;
	bottom: auto;
	padding: 0 0 44px;
}

.about-history-list .slides li:nth-child(even) .item:before {
	top: auto;
	bottom: -49px;
}

.about-history-list .slides li:nth-child(even) .item:after {
	top: auto;
	bottom: -45px;
}

.about-history-list .slides li .item:hover {
	background-color: #00aaff;
	border-color: transparent transparent #00aaff;
}

.about-history-list .slides li .item h3 {
	position: absolute;
	top: 0;
	right: 0;
	left: 0;
	height: 44px;
	line-height: 44px;
	margin: 0;
	font-size: 20px;
	font-weight: 400;
	color: #000000;
	text-align: center;
	background-color: #e2e2e2;
	-webkit-transition: all .2s ease;
	-moz-transition: all .2s ease;
	-ms-transition: all .2s ease;
	-o-transition: all .2s ease;
	transition: all .2s ease;
}

.about-history-list .slides li .item:hover h3 {
	color: #232323;
	background-color: #fff;
}

.about-history-list .slides li .item:hover h3:before {
	position: absolute;
	bottom: 100%;
	left: 50%;
	margin-left: -9px;
	border-width: 0 9px 18px;
	border-style: solid;
	border-color: transparent transparent #00aaff;
	content: '';
}


.about-history-list .slides li .item h3:before {
	position: absolute;
	bottom: 100%;
	left: 50%;
	margin-left: -9px;
	border-width: 0 9px 18px;
	border-style: solid;
	border-color: transparent transparent #E2E2E2;
	content: '';
}

.about-history-list .slides li:nth-child(even) .item h3 {
	top: auto;
	bottom: 0;
}

.about-history-list .slides li:nth-child(even) .item h3:before {
	top: 100%;
	bottom: auto;
	border-width: 18px 9px 0;
	border-color: #E2E2E2 transparent transparent;
}

.about-history-list .slides li:nth-child(even) .item:hover h3:before {
	top: 100%;
	bottom: auto;
	border-width: 18px 9px 0;
	border-color: #00aaff transparent transparent;
}

.about-history-list .slides li .item .desc {
	line-height: 24px;
	padding: 22px 26px 0;
	font-size: 18px;
	color: #000000;
}

.about-history-list .slides li .item:hover .desc {
	color: #ffffff;
}

.about-history-list .slides li .item .desc p {
	margin: 0;
}

.flex-direction-nav {
	padding: 0;
	margin: 0;
	list-style: none;
}

.flex-direction-nav a {
	position: absolute;
	top: 50%;
	width: 30px;
	height: 160px;
	line-height: 160px;
	overflow: hidden;
	margin-top: -80px;
	font-size: 50px;
	font-family: simsun;
	font-weight: bolder;
	color: #474747;
	text-align: center;
}

.flex-direction-nav a.flex-prev {
	left: -48px;
}

.flex-direction-nav a.flex-prev:hover {
	color: #00aaff;
}

.flex-direction-nav a.flex-next {
	right: -48px;
}

.flex-direction-nav a.flex-next:hover {
	color: #00aaff;
}

a {
	color: #414141;
	text-decoration: none;
	-webkit-transition: all .2s ease;
	-moz-transition: all .2s ease;
	-ms-transition: all .2s ease;
	-o-transition: all .2s ease;
	transition: all .2s ease;
}

a:hover {
	text-decoration: none;
}

.pull-left {
	float: left;
}

.pull-right {
	float: right;
}

.pull-none {
	float: none;
}

.clearfix:after {
	clear: both;
	display: block;
	visibility: hidden;
	height: 0;
	content: ".";
	font-size: 0;
}

* html .clearfix {
	zoom: 1;
}

*:first-child+html .clearfix {
	zoom: 1;
}

.container {
	width: 980px;
	margin: 0 auto;
}

img {
	max-width: 100%;
}

img.full {
	display: block;
	width: 100%;
}

.list {
	padding: 0;
	margin: 0;
	list-style: none;
}

.hidden {
	display: none;
}

.col-1 {
	float: left;
	width: 8.33333333%;
}

.col-2 {
	float: left;
	width: 16.66666667%;
}

.col-3 {
	float: left;
	width: 25%;
}

.col-4 {
	float: left;
	width: 33.33333333%;
}

.col-5 {
	float: left;
	width: 41.66666667%;
}

.col-6 {
	float: left;
	width: 50%;
}

.col-7 {
	float: left;
	width: 58.33333333%;
}

.col-8 {
	float: left;
	width: 66.66666667%;
}

.col-9 {
	float: left;
	width: 75%;
}

.col-10 {
	float: left;
	width: 83.33333333%;
}

.col-11 {
	float: left;
	width: 91.66666667%;
}

.col-12 {
	float: left;
	width: 100%;
}

.col-13 {
	float: left;
	width: 20%;
}

.col-offset-3 {
	margin-left: 25%;
}

.tb {
	display: table;
	width: 100%;
	height: 100%;
}

.tbr {
	display: table-row;
}

.tbc {
	display: table-cell;
	vertical-align: middle;
}

data模拟数据:

[{
		"content": "郭艾伦 (人事专员)",
		"name": "徐忠硕提交了一个审批",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "通过",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "拒绝",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "贺天举 (董事长)",
		"name": "失败",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "郭艾伦 (人事专员)",
		"name": "成功",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "错误",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "复核2",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "贺天举 (董事长)",
		"name": "审批",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "郭艾伦 (人事专员)",
		"name": "提交",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "通过",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "复核",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "贺天举 (董事长)",
		"name": "审批",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "郭艾伦 (人事专员)",
		"name": "提交",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "拒绝",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "错误",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "贺天举 (董事长)",
		"name": "成功",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "郭艾伦 (人事专员)",
		"name": "提交",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "失败",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "拒绝2",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "贺天举 (董事长)",
		"name": "审批",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "郭艾伦 (人事专员)",
		"name": "提交",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "通过",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "复核",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "贺天举 (董事长)",
		"name": "审批",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "郭艾伦 (人事专员)",
		"name": "提交",
		"timestamp": "2018-04-12 20:46",
		"idea": "一朵小红花"
	},
	{
		"content": "赵继伟 (人事主管)",
		"name": "通过",
		"timestamp": "2018-04-03 20:46",
		"type": "01"
	},
	{
		"content": "韩德君 (财务主管)",
		"name": "复核",
		"timestamp": "2018-04-03 20:46"
	},
	{
		"content": "xzs",
		"name": "审批",
		"timestamp": "2018-04-03 20:46"
	}

]

下面主要讲解一下我认为比较重点的内容:

flexslider.js插件没什么好说的,在网上有很多的案例和参数,我要说的是以下几点:

(1)如何动态绑定样式?

<h3 :style="{'color':`${activity.backgroundColor}`}">
     {{activity.timestamp}}
</h3>

这段代码想必大家都已经看到了,这是vue中,动态绑定标签样式的方式,要使用 “ ` ”  “$” 符号将数据内容包裹起来。这样就等达到动态绑定css样式的效果了。

(2)如何在开始页和结束页不能点击上一页按钮和下一页按钮?

start: function(slider) {
             console.log(slider);
             $('.flex-prev').attr('style', 'pointer-events: none;opacity: 0.2');
 },
after: function(slider) {
            console.log(slider);
           if (slider.currentSlide == 0) {
                    $('.flex-prev').attr('style', 'pointer-events: none;opacity: 0.2');
            } else if (slider.currentSlide + 1 == slider.pagingCount) {
                    $('.flex-next').attr('style', 'pointer-events: none;opacity: 0.2');
            } else {
                     $('.flex-prev').attr('style', 'pointer-events: black;opacity: 1');
                     $('.flex-next').attr('style', 'pointer-events: black;opacity: 1');
            }
},
 end: function(slider) {
             console.log(slider);
             $('.flex-next').attr('style', 'pointer-events: none;opacity: 0.2');
 }

在flexslider中,有start,end,after等函数参数,然后获取内部的className,设定样式。

下面是flexslider函数中常用的方法:

 

slider.count

值,滚动项目总数

slider.currentSlide

值,当前页

slider.flexAnimate(n)

方法,滚动到某页

slider.pagingCount

值,页数

slider.pause()

方法,暂停

slider.play()

方法,播放

 好了,这次文章就写到这里啦,若内容、代码有不妥的地方,望斧正!谢谢。

Logo

前往低代码交流专区

更多推荐