完成详情页的展示

This commit is contained in:
LittleBoy 2022-05-12 10:55:46 +08:00
parent 1d792e9f9a
commit 0847b0823a
6 changed files with 305 additions and 96 deletions

31
package-lock.json generated
View File

@ -478,6 +478,11 @@
"ms": "2.0.0"
}
},
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og=="
},
"decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-3.3.0.tgz",
@ -635,6 +640,11 @@
"to-regex-range": "^5.0.1"
}
},
"filter-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz",
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="
},
"finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz",
@ -1252,6 +1262,17 @@
"side-channel": "^1.0.4"
}
},
"query-string": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.1.tgz",
"integrity": "sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==",
"requires": {
"decode-uri-component": "^0.2.0",
"filter-obj": "^1.1.0",
"split-on-first": "^1.0.0",
"strict-uri-encode": "^2.0.0"
}
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
@ -1462,6 +1483,11 @@
"resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
},
"split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz",
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
},
"sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.1.tgz",
@ -1472,6 +1498,11 @@
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
},
"strict-uri-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",

View File

@ -14,6 +14,7 @@
"element-ui": "^2.15.8",
"express": "^4.18.1",
"mysql": "^2.18.1",
"query-string": "^7.1.1",
"vue": "^3.2.33"
},
"devDependencies": {

158
public/assets/style.css Normal file
View File

@ -0,0 +1,158 @@
* {
margin: 0;
padding: 0;
}
a{
text-decoration: none;
color:#333;
}
.show-flex {
display: flex;
}
header {
background-color: black;
color: #fff;
line-height: 60px;
height: 60px;
}
.logo {
font-size: 30px;
flex: 1;
}
.site-nav {
text-align: right;
}
.site-nav a {
color: #fff;
text-decoration: none;
display: inline-block;
padding: 0 20px;
font-size: 18px;
}
.site-nav a:hover {
color: #333;
background-color: aqua;
}
.container {
width: 900px;
max-width: 90%;
margin: auto;
}
.main {
margin: 30px auto;
}
.article-item {
margin-bottom: 30px;
border-bottom: dashed 1px #ccc;
padding-bottom: 30px;
}
.article-item .image img {
width: 100px;
height: 100px;
display: block;
border-radius: 5px;
}
.article-item .info {
flex: 1;
margin-left: 10px;
}
.info .title {
height: 30px;
overflow: hidden;
line-height: 30px;
text-overflow: ellipsis;
}
.info .title a{
display: block;
}
.info .desc {
color: #666;
font-size: 14px;
height: 40px;
line-height: 20px;
overflow: hidden;
}
.info .ext {
height: 30px;
line-height: 30px;
text-align: right;
color: #666;
font-size: 12px;
}
.search-input {
width: 200px;
}
.search-input .el-input__inner {
border-radius: 50px;
}
/* 详情页 */
#artilce-info{
color:#666;
font-size:14px;
margin:20px 0;
}
#artilce-info div{
margin-right: 10px;
}
#article-content{
line-height: 30px;
}
#article-content p{
margin: 10px 0;
}
@media screen and (max-width: 500px) {
header {
padding: 0 20px;
}
.container {
max-width: 100%;
}
.search-input {
position: absolute;
top: 60px;
width: auto;
left: 20px;
right: 20px;
}
.site-nav a {
padding: 0 10px;
}
.main {
padding-top: 50px;
}
.article-item {
padding: 15px;
margin-bottom: 0;
}
.article-item:hover,
.article-item:active {
background-color: rgba(0, 0, 0, 0.1);
}
.article-item .info .ext {
text-align: left;
}
}

88
public/detail.html Normal file
View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="./assets/style.css">
</head>
<body>
<div id="detail">
<header>
<div class="container show-flex">
<div class="logo">我的博客</div>
<nav class="site-nav">
<a href="./">首页</a>
<a href="./login.html">登录</a>
</nav>
</div>
</header>
<div class="main container">
<h1 id="article-title">{{a.title}}</h1>
<div id="artilce-info" class="show-flex">
<div class="category">分类:{{a.category}}</div>
<div class="time">发布于:{{a.publish_time}}</div>
<div class="count">
阅读数({{a.view_count}})
评论数({{a.comment_count}})
</div>
</div>
<div id="article-content" v-html="a.content"></div>
</div>
</div>
<!-- 引入vue库 -->
<script src="./vue/dist/vue.js"></script>
<script src="./element-ui/lib/index.js"></script>
<script src="./modules/dayjs.min.js"></script>
<script type="module">
// import Vue from './vue/dist/vue.esm-browser.js'
// vue 通过 Vue.createApp(选项)创建vue实例
import request from './modules/request.js'
import qs from './modules/qs.js'
new Vue({
el: '#detail', // 设置挂载对象
data() {
return {
a: {
"id": 1,
"title": "",
"cover": "",
"publish_time": "",
"description": "",
"content": "",
"category": "",
"view_count": 0,
"comment_count": 0,
"status": 1
}
}
},
async created() {
const params = qs.parse(location.search);
if (!params.id) {
alert("文章的编号不正确")
return;
}
const id = params.id;
const articleList = await request('./api/article/web/detail', { id });
if (articleList.length != 1) {
alert('文章数据有问题');
return;
}
this.a = articleList[0];
},
methods: {
formatDate(time) {
return dayjs(time).format('YYYY-MM-DD HH:mm')
},
}
})
</script>
</body>
</html>

View File

@ -7,101 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./element-ui/lib/theme-chalk/index.css">
<style>
* {
margin: 0;
padding: 0;
}
.show-flex {
display: flex;
}
header {
background-color: black;
color: #fff;
line-height: 60px;
height: 60px;
}
.logo {
font-size: 30px;
flex: 1;
}
.site-nav {
text-align: right;
}
.site-nav a {
color: #fff;
text-decoration: none;
display: inline-block;
padding: 0 20px;
font-size: 18px;
}
.site-nav a:hover {
color: #333;
background-color: aqua;
}
.container {
width: 900px;
max-width: 90%;
margin: auto;
}
.main {
margin: 30px auto;
}
.article-item {
margin-bottom: 30px;
border-bottom: dashed 1px #ccc;
padding-bottom: 30px;
}
.article-item .image img {
width: 100px;
height: 100px;
display: block;
border-radius: 5px;
}
.article-item .info {
flex: 1;
margin-left: 10px;
}
.info .title {
height: 30px;
}
.info .desc {
color: #666;
font-size: 14px;
height: 40px;
line-height: 20px;
}
.info .ext {
height: 30px;
line-height: 30px;
text-align: right;
color: #666;
font-size: 12px;
}
.search-input {
width: 200px;
}
.search-input .el-input__inner {
border-radius: 50px;
}
</style>
<link rel="stylesheet" href="./assets/style.css">
</head>
<body>
@ -125,7 +31,9 @@
<img :src="a.cover">
</div>
<div class="info">
<h3 class="title">{{a.title}}</h3>
<h3 class="title">
<a :href="'detail.html?id=' + a.id">{{a.title}}</a>
</h3>
<p class="desc">{{a.description}}</p>
<div class="ext">
<span>发布于:{{formatDate(a.publish_time)}}</span>

23
public/modules/qs.js Normal file
View File

@ -0,0 +1,23 @@
/**
*
* @param {string} str
*/
export function parse(str) {
// ?xx
// #
// a=a1&b=b1&....
str = str.replace(/^[(?#]/, '')
console.log(str)
const params = {}
str = str.split('&')
str.forEach(item => {
item = item.trim().split('='); // a=b ==> ['a','b']
if (item.length >= 1) {
params[item[0]] = item[1];
}
})
return params;
}
export default {
parse
}