139 lines
2.6 KiB
Vue
139 lines
2.6 KiB
Vue
<template>
|
||
<SlideLayout>
|
||
<div class="content">
|
||
<h1 class="title animate-slide-down">Hooks 的历史</h1>
|
||
<div class="timeline">
|
||
<div class="timeline-item animate-fade-in" v-for="(item, index) in history" :key="index" :style="{ animationDelay: `${index * 0.2}s` }">
|
||
<div class="timeline-date">{{ item.date }}</div>
|
||
<div class="timeline-content">
|
||
<h3>{{ item.title }}</h3>
|
||
<p>{{ item.description }}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</SlideLayout>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import SlideLayout from '../components/SlideLayout.vue';
|
||
|
||
const history = [
|
||
{
|
||
date: '2016',
|
||
title: 'Mixins 时代',
|
||
description: 'Vue2 主要使用 Mixins 来复用组件逻辑,但存在命名冲突和数据来源不清晰的问题。'
|
||
},
|
||
{
|
||
date: '2019',
|
||
title: 'React Hooks 发布',
|
||
description: 'React 16.8 发布 Hooks,展示了一种全新的逻辑复用方式。'
|
||
},
|
||
{
|
||
date: '2020',
|
||
title: 'Vue3 Composition API',
|
||
description: 'Vue3 正式发布,引入 Composition API,提供了类似 Hooks 的能力。'
|
||
},
|
||
{
|
||
date: '现在',
|
||
title: 'Hooks 生态繁荣',
|
||
description: 'Vue 社区出现了大量优秀的 Hooks 库,极大提升了开发效率。'
|
||
}
|
||
];
|
||
</script>
|
||
|
||
<style scoped>
|
||
.content {
|
||
padding: 2rem;
|
||
}
|
||
|
||
.title {
|
||
color: #ff8c00;
|
||
font-size: 3rem;
|
||
text-align: center;
|
||
margin-bottom: 3rem;
|
||
}
|
||
|
||
.timeline {
|
||
max-width: 800px;
|
||
margin: 0 auto;
|
||
position: relative;
|
||
}
|
||
|
||
.timeline::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 2px;
|
||
height: 100%;
|
||
background-color: #ff8c00;
|
||
}
|
||
|
||
.timeline-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 2rem;
|
||
opacity: 0;
|
||
}
|
||
|
||
.timeline-item:nth-child(odd) {
|
||
flex-direction: row-reverse;
|
||
}
|
||
|
||
.timeline-date {
|
||
width: 120px;
|
||
padding: 0.5rem;
|
||
background-color: #ff8c00;
|
||
color: white;
|
||
text-align: center;
|
||
border-radius: 4px;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.timeline-content {
|
||
width: calc(50% - 80px);
|
||
padding: 1rem;
|
||
background: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.timeline-content h3 {
|
||
color: #ff8c00;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
/* Animations */
|
||
.animate-slide-down {
|
||
animation: slideDown 1s ease;
|
||
}
|
||
|
||
.animate-fade-in {
|
||
animation: fadeIn 1s ease both;
|
||
}
|
||
|
||
@keyframes slideDown {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(-50px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
</style>
|