Vue.js实现时间轴功能
程序员文章站
2022-07-07 21:50:52
本文实例为大家分享了vue.js实现时间轴功能的具体代码,供大家参考,具体内容如下github时间轴组件封装main.js
本文实例为大家分享了vue.js实现时间轴功能的具体代码,供大家参考,具体内容如下
时间轴组件封装
main.js
<template> <div class="timeline-main"> <div class="timeline-axis"> <div class="axis-item" v-for="(time, index) in datetimes" :key="index"> <div class="axis-item-tick" :class="{ 'axis-item-tick-active': index === highlightindex }" @mouseenter="hoverindex = index" @mouseleave="hoverindex = -1" @click="tickclick(time, index)"> </div> <div class="axis-item-label" v-if="datetimeindexes.indexof(index) >= 0"> {{ time }}</div> <div class="axis-item-tip" v-if="index === highlightindex || index === hoverindex"> {{ time }}</div> </div> </div> <div class="timeline-control"> <i class="menu-icon icon-left" :class="{'menu-icon-disabled': playing}" @click="backward"></i> <i class="menu-icon" :class="{'icon-play': !playing, 'icon-pause': playing}" @click="toggleplay" @mouseleave="hoverindex = -1"></i> <i class="menu-icon icon-right" :class="{'menu-icon-disabled': playing}" @click="forward"></i> <i class="menu-icon icon-up" :class="{'menu-icon-disabled': playing}" @click="speedslow"></i> <i class="menu-icon speed">{{ options.speed }}</i> <i class="menu-icon icon-down" :class="{'menu-icon-disabled': playing}" @click="speedquick"></i> </div> </div> </template> <script> import { dateformat } from '../util/formatdate.js' // 日期格式化 export default { data() { return { intervaltimer: null, // 定时器 datetimeindexes: [], // 日期列表 playing: false, // 播放 activeindex: 0, // 当前的时间位置 hoverindex: 0 // 鼠标移入的时间位置 } }, props: { options: { type: object, default() { return {} } }, datetimes: { type: array, default() { return [] } }, interval: { type: number, default() { return 100 } } }, computed: { highlightindex() { return ( (this.activeindex === -1 && this.datetimes.length - 1) || this.activeindex ) } }, watch: { options: { handler() { this.rendertimeline() }, deep: true }, playing() { if (this.playing) { this.intervaltimer = setinterval(() => { this.activeindex = (this.activeindex + 1) % this.datetimes.length }, this.options.speed * 1000) } else { if (this.intervaltimer) { clearinterval(this.intervaltimer) this.intervaltimer = null } } }, activeindex() { const time = this.datetimes[this.activeindex].split(' ')[0] this.$emit('getdatefun', time) } }, mounted() { this.rendertimeline() let that = this window.onresize = function () { that.rendertimeline() } }, filters: { formatdatetime(datetime) { datetime = dateformat(datetime, 'mm.dd') return datetime } }, methods: { /** * @name: 初始化时间轴 */ rendertimeline() { // 时间轴的宽度 const timelinewidth = this.$el.offsetwidth - 40 // 日期个数 const datetimessize = this.datetimes.length // 如果时间全部显示,时间轴的理想宽度 const datetimeswidth = datetimessize * this.interval // 如果时间轴的宽度小于理想宽度 if (timelinewidth >= datetimeswidth) { this.datetimeindexes = this.datetimes.map((datetime, index) => { return index }) return } // 当前时间轴的宽度最大能容纳多少日期刻度 const maxticks = math.floor(timelinewidth / this.interval) // 间隔刻度数 const gapticks = math.floor(datetimessize / maxticks) // 记录需要显示的日期索引 this.datetimeindexes = [] for (let t = 0; t <= maxticks; t++) { this.datetimeindexes.push(t * gapticks) } const len = this.datetimeindexes.length // 最后一项需要特殊处理 if (len > 0) { const lastindex = this.datetimeindexes[len - 1] if (lastindex + gapticks > datetimessize - 1) { this.datetimeindexes[len - 1] = datetimessize - 1 } else { this.datetimeindexes.push(datetimessize - 1) } } }, /** * @name: 点击刻度 * @param {time} * @param {index} */ tickclick(time, index) { if (this.playing) { return } this.activeindex = index }, /** * @name: 播放和暂停 */ toggleplay() { this.playing = !this.playing }, /** * @name: 时间退后一日 */ backward() { if (this.playing) { return } this.activeindex = this.activeindex - 1 if (this.activeindex === -1) { this.activeindex = this.datetimes.length - 1 } }, /** * @name: 时间前进一日 */ forward() { if (this.playing) { return } this.activeindex = (this.activeindex + 1) % this.datetimes.length }, /** * @name: 减慢速度 */ speedslow() { if (this.playing || this.options.speed >= this.options.speedmax) { return } this.options.speed = this.options.speed + 1 }, /** * @name: 加快速度 */ speedquick() { if (this.playing || this.options.speed <= 1) { return } this.options.speed = this.options.speed - 1 } } } </script> <style scoped lang="scss"> .timeline-main { padding: 10px; box-sizing: border-box; .timeline-axis { position: relative; display: flex; justify-content: space-around; padding: 8px 0; &::before { content: ''; width: 100%; height: 10px; position: absolute; left: 0; bottom: 8px; display: inline-block; background: rgba(0, 0, 0, 0.5); } .axis-item { position: relative; display: flex; flex-direction: column; align-items: center; .axis-item-tick { display: inline-block; width: 4px; height: 20px; background: rgba(0, 0, 0, 0.5); transition: background 0.3s; cursor: pointer; &:hover { background: #000; } } .axis-item-tick-active { background: #000; } .axis-item-label { position: absolute; bottom: -30px; white-space: nowrap; } .axis-item-tip { position: absolute; top: -25px; padding: 2px 6px; border-radius: 2px; background: rgba(0, 0, 0, 0.5); white-space: nowrap; color: #fff; } } } .timeline-control { margin-top: 40px; text-align: center; i { cursor: pointer; display: inline-block; font-style: normal; } .menu-icon { font-size: 20px; width: 20px; height: 20px; background-size: cover; background-repeat: no-repeat; &.icon-left { background-image: url('../assets/icon-left.png'); } &.icon-right { background-image: url('../assets/icon-right.png'); } &.icon-play { background-image: url('../assets/icon-play.png'); } &.icon-pause { background-image: url('../assets/icon-pause.png'); } &.icon-up { background-image: url('../assets/icon-up.png'); } &.icon-down { background-image: url('../assets/icon-down.png'); } &.menu-icon-disabled { cursor: no-drop; opacity: 0.5; } } } } </style>
使用组件
app.vue
<template> <div> <h2 style="margin:0;text-align:center;"> {{this.date}} </h2> <main :options="options" :datetimes="datetimes" @getdatefun="getdatefun" :interval="interval"></main> </div> </template> <script> import { dateformat } from './util/formatdate.js' import main from './components/main' export default { name: 'app', data() { return { date: '', options: { speed: 1, // 速度 speedmax: 10 // 速度最大值 }, interval: 20, // 日期间的间隔 datetimes: [ '03-04', '03-05', '03-06', '03-07', '03-08', '03-09', '03-10', '03-11', '03-12', '03-13' ] } }, components: { main }, mounted() { // 获取最近 10 天的日期 let list = [] for (let i = 0; i < 10; i++) { list.unshift( dateformat( new date( new date().setdate(new date().getdate() - i) ).tolocaledatestring(), 'mm-dd' ) ) } this.date = list[0] this.datetimes = list }, methods: { // 接收父组件传值 getdatefun(time) { console.log(time) this.date = time }, } } </script>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 针灸减肥知多少 揭晓针灸减肥效果