最近在做的一个项目中,有一些点都不难但是还蛮有意思,特此来记录一番!
1. 实时动态计时

这个需求并不难,最初稍微找了下有木有现成的组件,发现没有,可能是太简单了没有封装的必要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| export default { data () { return { timer: null } } created() { this.timer = setInterval(this.updateCurrentTime, 1000) // 每秒更新当前时间 } destroyed() { clearInterval(this.timer) // 清除定时器 } methods: { updateCurrentTime() { const now = new Date() const difference = now - this.startTime // 计算当前时间与开始时间的时间差(毫秒)
// 计算经过的小时、分钟和秒数 let hours = Math.floor((difference / (1000 * 60 * 60)) % 24) let minutes = Math.floor((difference / (1000 * 60)) % 60) let seconds = Math.floor((difference / 1000) % 60) hours = hours < 10 ? '0' + hours : hours minutes = minutes < 10 ? '0' + minutes : minutes seconds = seconds < 10 ? '0' + seconds : seconds this.currentTime = hours < 1? `${minutes}:${seconds}` : `${hours}:${minutes}:${seconds}` }, } }
|
2. 屏幕的固定和适配

大概情况就是,在上面高度固定情况下,底部区域固定,中间区域高度动态并且超出滚动条显示。
滚动条很容易overflow:auto
配合着高度height
, 关键点就是这个高度怎么设置,固定写多少px
肯定不行。
于是乎,经过一番研究,最终代码如下。
1 2 3
| height: calc(100% - 260px); max-height: calc((100vh - 400px)); overflow-y: auto;
|
利用calc(100% - 260px)
根据设计图精准设置height
, 在通过设置max-height: calc((100vh - 400px))
来控制小屏时的height
达到overflow-y: auto
的效果。
小tips: calc中100%的对象是父容器,而其中的vh是整个屏幕
3. 滑动条位置控制
如上图中,当切上一题、下一题、或者点击进去某一题时滑动条位置不变或者到对应的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export default { methods: { nextClick() { localStorage.setItem("scrollPosition", this.$refs.questionsList.scrollTop); ... ... ... if (localStorage.getItem("scrollPosition")) { // 恢复滚动位置 this.$nextTick(() => { this.$refs.questionsList.scrollTo(0, localStorage.getItem("scrollPosition")) }) } } } }
|
questionsList
对应滚动条的区域, 上下题时通过localStorage
记录滚动条的位置, 执行完逻辑后,根据记录的scrollTop
, 设置对应滚动条位置。(一点要在$nextTick中设置哦)
4. 题目切换动画
初次听到这种,就感觉跟走马灯效果很相似,但是又不太一样。
太复杂的动画有没必要,直接把动画分解,只加入进入的动画,忽略退出的动画,达到简单的动态切换的效果。
1 2 3 4 5 6 7 8
| export default { methods: { nextClick() { this.$refs.questionArea.classList.add('fadeInRight') setTimeout(() => {this.$refs.questionArea.classList.remove('fadeInRight')}, 1000) } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @keyframes fadeInLeft { from { opacity: 0; transform: translate3d(-100%, 0, 0); }
to { opacity: 1; transform: translate3d(0, 0, 0); } }
@keyframes fadeInRight { from { opacity: 0; transform: translate3d(100%, 0, 0); }
to { opacity: 1; transform: translate3d(0, 0, 0); } }
.fadeInRight { animation: fadeInRight 1s; } .fadeInLeft { animation: fadeInLeft 1s; }
|
questionArea
对应着动画的区域, 当点击上一题或者下一题时,添加动画class,然后动画执行完再移除class。
5. window.open重复打开同一个界面
1 2 3 4 5 6 7
| if(this.newWindow && !this.newWindow.closed) { this.newWindow.location.href = url; this.newWindow.focus() } else { this.newWindow = window.open(url, "_blank", "") this.newWindow.focus() }
|