文件操作 - index.vue
返回文件管理
返回主菜单
删除本文件
文件: /var/www/OLD/pages/index.vue
编辑文件内容
<script lang="ts" setup> import Swiper from 'swiper'; import 'swiper/css'; import { Navigation, Scrollbar } from 'swiper/modules'; const { t, tm, rt } = useI18n(); useHead({ title: t('home.head.title'), }); const needList = tm('home.need.list') as string[]; const reviewsSlider = ref<HTMLElement>(); const reviews = tm('home.reviews.list') as { stars: number; name: string; date: string; text: string; }[]; onMounted(() => { if (reviewsSlider.value) { const nav = reviewsSlider.value .closest('.container') ?.querySelector('.slider-nav'); new Swiper(reviewsSlider.value, { speed: 400, slidesPerView: 'auto', modules: [Navigation, Scrollbar], breakpoints: { 0: { spaceBetween: 12, }, 1024: { spaceBetween: 20, }, }, navigation: { prevEl: nav?.querySelector('.slider-arrow-prev') as HTMLElement, nextEl: nav?.querySelector('.slider-arrow-next') as HTMLElement, }, scrollbar: { el: nav?.querySelector('.slider-scrollbar') as HTMLElement, draggable: true, }, }); } }); </script> <template> <main class="page-main"> <section class="promo"> <div class="container"> <h1 class="promo-title">{{ $t('home.promo.title') }}</h1> <div class="promo-desc">{{ $t('home.promo.desc') }}</div> <FormStart></FormStart> <TheCarriers></TheCarriers> </div> </section> <SectionSteps></SectionSteps> <section class="need section"> <div class="container"> <h2 class="section-title">{{ $t('home.need.title') }}</h2> <div class="need-body"> <div class="need-list"> <div v-for="(item, index) in needList" :key="index" class="need-item h4" > {{ rt(item) }} </div> </div> <div class="need-img"> <img src="/img/need.svg" alt="" /> </div> </div> <div class="need-note"> (<span>{{ $t('home.need.note.title') }}</span> {{ $t('home.need.note.desc') }}) </div> </div> </section> <section class="reviews section"> <div class="container"> <div class="reviews-head"> <h2 class="reviews-title">{{ $t('home.reviews.title') }}</h2> <div class="reviews-desc">{{ $t('home.reviews.desc') }}</div> </div> <div ref="reviewsSlider" class="reviews-slider swiper" > <div class="swiper-wrapper"> <div v-for="(item, index) in reviews" :key="index" class="reviews-slide swiper-slide" > <div class="reviews-slide-head"> <AppIcon name="quote"></AppIcon> <div class="reviews-slide-stars"> <AppIcon v-for="i in 5" :key="i" :class="{ active: item.stars >= i }" name="star" ></AppIcon> </div> </div> <div class="reviews-slide-text"> {{ rt(item.text) }} </div> <div class="reviews-slide-foot"> <div class="reviews-slide-name">{{ rt(item.name) }}</div> <div class="reviews-slide-date">{{ rt(item.date) }}</div> </div> </div> </div> </div> <div class="slider-nav"> <div class="slider-scrollbar"></div> <div class="slider-arrows"> <button class="slider-arrow slider-arrow-prev" aria-label="←" > <AppIcon name="arrow-left"></AppIcon> </button> <button class="slider-arrow slider-arrow-next" aria-label="→" > <AppIcon name="arrow-right"></AppIcon> </button> </div> </div> </div> </section> <section class="ready section"> <div class="container"> <div class="ready-body"> <div class="ready-content"> <h2 class="ready-title">{{ $t('home.ready.title') }}</h2> <FormStart></FormStart> </div> </div> </div> </section> </main> </template> <style lang="less" scoped> .page-main { padding-top: 0; } .promo { padding: calc(220px - var(--header-height)) 0 44px; @media @md { padding: calc(142px - var(--header-height)) 0 50px; } .container { display: flex; flex-direction: column; gap: 56px; @media @md { gap: 36px; } } .carriers { margin-top: 32px; @media @md { margin-top: 24px; } } } .promo-title { text-align: center; max-width: 998px; margin: 0 auto; } .promo-desc { text-align: center; max-width: 646px; margin: 0 auto; letter-spacing: -0.02em; @media @md_ { font-size: 20px; font-weight: 500; } } .need-body { display: flex; align-items: center; gap: 32px; justify-content: space-between; @media @md { flex-direction: column; gap: 32px; } } .need-list { display: flex; flex-direction: column; gap: 36px; width: 668px; min-width: 0; @media @md { width: 100%; gap: 24px; } } .need-item { --padding-left: 40px; position: relative; padding-left: var(--padding-left); opacity: 0.32; transition: opacity 0.4s; @media @md { --padding-left: 32px; } &:hover { opacity: 1; &:before { opacity: 1; } } &:before { content: ''; --size: 8px; position: absolute; width: var(--size); aspect-ratio: 1; border-radius: 50%; transition: opacity 0.4s; left: calc(0.5 * var(--padding-left) - 0.5 * var(--size)); top: calc(0.5lh - 0.5 * var(--size)); background-color: #056dae; opacity: 0; } } .need-img { display: flex; width: 566px; min-width: 0; @media @md { max-width: 100%; } } .need-note { margin-top: 20px; text-align: center; font-weight: 500; line-height: 1.25; color: #474747; @media @md_ { font-size: 18px; margin-top: 64px; } span { color: #6483ab; font-weight: 600; } } .reviews-head { display: flex; gap: 16px 24px; justify-content: space-between; margin-bottom: 48px; @media @md { margin-bottom: 36px; flex-direction: column; } } .reviews-desc { color: #393939; letter-spacing: -0.02em; @media @md_ { max-width: 266px; text-align: right; } } .reviews-slider { overflow: visible; } .reviews-slide { width: 528px; padding: 40px; border-radius: 12px; background-color: #f2f6fd; display: flex; flex-direction: column; gap: 40px; height: unset; @media @md { width: 286px; gap: 36px; padding: 24px; } } .reviews-slide-head { display: flex; gap: 16px; justify-content: space-between; align-items: flex-start; @media @md { margin-bottom: 8px; } & > svg { --size: 42px; color: #056dae; @media @md { --size: 26px; } } } .reviews-slide-stars { display: flex; gap: 2px; svg { --size: 22px; @media @md { --size: 18px; } &.active { color: #ffb800; } } } .reviews-slide-text { color: #323232; font-size: 20px; letter-spacing: -0.04em; font-weight: 500; @media @md { font-size: 18px; } } .reviews-slide-foot { display: flex; justify-content: space-between; gap: 16px; margin-top: auto; @media @md_ { padding-top: 8px; } } .reviews-slide-name { font-weight: 600; color: #056dae; letter-spacing: -0.016em; line-height: 1.1; @media @md_ { font-size: 18px; } } .reviews-slide-date { color: #939393; letter-spacing: -0.0625em; line-height: 1.2; @media @md { font-size: 15px; } } .slider-nav { margin-top: 40px; display: flex; gap: 28px; align-items: center; @media @md { margin-top: 20px; flex-direction: column; } } .slider-scrollbar { flex: auto; height: 2px; background-color: #efefef; min-width: 48px; @media @md { width: 100%; margin: 16px 0; } :deep(.swiper-scrollbar-drag) { background-color: #b2b2b2; height: 100%; } } .slider-arrows { flex: none; display: flex; gap: 24px; } .slider-arrow { display: flex; transition: color 0.4s; color: #5e5e5e; transition: color 0.4s; &:hover { color: #000; } &:active { color: #5c4c4c; } &.swiper-button-disabled { color: #d5d5d5; } svg { --size: 32px; } } .ready-body { padding: 64px 60px; border-radius: 15px; background: #6482ab url('/img/ready-bg.png') right bottom no-repeat; background-size: 768px 480px; @media @md { padding: 28px 20px; background-size: 280px 174px; } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx) { background-image: url('/img/ready-bg@2x.png'); } } .ready-content { max-width: 528px; .form-start { background-color: fade(@white, 25%); @media @sm_ { max-width: 504px; grid-template-columns: 1fr 1fr; gap: 20px 12px; margin: 0; padding: 20px; } } :deep(.form-start-submit) { @media @sm_ { grid-column: span 2; } } } .ready-title { font-size: 54px; color: @white; margin-bottom: 44px; @media @md { font-size: 36px; margin-bottom: 20px; } } </style>
修改文件时间
将文件时间修改为当前时间的前一年
删除文件