10

前文

上篇:https://segmentfault.com/a/11...
中篇:https://segmentfault.com/a/11...

github地址:https://github.com/ssevenk/ss...

现在只剩下把东西展示出来了

页面

clipboard.png

clipboard.png

clipboard.png

clipboard.png

这里有四种页面(其实是四个组件):
文章,杂谈,收藏,具体的文章或杂谈
前三个虽然布局一样,但功能有细微差别,同时考虑到以后可能要针对不同种类做不同的布局方法
我还是定义了三个组件
ShowBlogs、ShowEssays、ShowArticles
以及具体的那个
TheOne

可以看到它们共用一个抬头的logo和导航栏
所以我把这一块部分写进front组件里
剩下的部分用路由决定展示哪一个组件

clipboard.png
使用嵌套路由

clipboard.png

数据展示

这个很简单,就在最开始请求后端获取到数据后

created() {
    this.getData();
  },
methods: {
getData() {
  this.$axios.get("/data/blog").then(res => {
    this.blogs = res.data;
    this.show = this.blogs;
  });
}

v-forrouter-link循环出来
每一个数据都是一个link,可以跳转到具体的内容页面

<router-link class='ShowBlogs-blog'
    :to="{ name:'TheOne',params:{ kind:'blog',id:item._id }}"
    tag="li"
    v-for="item in show.slice((currentPage-1)*pageSize,currentPage*pageSize)"
    :key="item._id"
  >
    <span>{{ item.date }}</span>
    {{ item.title }}
  </router-link>

分页

在上面的代码中你应该注意到了,看到了一个很熟悉的东西

show.slice((currentPage-1)*pageSize,currentPage*pageSize)

这是我们在后台管理系统中用过的分页
这里不再赘述

搜索

不过搜索功能有点和后台管理不一样
这一次我定义了一个show数组
点击搜索之后,调用函数来进行搜索,把搜索出来的结果存放在show
所以我们展示的一直都是show数组

由于三个页面都用到了搜索框
所以我把搜索框单独做成了一个组件
并没有引入到main.js中使其成为全局组件
因为我们希望它是作为ShowBlogs、ShowEssays、ShowArticles这三个组件的子组件存在的,方便调用父组件提供的方法

import mySearch from "./mySearch";

每个组件都引入一次
点击搜索时,向父组件发射搜索框里的内容,并调用父组件的方法

//mySearch.vue
 methods:{
      search() {
          this.$emit('search',this.content)
      }
  }

在父组件中

<mySearch @search="searchfor"></mySearch>

methods:{
searchfor(s) {
  this.show = (this.blogs.filter(item => {
    if (item.title.includes(s)) {
      return item;
    }
  }));
}}

针对每个组件,搜索框的颜色不一样
这里用$route.path来判断
写在搜索框的组件里

clipboard.png
path来决定使用哪种样式

<input type="text" v-model="content" :class="classipt" placeholder="请输入关键词搜索">
<button @click="search" :class="classbtn">

具体文章或杂谈

获取后端送来的数据(字符串)
调用simpleMDE的原型方法将其转换为html格式

this.contentMarkdown=SimpleMDE.prototype.markdown(this.theOne.content)

v-html展示出来

<div id='markdownArticle' v-html="contentMarkdown"></div>

评论功能

建立输入框,供读者发布评论
每篇文章或者杂谈都有属于自己的comments数组
只需要将这个新的评论存进去就可以

pushComment() {
  if (this.comment.name && this.comment.content) {
    var comment = {
      name: this.comment.name,
      content: this.comment.content,
      date: Math.random()
        .toString(36)
        .substr(2)
    };
    this.theOne.comments.push(comment);
    this.$axios.post(`/data/${this.kind}/${this.$route.params.id}`, {
      id: this.$route.params.id,
      title: this.theOne.title,
      content: this.theOne.content,
      comments: this.theOne.comments
    });
  }
  this.comment.name = "";
  this.comment.content = "";
}

这里在存入前,先定义了一个局部变量,把输入框的值赋值给它
再把这个局部变量存进去
如果直接把输入框的值存进去,那么双向绑定依旧存在
输入框内容修改,已经存进去的评论也会跟着变

收藏夹

点击跳转外部链接

  <li class='ShowBlogs-article'
    v-for="item in show.slice((currentPage-1)*pageSize,currentPage*pageSize)"
    :key="item._id"
    @click="jumpTo(item.link)"
  >
  
  jumpTo(link) {
  // window.location.href=link //当前窗口打开
  window.open(link)}
  

总结

至此,我的个人博客项目算是完成了
还有很多需要优化的地方,比如管理页面的密码认证,页面布局的合理性与美观,移动端响应式设计,今后的上线部署等等
不过也算完成了一开始预期的目标了,学过的东西都派上了用场
继续努力学习~


夜行风
1k 声望50 粉丝

字节跳动持续招人中~