zoukankan      html  css  js  c++  java
  • vue-cnodejs

    感谢那些无私开源的程序员,你们是最可爱的人儿~~~~

    //根app app.js
    <template>
      <div id="app">
        <v-header></v-header>
         <div class="main">
           <router-view></router-view>
         </div>
        <v-footer></v-footer>
      </div>
    </template>
    
    <script>
    import vHeader from './components/header'
    import vFooter from './components/footer'
    
    export default {
      name: 'app',
      components: {
        vHeader,
        vFooter
      }
    }
    </script>
    
    <style>
    #app {
      font-family: Helvetica, Arial, sans-serif;
      font-size: 14px;
      background: #E2E2E2;
      color: #778087;
    }
    img {
      height: auto;
      vertical-align: top;
    }
    .main {
       1100px;
      margin: 0 auto;
    }
    </style>
    
    

    公共header

    //src/components/header.vue
    <template>
      <div class="header">
        <div class="header-wrapper">
          <h1 class="title">
            <router-link to="/tag/all">
              <img src="./../assets/logo.png">
              <span>cNodeJS</span>
            </router-link>
          </h1>
          <p class="about">关于</p>
        </div>
      </div>
    </template>
    
    <script>
    export default {
    };
    </script>
    
    <style scoped>
    .header {
      background: #fff;
      margin-bottom: 35px;
    }
    .header .header-wrapper {
       1100px;
      margin: 0 auto;
      overflow: hidden;
    }
    .header .header-wrapper .title {
      float: left;
      padding: 10px 0;
    }
    .header .header-wrapper .title img {
       30px;
      height: 30px;
      vertical-align: middle;
      margin-right: 10px;
    }
    .header .header-wrapper .title span {
      font-size: 18px;
      font-weight: bold;
      color: #778087;
    }
    .header .header-wrapper .about {
      float: right;
      margin-top: 15px;
    }
    </style>
    

    //src/components/footer.vue
    <template>
      <div class="footer">
        <p>由 Vue 强力驱动 | Write - By XMit</p>
      </div>
    </template>
    
    <script>
    export default {
      name: 'footer',
    }
    </script>
    
    <style scoped>
    .footer {
      background: #fff;
      margin-top: 35px;
      padding: 50px 0 30px;
      text-align: center;
    }
    </style>
    

    路由部分

    //src/router/index.js
    import Vue from 'vue'
    import Router from 'vue-router'
    
    import main from '@/components/main';
    import detail from '@/components/detail';
    import user from '@/components/user';
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'home',
          component: main,
          children: [
            {
              path: '/tag/:id',
            }
          ]
        },
        {
          path: '/topic/:id',
          name: 'detail',
          component: detail
        },
        {
          path: '/user/:id',
          name: 'user',
          component: user
        },
      ]
    })
    
    //src/components/user.vue
    <template>
      <div class="user" v-if="user.length !== 0">
        <div class="user-info">
          <div class="user-info-hd">个人用户信息</div>
          <div class="user-info-bd">
            <ul>
              <li>
                <img :src="user.avatar_url" alt="img">
                <p class="username">{{user.loginname}}</p>
              </li>
              <li>{{user.score}} 积分</li>
              <li>github <a :href="'http://github.com/' + user.githubUsername">{{'http://github.com/' + user.githubUsername}}</a></li>
              <li>注册时间 {{getTime(user.create_at)}}</li>
            </ul>
          </div>
        </div>
        <div class="new-topic" v-if="user.recent_topics.length !== 0">
          <div class="new-topic-hd">最近创建的话题</div>
          <div class="new-topic-bd">
            <ul>
              <li v-for="item in user.recent_topics">
                <img :src="user.avatar_url" alt="img">
                <router-link :to="{ name: 'detail', params: {id: item.id} }" class="title">{{item.title}}</router-link>
              </li>
            </ul>
          </div>
        </div>
        <div class="participate" v-if="user.recent_replies.length !== 0">
          <div class="participate-hd">最近参与的话题</div>
          <div class="participate-bd">
            <ul>
              <li v-for="item in user.recent_replies">
                <img :src="user.avatar_url" alt="img">
                <router-link :to="{ name: 'detail', params: {id: item.id} }" class="title">{{item.title}}</router-link>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: ['userdata'],
      data: function() {
        return {
          user: []
        };
      },
      methods: {
        getData: function() {
          this.$http
            .get("https://cnodejs.org/api/v1/user/" + (this.userdata || this.$route.params.id), {
              params: {}
            })
            .then(it => {
              this.user = it.data.data;
              console.log(this.user);
            })
            .catch(it => {
              console.log("user.vue:", it);
            });
        },
        getDateTimeStamp: function (dateStr){
          return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
        },
        getTime: function(hisTime, nowTime) {
          var now = nowTime ? nowTime : new Date().getTime(),
            diffValue = now - this.getDateTimeStamp(hisTime),
            result = "",
            minute = 1000 * 60,
            hour = minute * 60,
            day = hour * 24,
            halfamonth = day * 15,
            month = day * 30,
            year = month * 12,
            _year = diffValue / year,
            _month = diffValue / month,
            _week = diffValue / (7 * day),
            _day = diffValue / day,
            _hour = diffValue / hour,
            _min = diffValue / minute;
          if (_year >= 1) result = parseInt(_year) + "年前";
          else if (_month >= 1) result = parseInt(_month) + "个月前";
          else if (_week >= 1) result = parseInt(_week) + "周前";
          else if (_day >= 1) result = parseInt(_day) + "天前";
          else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
          else if (_min >= 1) result = parseInt(_min) + "分钟前";
          else result = "刚刚";
          return result;
        }
      },
      created() {
        this.getData();
      }
    };
    </script>
    
    <style scoped>
    .user {
      border-radius: 4px;
    }
    .user a {
      color: #778087;
    }
    .user-info,
    .new-topic,
    .participate {
      margin-bottom: 20px;
      background: #fff;
      border-radius: 4px;
    }
    .user .user-info-hd,
    .new-topic .new-topic-hd,
    .participate .participate-hd {
      padding: 10px 20px;
      background: #F6F6F6;
      border-radius: 4px;
    }
    .user .user-info-bd img {
       50px;
      height: auto;
      border-radius: 4px;
      margin-bottom: 5px;
    }
    .new-topic .new-topic-bd img,
    .participate .participate-bd img {
       30px;
      height: auto;
      border-radius: 4px;
      margin-bottom: 5px;
      margin-right: 10px;
      vertical-align: middle;
    }
    .user .user-info-bd {
      padding: 20px;
    }
    .user .user-info-bd li {
      margin-bottom: 10px;
    }
    .new-topic .new-topic-bd li,
    .participate .participate-bd li {
      border-bottom: 1px solid #ddd;
      padding: 5px 20px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .new-topic .new-topic-bd li:last-child,
    .participate .participate-bd li:last-child {
      border-bottom: 0
    }
    </style>
    


    //src/components/main.vue
    <template>
      <div class="main">
        <div class="main-wrapper">
          <ul class="tab-list">
            <li class="item" @click="tabs('all')">全部</li>
            <li class="item" @click="tabs('good')">精华</li>
            <li class="item" @click="tabs('share')">分享</li>
            <li class="item" @click="tabs('ask')">问答</li>
            <li class="item" @click="tabs('job')">招聘</li>
            <li class="item" @click="tabs('dev')">客户端测试</li>        
          </ul>
          <ul class="list">
            <li v-for="(item,index) in content" :key="index" class="item">
              <div class="item-hd">
                <router-link :to="{ name: 'user', params: {id: item.author.loginname} }" class="user">
                  <img :src="item.author.avatar_url">
                </router-link> 
              </div>
              <div class="item-bd">
                <router-link :to="{ name: 'detail', params: {id: item.id} }" class="title">{{item.title}}</router-link>
                <p class="footer">
                  <span class="reply" v-show="item.reply_count !== 0">{{item.reply_count}}</span>
                  <span class="authour">{{item.author.loginname}} • </span>
                  <span class="time">创建于: {{getTime(item.create_at)}}</span>
                </p>
                <p :class="{top: item.top}" v-if="item.top">置顶</p>
              </div>
            </li>
          </ul>  
        </div>
        <p class="pagination">
          <!-- <a class="button" @click="prev" >GO PREV</a>
          <a class="button" @click="next" >GO NEXT</a> -->
          <v-tab v-on:changePage="test"></v-tab>
        </p>
      </div>
    </template>
    
    <script>
    import vTab from "./tab";
    
    export default {
      data: function() {
        return {
          content: [],
          page: 1,
          tab: 'all',
          show: true
        };
      },
      methods: {
        test(page) {
          // console.log('page:' + page)
          this.page = page
        },
        tabs(data) {
          this.tab = data
          this.$router.push({ path: `/tag/${data}` })
        },
        prev() {
          if(this.page > 1) {
            return this.page--
          }
        },
        next() {
          return this.page++
        },
        getData: function(page,tab) {
          this.$http
            .get("https://cnodejs.org/api/v1/topics", {
              params: {
                page: page,
                limit: 0,
                tab: tab,
                mdrender: true
              }
            })
            .then(it => {
              this.content = it.data.data
            })
            .catch(it => {
              console.log("main.vue:", it);
            });
        },
        getDateTimeStamp: function (dateStr){
          return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
        },
        getTime: function(hisTime, nowTime) {
          var now = nowTime ? nowTime : new Date().getTime(),
            diffValue = now - this.getDateTimeStamp(hisTime),
            result = "",
            minute = 1000 * 60,
            hour = minute * 60,
            day = hour * 24,
            halfamonth = day * 15,
            month = day * 30,
            year = month * 12,
            _year = diffValue / year,
            _month = diffValue / month,
            _week = diffValue / (7 * day),
            _day = diffValue / day,
            _hour = diffValue / hour,
            _min = diffValue / minute;
          if (_year >= 1) result = parseInt(_year) + "年前";
          else if (_month >= 1) result = parseInt(_month) + "个月前";
          else if (_week >= 1) result = parseInt(_week) + "周前";
          else if (_day >= 1) result = parseInt(_day) + "天前";
          else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
          else if (_min >= 1) result = parseInt(_min) + "分钟前";
          else result = "刚刚";
          return result;
        }
      },
      created() {
        this.getData(this.page)
      },
      watch: {
        page(val) {
          this.getData(val)
        },
        tab(newVal, oldVal) {
          this.getData(this.page, newVal)
        },
        $route(to, from) {
          // this.getData(to.params.id)
          this.getData(this.page, to.params.id)
        }
      },
      components: {
        vTab
      }
    };
    </script>
    
    <style scoped>
    .tab-list {
      overflow: hidden;
      padding: 10px 15px;
      background: #f6f6f6;
      border-radius: 4px 4px 0 0;
    }
    .tab-list .item {
      float: left;
      margin-right: 15px;
    }
    .button {
      display: inline-block;
      background: #212121;
      color: #fff;
      font-weight: bold;
      text-align: center;
      padding: 1em;
      cursor: pointer;
      text-decoration: none;
    }
    .pagination {
      padding: 20px 0 0;
      text-align: center;
    }
    .main .main-wrapper {
      background: #fff;
      border-radius: 4px;
    }
    .main .main-wrapper .list .item {
      overflow: hidden;
      padding: 10px;
      border-bottom: 1px solid #ddd;
    }
    .main .main-wrapper .list .item:last-child {
      border: 0;
    }
    .main .main-wrapper .list .item .item-hd {
      float: left;
    }
    .main .main-wrapper .list .item .item-hd .user {
      display: inline-block;
    }
    .main .main-wrapper .list .item .item-hd img {
       50px;
      height: 50px;
      display: inline-block;
      border-radius: 4px;
    }
    .main .main-wrapper .list .item .item-bd {
      margin-left: 70px;
    }
    .main .main-wrapper .list .item .item-bd .title {
      font-size: 16px;
      margin-bottom: 5px;
      color: #778087;
    }
    .main .main-wrapper .list .item .item-bd .footer {
      color: #8492a6;
    }
    .main .main-wrapper .list .item .item-bd .footer .reply {
      display: inline-block;
      position: absolute;
      right: 10px;
      top: 15px;
      background: #aab0c5;
      border-radius: 10px;
       30px;
      text-align: center;
      color: #fff;
      font-size: 12px;
    }
    .main .main-wrapper .list .item .item-bd {
      position: relative;
    }
    .main .main-wrapper .list .item .item-bd .top {
      position: absolute;
      right: -20px;
      top: -20px;
      background: #81bb24;
      color: #fff;
      padding: 3px 3px;
      border-radius: 2px;
      font-size: 12px;
      text-indent: -9999px;
      transform: rotate(-45deg);
    }
    </style>
    

    //src/components/detail.vue
    <template>
      <div class="content" v-if="itemdetail">
        <div class="detail-left">
          <div class="detail">
            <div class="detail-wrapper">
              <div class="detail-hd">
                <h2 class="title">{{itemdetail.title}}</h2>
                <span class="time">发布于 {{getTime(itemdetail.create_at)}} •</span>
                <span class="author">作者 {{itemdetail.author.loginname}} •</span>
                <span class="visit">{{itemdetail.visit_count}} 次浏览</span>
              </div>
              <div class="detail-bd">
                <div id="content" v-html="itemdetail.content"></div>
              </div>
            </div>
          </div>
          <v-reply :replydata="itemdetail.replies"></v-reply>
        </div>
        <div class="detail-right">
          <v-user :userdata="itemdetail.author.loginname"></v-user>
        </div>
      </div>
    </template>
    
    <script>
    import vReply from "./reply";
    import vUser from "./user";
    
    export default {
      name: "detail",
      data() {
        return {
          itemdetail: ""
        };
      },
      methods: {
        getData: function(id) {
          this.$http
            .get("https://cnodejs.org/api/v1/topic/" + id, {
              params: {
                accesstoken: true,
                mdrender: true
              }
            })
            .then(it => {
              this.itemdetail = it.data.data;
              // console.log(this.itemdetail);
            })
            .catch(it => {
              //  console.log('detail.vue:',it)
            });
        },
        getDateTimeStamp: function (dateStr){
          return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
        },
        getTime: function(hisTime, nowTime) {
          var now = nowTime ? nowTime : new Date().getTime(),
            diffValue = now - this.getDateTimeStamp(hisTime),
            result = "",
            minute = 1000 * 60,
            hour = minute * 60,
            day = hour * 24,
            halfamonth = day * 15,
            month = day * 30,
            year = month * 12,
            _year = diffValue / year,
            _month = diffValue / month,
            _week = diffValue / (7 * day),
            _day = diffValue / day,
            _hour = diffValue / hour,
            _min = diffValue / minute;
          if (_year >= 1) result = parseInt(_year) + "年前";
          else if (_month >= 1) result = parseInt(_month) + "个月前";
          else if (_week >= 1) result = parseInt(_week) + "周前";
          else if (_day >= 1) result = parseInt(_day) + "天前";
          else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
          else if (_min >= 1) result = parseInt(_min) + "分钟前";
          else result = "刚刚";
          return result;
        }
      },
      created() {
        this.getData(this.$route.params.id);
      },
      watch: {
        $route(to, from) {
          this.getData(to.params.id)
          // console.log(to, from)
        }
      },
      components: {
        vReply,
        vUser
      }
    };
    </script>
    
    <style scoped>
    .content {
      overflow: hidden;
    }
    .detail-left {
      float: left;
       70%;
    }
    .detail-right {
      float: right;
       28%;
    }
    .detail .detail-wrapper {
      background: #fff;
      border-radius: 4px;
    }
    .detail .detail-wrapper .detail-hd,
    .detail .detail-wrapper .detail-bd {
      padding: 20px;
    }
    .detail .detail-wrapper .detail-hd {
      border-bottom: 1px solid #ddd;
    }
    .detail .detail-wrapper .detail-hd .title {
      font-size: 20px;
      margin-bottom: 15px;
    }
    </style>
    

    //src/components/reply.vue
    <template>
      <div class="reply" v-if="replydata && replydata.length !== 0">
        <div class="reply-wrapper">
          <p class="reply-head">{{replydata.length}} 回复</p>
          <ul class="list">
            <li class="item" v-for="(item, index) in replydata" :key="index">
              <div class="item-hd">
                <router-link :to="{ name: 'user', params: {id: item.author.loginname} }" class="user">
                  <img :src="item.author.avatar_url">
                </router-link> 
              </div>
              <div class="item-bd">
                <div class="top">
                  <span class="user">{{item.author.loginname}}</span>
                  <span class="floor">{{index+1}} 楼</span>
                  <span class="time">{{getTime(item.create_at)}}</span>
                </div>
                <div class="content" v-html="item.content"></div>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: "reply",
      props: ["replydata"],
      methods: {
        getDateTimeStamp: function (dateStr){
          return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
        },
        getTime: function(hisTime, nowTime) {
          var now = nowTime ? nowTime : new Date().getTime(),
            diffValue = now - this.getDateTimeStamp(hisTime),
            result = "",
            minute = 1000 * 60,
            hour = minute * 60,
            day = hour * 24,
            halfamonth = day * 15,
            month = day * 30,
            year = month * 12,
            _year = diffValue / year,
            _month = diffValue / month,
            _week = diffValue / (7 * day),
            _day = diffValue / day,
            _hour = diffValue / hour,
            _min = diffValue / minute;
          if (_year >= 1) result = parseInt(_year) + "年前";
          else if (_month >= 1) result = parseInt(_month) + "个月前";
          else if (_week >= 1) result = parseInt(_week) + "周前";
          else if (_day >= 1) result = parseInt(_day) + "天前";
          else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
          else if (_min >= 1) result = parseInt(_min) + "分钟前";
          else result = "刚刚";
          return result;
        }
      }
    };
    </script>
    
    <style scoped>
    .reply {
      margin-top: 30px;
      background: #fff;
      border-radius: 4px;
    }
    .reply .reply-wrapper .reply-head {
      padding: 8px 10px;
      background: #f6f6f6;
      border-radius: 4px;
    }
    .reply .reply-wrapper .list .item {
      overflow: hidden;
      padding: 20px;
      border-bottom: 1px solid #ddd;
    }
    .reply .reply-wrapper .list .item:last-child {
      border: 0;
    }
    .reply .reply-wrapper .list .item .item-hd {
      float: left;
    }
    .reply .reply-wrapper .list .item .item-hd img {
      border-radius: 4px;
       50px;
    }
    .reply .reply-wrapper .list .item .item-bd {
      margin-left: 60px;
    }
    .reply .reply-wrapper .list .item .item-bd .top {
      margin-bottom: 10px;
    }
    .reply .reply-wrapper .list .item .item-bd .user {
      color: #666;
    }
    </style>
    

    点进去就可以看到项目哇~

  • 相关阅读:
    在IIS中设置默认网页
    vim 查找匹配字符串次数
    resource about NLP
    Mongodb基本知识和常用语法
    fudanNLP keyword Extraction
    nltk support chinese by sinica
    Gmail小技巧:只显示未读邮件
    java get line number and file name
    java classpath import package 机制
    linux 调用 fudanNLP
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10856374.html
Copyright © 2011-2022 走看看