页面样式优化

master
liuyx 2 years ago
parent 071afe3388
commit e4ba339b5c

@ -1,16 +1,25 @@
<template>
<div
class="m-banner animate__animated animate__slideInDown"
:style="{ background: 'url(' + props.bannerUrl + ') center center / cover no-repeat' }"
:style="{ background: 'url(' + bannerUrl + ') center center / cover no-repeat' }"
class="m-banner animate__animated animate__fadeInDown"
></div>
</template>
<script setup>
import { defineProps } from 'vue'
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { getPageByName } from '@/api/page.js'
const props = defineProps({
bannerUrl: String
const route = useRoute()
const bannerUrl = ref('')
onMounted(async () => {
bannerUrl.value = (await getPageByName(route.name)).data.bannerUrl
})
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.animate__fadeInDown {
--animate-duration: 1.7s;
}
</style>

@ -1,90 +1,132 @@
<template>
<el-card class="card-box" v-for="item in blogList" :key="item" shadow="hover">
<el-card class="card-box animate__animated animate__zoomIn" v-for="item in blogList" :key="item">
<div class="blog-item">
<el-row>
<!-- 文章图片 -->
<el-col :span="10">
<router-link :to="'/articles/' + item.id">
<img :src="item.firstPicture" alt="" class="first-picture" />
</router-link>
</el-col>
<!-- 文章标题和简述 -->
<el-col :span="14">
<div class="blog-container">
<router-link :to="'/articles/' + item.id">
<h3>{{ item.title }}</h3>
</router-link>
<div class="description">{{ item.description }}</div>
</div>
</el-col>
</el-row>
<!-- 文章图片 -->
<div class="blog-cover-container">
<router-link :to="'/articles/' + item._id">
<img :src="item.cover" alt="" class="cover" />
</router-link>
</div>
<!-- 文章标题和简述 -->
<div class="blog-content">
<router-link :to="'/articles/' + item._id">
<div class="title">{{ item.title }}</div>
</router-link>
<div class="blog-info">
<span><svg-icon name="calendar" class="icon"></svg-icon>{{ item.createTime }}</span>
<span class="separator">|</span>
<span><svg-icon name="category" class="icon"></svg-icon>{{ item.category }}</span>
<span class="separator">|</span>
<span v-for="tag in item.tagList" :key="tag._id"
><svg-icon name="tag" class="icon"></svg-icon>{{ tag.name }}</span
>
</div>
<div class="description">{{ item.content }}</div>
</div>
</div>
</el-card>
</template>
<script setup>
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
// import { Calendar, Memo, CollectionTag } from '@element-plus/icons-vue'
import { getArticleList } from '../api/article'
const blogList = ref([
{
id: 1,
firstPicture: 'https://w.wallhaven.cc/full/zy/wallhaven-zyxvqy.jpg',
title: '测试',
description: '这是一篇测试文章'
},
{
id: 1,
firstPicture: 'https://w.wallhaven.cc/full/zy/wallhaven-zyxvqy.jpg',
title: '测试',
description: '这是一篇测试文章'
},
{
id: 1,
firstPicture: 'https://w.wallhaven.cc/full/zy/wallhaven-zyxvqy.jpg',
title: '测试',
description: '这是一篇测试文章'
},
{
id: 1,
firstPicture: 'https://w.wallhaven.cc/full/zy/wallhaven-zyxvqy.jpg',
title: '测试',
description: '这是一篇测试文章'
},
{
id: 1,
firstPicture: 'https://w.wallhaven.cc/full/zy/wallhaven-zyxvqy.jpg',
title: '测试',
description: '这是一篇测试文章'
}
])
const blogList = ref([])
onMounted(() => {
getBlogList()
})
const getBlogList = async () => {
const { data } = await getArticleList()
blogList.value = data.articleList
console.log(data)
}
</script>
<style lang="scss" scoped>
.card-box {
margin: 20px 0;
margin-top: 10px;
}
.blog-item {
display: flex;
height: 256px;
// justify-content: center;
align-items: center;
.first-picture {
.blog-cover-container {
overflow: hidden;
width: 70%;
height: 100%;
}
.cover {
width: 100%;
height: 100%;
box-sizing: border-box;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
border-top-left-radius: 11px;
border-bottom-left-radius: 11px;
transform: scale(1);
transition: transform 1s ease 0s;
overflow: hidden;
}
&:hover .first-picture {
&:hover .cover {
transform: scale(1.1);
}
.blog-container {
padding: 20px 20px 20px 40px;
height: 100%;
.blog-content {
padding: 0 40px;
width: 100%;
box-sizing: border-box;
.title {
font-size: 1.35em;
&:hover {
color: #8e8cd8;
}
}
.blog-info {
font-size: 0.85em;
margin: 0.85em 0;
}
.separator {
margin: 0 8px;
font-weight: bold;
font-size: 16px;
}
.icon {
vertical-align: -0.33em;
font-size: 12px;
margin-right: 5px;
}
.description {
margin-top: 15px;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
@media screen and (max-width: 768px) {
.blog-item {
display: block;
height: inherit;
.blog-cover-container {
width: 100vw;
.cover {
border-radius: 11px 11px 0 0 !important;
}
}
.blog-content {
height: 202px;
padding: 20px 30px;
.description {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}

@ -1,90 +1,190 @@
<template>
<header class="header" ref="menu">
<el-menu
:default-active="navActive"
mode="horizontal"
background-color="rgba(0, 0, 0, 0)"
text-color="#000"
active-text-color="#FB3B49"
@select="handleSelect"
router="true"
>
<el-menu-item index="/">首页</el-menu-item>
<el-menu-item index="/tags">标签</el-menu-item>
<el-menu-item index="/categories">分类</el-menu-item>
<el-menu-item index="/archives">归档</el-menu-item>
<el-menu-item index="/about">关于我</el-menu-item>
</el-menu>
<div class="right-header">
<el-input v-model="input" placeholder="Please input" />
<el-button type="primary" :icon="Search" circle />
<div>登录</div>
<header class="header">
<div>
<router-link to="/" class="h-left">BLOG</router-link>
</div>
<div class="menu">
<ul>
<li>
<router-link to="/">
<el-icon class="m-icon"><House /></el-icon>
</router-link>
</li>
<li>
<router-link to="/tags">
<el-icon class="m-icon"><PriceTag /></el-icon>
</router-link>
</li>
<li>
<router-link to="/categories">
<el-icon class="m-icon"><Collection /></el-icon>
</router-link>
</li>
<li>
<router-link to="/archives">
<el-icon class="m-icon"><Files /></el-icon>
</router-link>
</li>
<li>
<router-link to="/about">
<el-icon class="m-icon"><User /></el-icon>
</router-link>
</li>
<div class="bottom-strip"></div>
</ul>
</div>
<div class="mobile-menu" @click="mobileShow">
<svg-icon name="menu"></svg-icon>
</div>
</header>
<!-- 移动端展示 -->
<el-drawer v-model="mobileDrawer" size="60%" :show-close="false" :with-header="false">
<h1 class="drawer-header">BLOG</h1>
<div class="drawer-menu">
<router-link to="/">
<el-icon class="drawer-menu-icon"><House /></el-icon>
</router-link>
<router-link to="/tags">
<el-icon class="drawer-menu-icon"><PriceTag /></el-icon>
</router-link>
<router-link to="/categories">
<el-icon class="drawer-menu-icon"><Collection /></el-icon>
</router-link>
<router-link to="/archives">
<el-icon class="drawer-menu-icon"><Files /></el-icon>
</router-link>
<router-link to="/about">
<el-icon class="drawer-menu-icon"><User /></el-icon>
</router-link>
</div>
</el-drawer>
</template>
<script setup>
import { Search } from '@element-plus/icons-vue'
import { ref, watch, onMounted } from 'vue'
import { useRouter } from 'vue-router'
const menu = ref()
const navActive = ref('/')
const router = useRouter()
import { House, PriceTag, Collection, Files, User } from '@element-plus/icons-vue'
import { ref } from 'vue'
// 使el-menu
watch(router.currentRoute, () => {
navActive.value = router.currentRoute.value.path
console.log(navActive.value)
})
const mobileDrawer = ref(false)
onMounted(() => {
//
window.addEventListener('scroll', scrollTop, true)
})
//
const scrollTop = () => {
const scroll = document.documentElement.scrollTop || document.body.scrollTop
if (scroll > 0) {
menu.value.style.backgroundColor = '#fff'
menu.value.style.boxShadow = '0px 2px #eee'
} else {
menu.value.style.backgroundColor = 'rgba(0, 0, 0, 0)'
menu.value.style.boxShadow = 'none'
}
const mobileShow = () => {
mobileDrawer.value = true
}
// onMounted(() => {
// //
// window.addEventListener('scroll', scrollTop, true)
// })
// //
// const scrollTop = () => {
// const scroll = document.documentElement.scrollTop || document.body.scrollTop
// if (scroll > 0) {
// menu.value.style.backgroundColor = '#fff'
// menu.value.style.boxShadow = '0px 2px #eee'
// } else {
// menu.value.style.backgroundColor = 'rgba(0, 0, 0, 0)'
// menu.value.style.boxShadow = 'none'
// }
// }
</script>
<style lang="scss" scoped>
.header {
padding: 0 40px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
// box-shadow: 0px 2px #eee;
// background-color: rgba(0, 0, 0, 0);
padding: 0 30px;
box-sizing: border-box;
position: fixed;
position: absolute;
top: 0;
z-index: 999;
transition-duration: 0.7s;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);
}
.right-header {
display: flex;
width: 40%;
align-items: center;
justify-content: end;
.el-input {
width: 50%;
.h-left {
width: 60%;
font: 100 30px '优设标题黑';
color: #eee;
}
.menu {
// width: 100%;
height: 50px;
position: relative;
top: 0;
& ul {
width: 100%;
height: 100%;
display: flex;
align-items: center;
}
& ul li {
width: 100%;
text-align: center;
list-style: none;
}
& ul li a {
color: #eee;
font: 100 20px '优设标题黑';
display: block;
width: 100%;
height: 100%;
margin-right: 30px;
}
& ul .bottom-strip {
position: absolute;
bottom: 0;
left: 0;
width: calc((100% / 5) * 1);
height: 5px;
border-radius: 2px;
transition: 0.45s;
}
& ul li:nth-child(1):hover ~ .bottom-strip {
left: calc(100% / 5 * 0);
background-color: rgb(250, 190, 250);
}
& ul li:nth-child(2):hover ~ .bottom-strip {
left: calc(100% / 5 * 1);
background-color: red;
}
& ul li:nth-child(3):hover ~ .bottom-strip {
left: calc(100% / 5 * 2);
background-color: #d18df8;
}
& ul li:nth-child(4):hover ~ .bottom-strip {
left: calc(100% / 5 * 3);
background-color: #ffb1b1;
}
& ul li:nth-child(5):hover ~ .bottom-strip {
left: calc(100% / 5 * 4);
background-color: #8da1f8;
}
}
.el-menu {
width: 60%;
.mobile-menu {
display: none;
}
.el-menu-item {
font-size: 17px;
font-weight: 600;
.drawer-header {
text-align: center;
margin-bottom: 20px;
}
.drawer-menu {
& a {
display: block;
padding: 10px 10px;
font-size: 18px;
}
.drawer-menu-icon {
margin-right: 1.2em;
vertical-align: -0.13em;
}
}
@media screen and (max-width: 768px) {
.menu {
display: none;
}
.mobile-menu {
display: block;
}
}
</style>

@ -0,0 +1,99 @@
<!--
* @Author: liuyx 1517482303@qq.com
* @Date: 2022-11-11 09:30:01
* @LastEditTime: 2022-12-19 07:42:44
* @Description: 主页右侧组件用于展示网站信息
-->
<template>
<div class="user-info">
<el-card class="animate__animated animate__zoomIn">
<!-- 头像 -->
<div class="avatar">
<el-avatar :size="100" :src="siteInfo.avatar" />
</div>
<!-- 名称 -->
<h2>{{ siteInfo.author }}</h2>
<!-- 简述 -->
<p>{{ siteInfo.intro }}</p>
<!-- 分类统计 -->
<div class="classification">
<div class="class-item">
<router-link to="/tags">
<div>标签</div>
<div class="class-item-nums">{{ tagNum }}</div>
</router-link>
</div>
<div class="class-item">
<router-link to="/categories">
<div>分类</div>
<div class="class-item-nums">{{ categoryNum }}</div>
</router-link>
</div>
<div class="class-item">
<router-link to="/archives">
<div>归档</div>
<div class="class-item-nums">{{ archiveNum }}</div>
</router-link>
</div>
</div>
<!-- 一些图标 -->
<div class="icons">
<a :href="siteInfo.github"><svg-icon name="github"></svg-icon></a>&nbsp;
<a :href="siteInfo.gitee"><svg-icon name="gitee"></svg-icon></a>
</div>
</el-card>
<el-card class="notice animate__animated animate__zoomIn">
<h3 style="margin-bottom: 10px"><svg-icon name="notice" /> 公告</h3>
{{ siteInfo.notice }}
</el-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { getSiteInfo } from '../api/site'
const siteInfo = ref({})
const tagNum = ref(0)
const categoryNum = ref(0)
const archiveNum = ref(0)
onMounted(() => {
getInfo()
})
const getInfo = async () => {
const { data } = await getSiteInfo()
console.log(data)
siteInfo.value = data
}
</script>
<style lang="scss" scoped>
.user-info {
padding: 10px;
text-align: center;
position: sticky;
top: 0px;
.avatar {
}
.classification {
display: flex;
padding: 20px 10px;
box-sizing: border-box;
.class-item {
width: 33.3%;
.class-item-nums {
line-height: 40px;
height: 40px;
}
}
}
.icons {
margin-top: 10px;
}
.notice {
text-align: left;
}
}
</style>

@ -1,82 +0,0 @@
<template>
<el-card shadow="hover" class="user-info">
<!-- 头像 -->
<div class="avatar">
<el-avatar :size="100" :src="userInfo.avatar" />
</div>
<!-- 名称 -->
<h2>{{ userInfo.name }}</h2>
<!-- 简述 -->
<p>{{ userInfo.description }}</p>
<!-- 分类统计 -->
<div class="classification">
<div class="class-item">
<router-link to="/tags">
<div>标签</div>
<div class="class-item-nums">{{ userInfo.tags }}</div>
</router-link>
</div>
<div class="class-item">
<router-link to="/categories">
<div>分类</div>
<div class="class-item-nums">{{ userInfo.categories }}</div>
</router-link>
</div>
<div class="class-item">
<router-link to="/archives">
<div>归档</div>
<div class="class-item-nums">{{ userInfo.archives }}</div>
</router-link>
</div>
</div>
<!-- 一些图标 -->
<div class="icons">
<a :href="userInfo.github"><svg-icon name="github"></svg-icon></a>&nbsp;
<a :href="userInfo.gitee"><svg-icon name="gitee"></svg-icon></a>
</div>
</el-card>
</template>
<script setup>
import { ref } from 'vue'
const userInfo = ref({
name: 'Liuyx',
avatar: 'https://liuyxcc.github.io/img/avatar.png',
description: '抓住现在,做好自己',
tags: 0,
categories: 0,
archives: 0,
github: 'https://github.com/liuyxcc',
gitee: 'https://gitee.com/liuyxcc'
})
</script>
<style lang="scss" scoped>
.el-card {
margin: 20px 0;
}
.user-info {
padding: 10px;
text-align: center;
position: sticky;
top: 10px;
.avatar {
}
.classification {
display: flex;
padding: 20px 10px;
box-sizing: border-box;
.class-item {
width: 33.3%;
.class-item-nums {
line-height: 40px;
height: 40px;
}
}
}
.icons {
margin-top: 10px;
}
}
</style>

@ -1,28 +1,22 @@
<template>
<Banner :bannerUrl="data.bannerUrl" />
<Banner />
<div class="m-content">
<el-card shadow="hover" class="aboutme">
<v-md-preview :text="blog"></v-md-preview>
<v-md-preview :text="content"></v-md-preview>
</el-card>
</div>
</template>
<script setup>
import Banner from '@/components/Banner.vue'
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { getAboutContent } from '../../api/about'
const data = ref({
bannerUrl: 'https://typora-lyx.oss-cn-guangzhou.aliyuncs.com/typora/wallhaven-p931d9.png'
})
const blog = `
## Welcome!
const content = ref('') //
Hello欢迎来到我的个人博客
~~~js
console.log('Hello World')
~~~
`
onMounted(async () => {
content.value = (await getAboutContent()).data.content
})
</script>
<style lang="scss" scoped>

@ -1,17 +1,43 @@
<template>
<Banner :bannerUrl="data.bannerUrl" />
<Banner />
<div class="m-content">
<el-card shadow="hover">Archives</el-card>
<el-card>
<el-timeline>
<el-timeline-item
v-for="article in articleList"
:key="article._id"
:timestamp="article.createTime"
type="primary"
>
<router-link :to="'/articles/' + article._id">
{{ article.title }}
</router-link>
</el-timeline-item>
</el-timeline>
</el-card>
</div>
</template>
<script setup>
import Banner from '@/components/Banner.vue'
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { getArticleList } from '@/api/article.js'
const data = ref({
bannerUrl: 'https://typora-lyx.oss-cn-guangzhou.aliyuncs.com/typora/wallhaven-1p38v3.png'
const articleList = ref([])
onMounted(async () => {
const { data } = await getArticleList()
articleList.value = data.articleList
// console.log(articleList.value)
})
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.el-timeline {
padding: 20px 40px;
font-size: 17px;
.el-timeline-item {
margin-top: 10px;
}
}
</style>

@ -1,66 +1,49 @@
<template>
<div class="m-content">
<el-row :gutter="20">
<el-col :span="18">
<el-card shadow="hover" class="article">
<v-md-preview :text="blog" ref="preview"></v-md-preview>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" class="directory">
<h3>目录</h3>
<div
:style="{ background: 'url(' + article.cover + ') center center / cover no-repeat' }"
class="m-banner animate__animated animate__fadeInDown"
></div>
<div class="m-content article-container">
<div class="article animate__animated animate__fadeInUp">
<el-card>
<v-md-preview :text="article.content" ref="preview"></v-md-preview>
</el-card>
</div>
<div class="dir-container animate__animated animate__fadeInUp">
<div class="directory">
<el-card>
<h3 style=""><svg-icon name="dir" class="dir-icon"></svg-icon> </h3>
<div
v-for="anchor in directory"
:key="anchor"
:style="{ padding: `10px 0 10px ${anchor.indent * 20}px` }"
:style="{ padding: `10px 0 10px ${(anchor.indent * 20) / 1.5 + 10}px` }"
@click="handleAnchorClick(anchor)"
:class="{ active: currentAhchor === anchor }"
>
<a style="cursor: pointer">{{ anchor.title }}</a>
<a class="anchor">{{ anchor.title }}</a>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const blog = `
## 二级标题
这是一篇测试文章~
这是一篇测试文章~
这是一篇测试文章~
这是一篇测试文章~
这是一篇测试文章~
### 三级标题
1. a
2. b
3. c
#### 四级标题
~~~js
console.log('这是一篇测试文章~')
~~~
## 实现目录功能
> v-md-editor可太好用了完美
::: tip
居然还有tip功能Amazing
:::
`
import { useRoute } from 'vue-router'
import { getArticleById } from '@/api/article'
const article = ref({})
const route = useRoute()
const preview = ref()
const directory = ref([])
const currentAhchor = ref({}) // anchor
onMounted(() => {
console.log(preview.value.$el)
const anchors = preview.value.$el.querySelectorAll('h1,h2,h3,h4,h5,h6')
onMounted(async () => {
await getArticle(route.params.articleId) // await
const anchors = preview.value.$el.querySelectorAll('h1, h2, h3, h4, h5, h6')
console.log(preview.value)
const titles = Array.from(anchors).filter((title) => !!title.innerText.trim())
if (!titles.length) {
directory.value = []
@ -74,12 +57,16 @@ onMounted(() => {
lineIndex: el.getAttribute('data-v-md-line'),
indent: hTags.indexOf(el.tagName)
}))
console.log(directory.value)
})
const getArticle = async (id) => {
const { data } = await getArticleById(id)
article.value = data
}
const handleAnchorClick = (anchor) => {
const { lineIndex } = anchor
currentAhchor.value = anchor
const heading = preview.value.$el.querySelector(`[data-v-md-line="${lineIndex}"]`)
@ -87,18 +74,56 @@ const handleAnchorClick = (anchor) => {
preview.value.scrollToTarget({
target: heading,
scrollContainer: window,
top: 60
top: 25
})
}
console.log(heading.scrollTop)
}
</script>
<style lang="scss" scoped>
.article {
margin: 20px 0;
.article-container {
display: flex;
.article {
width: 75%;
margin-right: 20px;
}
.dir-container {
width: 25%;
.directory {
position: sticky;
top: 10px;
& h3 {
padding-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid #000;
.dir-icon {
vertical-align: -0.33em;
}
}
.anchor {
cursor: pointer;
}
.active {
background-color: #00c4b6;
transition: all 1s ease-in-out;
}
}
}
}
@media screen and (max-width: 768px) {
.article-container {
display: block;
.article {
width: 100%;
}
.dir-container {
// width: 100%;
display: none;
}
}
}
.directory {
position: sticky;
top: 10px;
.animate__fadeInDown {
--animate-duration: 1.7s;
}
</style>

@ -1,16 +1,34 @@
<template>
<Banner :bannerUrl="data.bannerUrl" />
<Banner />
<div class="m-content">
<el-card shadow="hover">Categories</el-card>
<el-card shadow="hover">
<div class="m-tc-container">
<h1 class="m-tc-title">分类 - {{ categoryList.length }}</h1>
<div class="m-tc-content">
<router-link
v-for="category in categoryList"
:key="category._id"
:style="{ 'font-size': Math.floor(Math.random() * 10) + 18 + 'px' }"
:to="'/about'"
>
{{ category.name }}
</router-link>
</div>
</div>
</el-card>
</div>
</template>
<script setup>
import Banner from '@/components/Banner.vue'
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { getCategoryList } from '../../api/category'
const data = ref({
bannerUrl: 'https://typora-lyx.oss-cn-guangzhou.aliyuncs.com/typora/wallhaven-kxw9o1.png'
const categoryList = ref([])
onMounted(async () => {
const { data } = await getCategoryList()
categoryList.value = data
})
</script>

@ -1,27 +1,278 @@
<!--
* @Author: liuyx 1517482303@qq.com
* @Date: 2022-11-10 08:03:12
* @LastEditTime: 2022-12-19 07:44:43
* @Description: 主页
-->
<template>
<div class="home-banner animate__animated animate__fadeIn"></div>
<div class="m-content">
<el-row :gutter="20">
<el-col :span="18">
<BlogList />
</el-col>
<el-col :span="6"
><div class="grid-content ep-bg-purple" />
<UserInfo />
</el-col>
</el-row>
<div
class="home-banner animate__animated animate__fadeIn animate__slow"
:style="{ background: 'url(' + bannerUrl + ') center center / cover no-repeat' }"
>
<h1 class="site-name">{{ siteName }}</h1>
</div>
<div class="home-content">
<div class="article-list">
<el-card
class="card-box animate__animated animate__zoomIn"
v-for="item in blogList"
:key="item"
>
<div class="article-item">
<!-- 文章图片 -->
<div class="cover-container">
<router-link :to="'/articles/' + item._id">
<img :src="item.cover" alt="" class="cover" />
</router-link>
</div>
<!-- 文章标题和简述 -->
<div class="article-content">
<router-link :to="'/articles/' + item._id">
<div class="title">{{ item.title }}</div>
</router-link>
<div class="article-info">
<span><svg-icon name="calendar" class="icon"></svg-icon>{{ item.createTime }}</span>
<span class="separator">|</span>
<span><svg-icon name="category" class="icon"></svg-icon>{{ item.category }}</span>
<span class="separator">|</span>
<span v-for="tag in item.tagList" :key="tag._id"
><svg-icon name="tag" class="icon"></svg-icon>{{ tag.name }}</span
>
</div>
<div class="description">{{ item.content }}</div>
</div>
</div>
</el-card>
</div>
<div class="site-info">
<div class="info-container">
<el-card class="animate__animated animate__zoomIn">
<!-- 头像 -->
<div class="avatar">
<el-avatar :size="100" :src="siteInfo.avatar" />
</div>
<!-- 名称 -->
<h2>{{ siteInfo.author }}</h2>
<!-- 简述 -->
<p>{{ siteInfo.intro }}</p>
<!-- 分类统计 -->
<div class="classification">
<div class="class-item">
<router-link to="/tags">
<div>标签</div>
<div class="class-item-nums">{{ tagNum }}</div>
</router-link>
</div>
<div class="class-item">
<router-link to="/categories">
<div>分类</div>
<div class="class-item-nums">{{ categoryNum }}</div>
</router-link>
</div>
<div class="class-item">
<router-link to="/archives">
<div>归档</div>
<div class="class-item-nums">{{ archiveNum }}</div>
</router-link>
</div>
</div>
<!-- 一些图标 -->
<div class="icons">
<a :href="siteInfo.github"><svg-icon name="github"></svg-icon></a>&nbsp;
<a :href="siteInfo.gitee"><svg-icon name="gitee"></svg-icon></a>
</div>
</el-card>
<el-card class="notice animate__animated animate__zoomIn">
<h3 style="margin-bottom: 10px"><svg-icon name="notice" /> 公告</h3>
{{ siteInfo.notice }}
</el-card>
</div>
</div>
</div>
</template>
<script setup>
import BlogList from '../../components/BlogList.vue'
import UserInfo from '../../components/UserInfo.vue'
import { ref, onMounted } from 'vue'
import { getSiteInfo } from '../../api/site'
import { getArticleList } from '../../api/article'
import { getPageByName } from '@/api/page.js'
const siteName = ref('')
const blogList = ref([])
const siteInfo = ref({})
const tagNum = ref(0)
const categoryNum = ref(0)
const archiveNum = ref(0)
const bannerUrl = ref('')
onMounted(async () => {
const { data } = await getSiteInfo()
siteName.value = data.siteName
bannerUrl.value = (await getPageByName('首页')).data.bannerUrl
getBlogList()
getInfo()
})
const getBlogList = async () => {
const { data } = await getArticleList()
blogList.value = data.articleList
console.log(data)
}
const getInfo = async () => {
const { data } = await getSiteInfo()
console.log(data)
siteInfo.value = data
}
</script>
<style lang="scss" scoped>
.home-banner {
background: url('https://typora-lyx.oss-cn-guangzhou.aliyuncs.com/typora/wallhaven-x6l5vl.jpg')
center center / cover no-repeat;
// background: url('http://cdn.liuyx.cc/wallhaven-m3dm1k.png') center center / cover no-repeat;
height: 100vh;
position: relative;
display: flex;
justify-content: center;
align-items: center;
.site-name {
position: absolute;
top: 35%;
color: #eee;
letter-spacing: 5px;
}
}
.home-content {
display: flex;
margin: 20px auto;
}
@media screen and (min-width: 960px) {
.home-content {
width: 80%;
.article-list {
width: 75%;
padding-right: 10px;
}
.site-info {
width: 25%;
}
}
}
@media screen and (max-width: 768px) {
.home-content {
width: 100%;
display: block;
padding: 10px;
box-sizing: border-box;
}
}
.card-box {
margin-top: 10px;
}
.article-item {
display: flex;
height: 256px;
// justify-content: center;
align-items: center;
.cover-container {
overflow: hidden;
width: 70%;
height: 100%;
}
.cover {
width: 100%;
height: 100%;
box-sizing: border-box;
border-top-left-radius: 11px;
border-bottom-left-radius: 11px;
transform: scale(1);
transition: transform 1s ease 0s;
overflow: hidden;
}
&:hover .cover {
transform: scale(1.1);
}
.article-content {
padding: 0 40px;
width: 100%;
box-sizing: border-box;
.title {
font-size: 1.35em;
&:hover {
color: #8e8cd8;
}
}
.article-info {
font-size: 0.85em;
margin: 0.85em 0;
}
.separator {
margin: 0 8px;
font-weight: bold;
font-size: 16px;
}
.icon {
vertical-align: -0.33em;
font-size: 12px;
margin-right: 5px;
}
.description {
margin-top: 15px;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
@media screen and (max-width: 768px) {
.article-item {
display: block;
height: inherit;
.cover-container {
width: 100vw;
.cover {
border-radius: 11px 11px 0 0 !important;
}
}
.article-content {
height: 202px;
padding: 20px 30px;
.description {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.info-container {
padding: 10px;
text-align: center;
position: sticky;
top: 10px;
.avatar {
}
.classification {
display: flex;
padding: 20px 10px;
box-sizing: border-box;
.class-item {
width: 33.3%;
.class-item-nums {
line-height: 40px;
height: 40px;
}
}
}
.icons {
margin-top: 10px;
}
.notice {
text-align: left;
}
}
</style>

@ -1,16 +1,34 @@
<template>
<Banner :bannerUrl="data.bannerUrl" />
<Banner />
<div class="m-content">
<el-card shadow="hover">Tags</el-card>
<el-card>
<div class="m-tc-container">
<h1 class="m-tc-title">标签 - {{ tagList.length }}</h1>
<div class="m-tc-content">
<router-link
v-for="tag in tagList"
:key="tag._id"
:style="{ 'font-size': Math.floor(Math.random() * 10) + 18 + 'px' }"
:to="'/about'"
>
{{ tag.name }}
</router-link>
</div>
</div>
</el-card>
</div>
</template>
<script setup>
import Banner from '@/components/Banner.vue'
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { getTagList } from '../../api/tag'
const data = ref({
bannerUrl: 'https://typora-lyx.oss-cn-guangzhou.aliyuncs.com/typora/wallhaven-kxw3p1.jpg'
const tagList = ref([])
onMounted(async () => {
const { data } = await getTagList()
tagList.value = data
})
</script>

Loading…
Cancel
Save