使用nuxt,express,mysql,nginx创建个人博客系列-18
159
2020-01-24 18:37
10 个月前
文章详情页面
创建一个文章详情的页面
目录:pages/articles/_id.vue
<template>
<section class="container clearfix" v-if="result">
<div class="content-wrap clearfix">
<div class="content">
<div class="content-main">
<div class="article-header">
<h1 class="article-title">{{result.data.item.title}}</h1>
</div>
<div class="article-introduction" v-if="result.data.item.introduction">简介:{{result.data.item.introduction}}</div>
<article class="article-content" v-html="marked(result.data.item.content)"></article>
</div>
<div class="respond">
<div class="comt-title">
<div class="comt-author">发表我的评论</div>
</div>
<div class="comt">
<div class="comt-box">
<div class="comt-ctrl">
<div class="comment-sumbit" @click="submit_comment">发表评论</div>
</div>
</div>
</div>
</div>
<div class="post-comment-box">
<h3>最新评论</h3>
<div class="commentlist">
<commentlist :childIndex="0" :list="result.data.comment" @setpid="setPid" v-if="result.data.comment.length"></commentlist>
</div>
</div>
</div>
</div>
<my-right :tags="result.data.tags"></my-right>
<my-comment v-if="showComment" @hideCommentBox="hideCommentBox">
<div class="comment-model-title">请填写评论</div>
<div class="comment-model-input-box">
<div class="clearfix" v-if="!showCommentInput">
<input type="text" v-model="username" placeholder="请输入你的昵称" />
<input type="text" v-model="email" placeholder="请输入你的邮箱"/>
<div class="comment-model-user-btn" @click="saveLocalUser">提交昵称和邮箱</div>
</div>
<div class="cleatfix" v-if="showCommentInput">
<textarea v-model="content"></textarea>
<div class="comment-model-user-btn" @click="addComment">提交评论</div>
</div>
</div>
</my-comment>
</section>
</template>
<script>
import axios from "~/plugins/axios";
import MyRight from "~/components/Right.vue";
import MyComment from "~/components/comment.vue";
//封装的简单comment弹框组件
import commentlist from "~/components/commentlist"; // 评论列表
let uk = "upupjs-ukey"; //localStorage ,username-key
let ek = "upupjs-ekey";//localStorage ,email-key
export default {
components: {
MyRight,
MyComment,
commentlist
},
data() {
return {
articles_id: this.$route.params.id,
content: "",
p_id: 0,
push_comment_index: -1,
showCommentInput: false,
username: "",
email: "",
showComment: false
};
},
asyncData({ params, error, isClient }) {
const fetchUrl = `/api/article/${params.id}`;
return axios
.get(fetchUrl)
.then(resp => {
let { data } = resp;
let obj = {
result: data
};
return obj;
})
.catch(err => {
error({ statusCode: 500, message: `${e}` });
});
},
mounted() {
//判断是否已经登陆,使用localStorage伪登陆
(this.username = localStorage.getItem(uk)),
(this.email = localStorage.getItem(ek)),
(this.showCommentInput = this.username && this.email);
},
head() {
return {
title: this.result.data.item.title,
meta: [
{
hid: "keywords",
name: "keywords",
content: this.result.data.item.keyword
}
]
};
},
methods: {
setPid(obj) {
console.log(obj);
this.showComment = !this.showComment;
this.p_id = obj.id;
this.push_comment_index = obj.orginDataIndex;
console.log(obj);
},
hideCommentBox() {
this.showComment = !this.showComment;
},
saveLocalUser() {
if (this.username && this.email) {
localStorage.setItem(uk, this.username);
localStorage.setItem(ek, this.email);
this.showCommentInput = true;
} else {
alert("请填写昵称和邮箱再评论");
}
},
submit_comment() {
this.showComment = !this.showComment;
this.p_id = 0;
this.push_comment_index = -1;
},
addComment() {
let { articles_id, p_id, content, username, email } = this;
axios
.post("/api/article/addComment", {
p_id,
articles_id,
content,
username,
email
})
.then(resp => {
let result = resp.data;
if (result.status == 1) {
this.showComment = !this.showComment;
if (this.push_comment_index == -1) {
this.result.data.comment.splice(0,0,{
content,
username,
email,
created_at: new Date(),
id: result.data.insertId,
commentList:[]
});
}else{
let res = null;
for(var i=0;i<this.push_comment_index.length;i++){
if(res){
if(!res[this.push_comment_index[i]]['commentList']){
this.$set(res[this.push_comment_index[i]],'commentList',[])
}
res = res[this.push_comment_index[i]]['commentList'];
}else{
if(!this.result.data.comment[this.push_comment_index[i]]['commentList']){
this.$set(this.result.data.comment[this.push_comment_index[i]],'commentList',[])
}
res = this.result.data.comment[this.push_comment_index[i]]['commentList'];
}
}
res.splice(0,0,{
content,
username,
email,
created_at: new Date(),
id: result.data.insertId
})
// this.result.data.comment[ax]['commentList'].splice()
}
}
});
}
}
};
</script>
上面看到页面的asyncData方法,是去请求/api/article/${params.id},我们根据url上面的查找文章详情,所以我们要往articles.js文件上添加这个路由,获取文章详情和文章评论。 目录:server/api/articles.js
router.get('/article/:id', async (req, res, next) => {
try {
let myConnect = await mysql.getConnect();
let sql = `select a.title,a.user_id, a.articles_img, a.keyword ,a.id ,a.introduction,a.content ,a.category_id ,a.tag_id from articles as a where id = ? limit 1`;
let tags = await mysql.query(myConnect, tagsSql);
let articles = await mysql.query(myConnect, sql,req.params.id);
let commentSql = `SELECT id,p_id,content,username,email,created_at FROM comments WHERE articles_id = ? AND p_id = 0 order by created_at desc`;
let commentFirstResult = await mysql.query(myConnect,commentSql,req.params.id);
let childCommentSql = `SELECT id,p_id,content,username,email,created_at FROM comments WHERE articles_id = ? AND p_id <> 0 order by created_at desc`;
let childCommentResult = await mysql.query(myConnect,childCommentSql,req.params.id);
await mysql.release(myConnect);
_.map(commentFirstResult,(item)=>{
let child =zTree(item.id)
item.commentList = child
// item.child =
});
function zTree(pid){
let child = []
if(!childCommentResult.length){
return child;
}
child = _.remove(childCommentResult,(childItem)=>{
return childItem.p_id == pid
})
if(child.length){
_.map(child,(item)=>{
item.commentList = zTree(item.id)
})
}
return child;
}
if(articles.length){
res.send(util.resSuccess({
data: {
item:articles[0],
tags,
comment:commentFirstResult,
// childComment:childCommentResult
}
}))
}
} catch (err) {
next(err)
}
})
上一篇-使用nuxt,express,mysql,nginx创建个人博客系列-17
下一篇-使用nuxt,express,mysql,nginx创建个人博客系列-19