前言
才发现github上有个50projects50days的项目,感觉还挺有趣的,可以练手学习,增加点代码练习,巩固下基础知识。
计划用vue2改写15个项目,vue3+js改写15个项目,vue3+ts改写20个项目。
在此仅作个人记录,权当打卡and水文章了hh
实现
第二个项目,ProgressSteps,基于vue2实现
(简单的学习笔记在代码中)
<template>
<div class="body">
<div class="container">
<div class="progress-container">
<div class="progress" ref="progress"></div>
<div v-for="(item, index) of progressList" :key="index" class="circle" ref="circles">{
{
item.value }}</div>
</div>
<button class="btn" @click="prev" ref="prev" disabled>Prev</button>
<button class="btn" @click="next" ref="next">Next</button>
</div>
</div>
</template>
<script>
export default {
name: 'ProgressSteps',
components: {
},
data() {
return {
currentActive: 1,
progressList: [
{
value: '1'
},
{
value: '2'
},
{
value: '3'
},
{
value: '4'
}
]
}
},
methods: {
next() {
this.currentActive++;
console.log(this.$refs.circles.length)
if (this.currentActive > this.$refs.circles.length) {
this.currentActive = this.$refs.circles.length
}
this.update()
},
prev() {
this.currentActive--;
if (this.currentActive < 1) {
this.currentActive = 1
}
this.update()
},
update() {
this.$refs.circles.forEach((circle, index) => {
if (index < this.currentActive) {
circle.classList.add('active')
} else {
circle.classList.remove('active')
}
})
this.$refs.progress.style.width = (this.currentActive - 1) / (this.$refs.circles.length - 1) * 100 + '%'
if (this.currentActive === 1) {
this.$refs.prev.disabled = true
} else if (this.currentActive === this.$refs.circles.length) {
this.$refs.next.disabled = true
} else {
this.$refs.prev.disabled = false;
this.$refs.next.disabled = false;
}
},
initPage() {
this.$refs.circles[0].classList.add('active')
}
},
mounted() {
this.initPage()
}
}
</script>
<style scoped>
@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');
/* 1 :root伪类,匹配文档树的根目录,在html中代表<html>元素,优先级更高,其他相同 */
/* 2 --* 自定义属性 */
/* https://www.jianshu.com/p/1d2d02569351 */
/* 不在app.vue中不起作用 */
:root {
--line-border-fill: #3498db;
--line-border-empty: #383838;
}
* {
/* 需在app.vue中设置 */
box-sizing: border-box;
}
/* 不在app.vue中,不能用body */
.body {
background-color: #1f1f1f;
font-family: 'Muli', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
.container {
text-align: center;
/* vue需要设置此项,否则横线z-index=-1会看不见 */
z-index: 0;
}
.progress-container {
display: flex;
justify-content: space-between;
position: relative;
margin-bottom: 30px;
max-width: 100%;
width: 350px;
/* vue也可以设置此项,否则横线z-index=-1会看不见 */
/* z-index: 0; */
}
/* 3 ::before微元素,插入匿名替换元素,通过css样式达到想要的图形效果 */
/* https://www.jianshu.com/p/21ae3227cc3e */
.progress-container::before {
content: '';
background-color: var(--line-border-empty);
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
height: 4px;
width: 100%;
z-index: -1;
}
.progress {
background-color: var(--line-border-fill);
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
height: 4px;
width: 0%;
z-index: -1;
/* 4 开始样式与结束样式,相当于两个关键帧,然后过渡效果 */
transition: 0.4s ease;
}
.circle {
background-color: #1f1f1f;
color: #e2e2e2;
border-radius: 50%;
height: 30px;
width: 30px;
display: flex;
align-items: center;
justify-content: center;
border: 3px solid var(--line-border-empty);
transition: 0.4s ease;
}
.circle.active {
border-color: var(--line-border-fill);
}
.btn {
background-color: var(--line-border-fill);
color: #fff;
border: 0;
border-radius: 6px;
font-family: inherit;
cursor: pointer;
padding: 8px 30px;
margin: 5px;
font-size: 14px;
}
/* 5 按钮变小,模仿点击效果 */
.btn:active {
transform: scale(0.98);
}
.btn:focus {
outline: 0;
}
.btn:disabled {
background-color: var(--line-border-empty);
cursor: not-allowed;
}
</style>