使用nuxt,express,mysql,nginx创建个人博客系列-18

133
2020-01-24 18:37
5 个月前

文章详情页面

创建一个文章详情的页面
目录: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