cnode实战篇

1.cnode社区的基本构架

组件:
Header 头部
PostList 列表
Article 文章的详情页
SlideBar 侧边栏
UserInfo 用户个人信息
Pagination 分页组件

2.从零开始的实战

初始化项目

vue init webpack cnode
cnpm install
npm run dev

3. Header组件

引入组件

import Header from "./components/Header";
export default {
  name: "App",
  components: {
    Header
  }
};

在App.vue中插入组件

<Header></Header>

4. ProstList

API接口:https://cnodejs.org/api/v1/topics 获取帖子列表

拿到的参数分析

头像:author.avatar_url
回复量/浏览量 :reply_count/visit_count
帖子的标题:title
需要使用到过滤器:
时间:last_reply_at
帖子分类:top: 代表是否置顶
good: 代表是否精华
tab 是表示除了置顶和精华之外的其余分区
­share 分享
­ask 问答
­job 招聘
引入Axios

npm install anxious
在main.js中引入Axios

import Axios from 'axios'

Vue.prototype.$http = Axios;
利用一个v-for循环来把参数放到dom节点上
<li v-for="post in posts">
          <!--头像-->
          <img :src="post.author.avatar_url" />
          <!--回复/浏览-->
          <span>
            <span class="reply_count">{{post.reply_count}}</span>
            /{{post.visit_count}}
          </span>
          <span
            :class="[{put_good:(post.good == true),put_top:(post.top == true),
            'topiclist-tab':(post.good != true && post.top !=true)}]"
          >
            <span>{{post| tabFormatter}}</span>
          </span>
          <!--标题-->
          <span>{{post.title}}</span>
          <!--时间-->
          <span class="last_reply">{{post.last_reply_at | formatDate}}</span>
        </li>
在main.js中添加过滤器,处理时间
Vue.filter('formatDate', function (str) {
  if (!str) return ""
  var date = new Date(str)
  var time = new Date().getTime() - date.getTime() //单位为毫秒,现在的时间-过去的时间
  if (time < 0) {
    return ""
  } else if ((time / 1000 < 30)) {
    return '刚刚'
  } else if ((time / 1000 < 60)) {
    return parseInt((time / 1000)) + '秒前'
  } else if ((time / 6000 < 60)) {
    return parseInt((time / 6000)) + '分钟前'
  } else if ((time / 3600000 < 24)) {
    return parseInt((time / 3600000)) + '小时前'
  } else if ((time / 86400000 < 31)) {
    return parseInt((time / 86400000)) + '天前'
  } else if ((time / 2592000000 < 12)) {
    return parseInt((time / 2592000000)) + '月前'
  } else {
    return parseInt((time / 31536000000)) + '年前'
  }
})
在main.js中添加过滤器处理小标题
Vue.filter('tabFormatter', function (post) {
  if (post.good == true) {
    return '精华'
  } else if (post.top == true) {
    return '置顶'
  } else if (post.tab == 'ask') {
    return '问答'
  } else if (post.tab == 'share') {
    return '分享'
  } else {
    return '招聘'
  }
})

5. Article

API https://cnodejs.org/api/v1/topic/ + 帖子ID

写入header
<div class="topic_header">
        <div class="topic_title">{{post.title}}</div>
        <ul>
          <li>·发布于: {{post.create_at |formatDate}}</li>
          <li>• 作者:{{post.author.loginname}}</li>
          <li>· {{post.visit_count}}次浏览</li>
          <li>· 来自{{post | tabFormatter}}</li>
        </ul>
        <div v-html="post.content" class="topic_content"></div>
      </div>
写入回复板块
<div>
        <div class="topbar">回复</div>
        <div v-for="(reply,index) in post.replies" class="replySec">
          <div class="replyUp">
            <router-link>
              <img src="reply.author.avatar_url" />
            </router-link>
            <router-link>
              <span>{{reply.author.loginname}}</span>
            </router-link>
            <span>☝{{index + 1}}楼</span>
            <span v-if="reply.ups.length>0">{{reply.ups.length}}</span>
          </div>
          <p v-html="reply.content"></p>
        </div>
      </div>
methods

利用axious调入api地址

methods: {
    getArticleData() {
      this.$http
        .get("https://cnodejs.org/api/v1/topic/" + this.$route.params.id)
        .then(res => {
          if (res.data.success == true) {
            this.post = res.data.data;
            this.isLoading = false;
          }
        })
        .catch(function(err) {
          console.log(err);
        });
    }
  },
在postlist上加入router-link

加入路由跳转

<router-link
            :to="{
            name: 'post_content',
            params: {
              id: post.id
            }
          }"
          >
            <span>{{post.title}}</span>
          </router-link>
在index.js加入router路由跳转
export default new Router({
  routes: [{
      name: 'root',
      path: '/',
      components: {
        main: PostList
      }
    },
    {
      name: 'post_content',
      path: '/topic/:id',
      components: {
        main: Article
      }
    }]

4.UserInfo
https://cnodejs.org/api/v1/user/

在article板块中加入router-link
 <router-link
              :to="{
                name:'user_info',
                params: {
                  name: reply.author.loginname
                }
              }"
            >
              <img :src="reply.author.avatar_url" alt />
            </router-link>
在index.js中添加路由
{
      name: 'user_info',
      path: '/userinfo/:name',
      components: {
        main: UserInfo
      }
    },
在回复板块上路由重新跳转回Postlist板块
<div class="replies">
        <p>回复的主题</p>
        <ul>
          <li v-for="item in userinfo.recent_replies" :key="item">
            <router-link
              :to="{
                    name: 'post_content',
                    params: {
                    id: item.id  
                    }
                }"
            >{{item.title}}</router-link>
          </li>
        </ul>
      </div>
在创建主题板块上也是同理
div class="topics">
        <p>创建的主题</p>
        <ul>
          <li v-for="item in userinfo.recent_topics" :key="item">
            <router-link
              :to="{
                    name: 'post_content',
                    params: {
                    id: item.id  
                    }
                }"
            >{{item.title}}</router-link>
          </li>
        </ul>
      </div>
    </div>

SlideBar注意事项

1.需要在PostList上多加上一个参数来显示作者名
<router-link
            :to="{
            name: 'post_content',
            params: {
              id: post.id,
              name: post.author.loginname
            }
          }"
          >
            <span>{{post.title}}</span>
          </router-link>

同理修改路由跳转

{
      name: 'post_content',
      path: '/topic/:id&author=:name',
      components: {
        main: Article,
        slidebar: SlideBar
      }
    },
2.处理回复的消息需要得到最近的五条,此时需要利用computed属性
<li v-for="list in topiclimitby5" :key="list">
          <router-link
            :to="{
            name: 'post_content',
            params: {
                id: list.id,
                name: list.author.loginname
            }
        }"
          >{{list.title}}</router-link>
        </li>
computed: {
    topiclimitby5() {
      if (this.userinfo.recent_topics) {
        return this.userinfo.recent_topics.slice(0, 5);
      }
    },
    replylimitby5() {
      if (this.userinfo.recent_replies) {
        return this.userinfo.recent_replies.slice(0, 5);
      }
    }
  },
3.由于点击连接主题路由跳转的地址相同,需要在Article组件中加入watch观察路由跳转
watch: {
    $route(to, from) {
      this.getArticleData();
    }
  }

6.Pagination注意事项

1.注意如何进行删除button和添加button
if (page == this.pagebtns[4]) {
        this.pagebtns.shift(); //移除第一个元素
        this.pagebtns.splice(4, 0, this.pagebtns[3] + 1); //添加最后一个
      } else if (page == this.pagebtns[0] && page != 1) {
        //现在第一个位置加一个
        this.pagebtns.unshift(this.pagebtns[0] - 1);
        //移除最后一个数字
        this.pagebtns.splice(5, 1);
      }
2.如何处理首页和下一页上一页的数据
if (typeof page != "number") {
        switch (page.target.innerText) {
          case "上一页":
            $("button.currentPage")
              .prev()
              .click();
            break;
          case "下一页":
            $("button.currentPage")
              .next()
              .click();
            break;
          case "首页":
            this.pagebtns = [1, 2, 3, 4, 5, "......"];
            this.changeBtn(1);
            break;
          default:
            break;
        }
        return;
      }
3.在Poslist中获得Pagination的参数

1.在组件添加方法

<pagination @handleList="renderList"></pagination>

2.方法

renderList(value) {
      this.postpage = value;
      this.getData();
    }

3.在pagination中传递数据

this.$emit("handleList", this.currentPage);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容