当前位置: 首页 > 工具软件 > cnode-vue > 使用案例 >

Vue实现CNode

喻渊
2023-12-01

效果实现思路及过程:

  1. 通过vuex调用CNdoe接口,
  2. 通过Tap切换来实现跳转
  3. 通过dayjs插件是现实事件
  4. 获取屏幕可视区实现回到顶部

效果代码实现:

 vuex代码实现思路:

我们通过async和await异步获取数据,然后进行赋值,接口文档https://cnodejs.org/api

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    homeData:[],
    status:'all',
    aboutData:{}
  },
  mutations: {
    SET_HOME(state,data){
      state.homeData=data
    },
    SET_TAP(state,status){
      state.status=status;
      console.log(status)
    },
    SET_ABOUT(state,data){
      state.aboutData=data
    }
  },
  actions: {
    async setHome({commit},tab='all'){
      await axios.get('https://cnodejs.org/api/v1/topics?tab='+tab).then(res=>{
        console.log(res.data.data);
        commit('SET_HOME',res.data.data)
      })
    },
    setTap({commit},status){
      commit('SET_TAP',status)
    },
    setAbout({commit},id){
      axios.get('https://cnodejs.org/api/v1/topic/'+id).then(res=>{
        console.log(res.data.data)
        commit('SET_ABOUT',res.data.data)
      })
    }
  },
  modules: {
  }
})

首页代码实现思路:

先编写一下我们导航栏数据信息,然后通过Tap切换实现跳转,然后获取vuex中赋值的数据进行渲染,然后用dayjs插件实现时间的优化,在通过导航守卫在判断当我们页面刷新导航在跳,然后通过屏幕可视区实现点击返回顶部

<template>
  <div class="home">
    <header>
      <ul>
        <router-link tag="li" :class="{'current-tab':status==item.title}" 
        :to="{path:'/',query:{'tab':item.title}}" 
        v-for="item in tap" :key="item.id">{{item.name}}</router-link>
      </ul>
    </header>
    <div class="inner"  @scroll="totop($event)">
      <ul v-for="item in homeData" :key="item.id">
        <li>
          <img :src="item.author.avatar_url">
        </li>
        <li>置顶</li>
        <router-link tag="li" :to="'/topic/'+item.id">{{item.title}}</router-link>
        <li>
          <span>{{item.reply_count}}</span><span>/</span><span>{{item.visit_count}}</span>
        </li>
        <li>{{item.create_at | Time}}</li>
      </ul>
    </div>
    <div class="return-to" v-show="sctop>300" @click="addto">回到顶部</div>
  </div>
</template>

<script>
import dayjs from 'dayjs'
import "dayjs/locale/zh-cn"
import rTime from "dayjs/plugin/relativeTime"
dayjs.locale('zh-cn')
dayjs.extend(rTime)
import {mapState,mapActions} from 'vuex'

const tap=[
  {
    id:0,
    title:'all',
    name:"全部"
  },
  {
    id:1,
    title:'good',
    name:"精华"
  },
  {
    id:2,
    title:'job',
    name:"分享"
  },
  {
    id:3,
    title:'share',
    name:"问答"
  },
  {
    id:4,
    title:'ask',
    name:"招聘"
  },
];
export default {
  data() {
    return {
      tap,
      sctop:0,
      cstop:null
    }
  },
  computed:{
    ...mapState(['homeData','status']),
  },
  methods: {
    ...mapActions(['setTap','setHome']),
    totop(e){
      this.cstop=e
      this.sctop=e.target.scrollTop
      console.log(this.sctop)
    },
    addto(){
      this.sctop=0
      this.cstop.target.scrollTop=0
    }
  },
  filters:{
    Time(value){
      return dayjs().to(dayjs(value))
    }
  },  
  created(){
    this.$store.dispatch('setHome');
  },
  async beforeRouteUpdate(to, from, next) {
    this.$store.dispatch('setTap',to.query.tab)
    await this.$store.dispatch('setHome',to.query.tab)
    console.log(to)
    next();
  },
}
</script>

<style lang="scss" scoped>
  .home{
    width: 100%;
    margin: 0 auto;
    header{
      ul{
        display: flex;
        li{
          width: 0.5rem;
          line-height: 0.3rem;
          margin: 10px;
          color: chartreuse;
        }
        .current-tab{
          background: chartreuse;
          border-radius: 5px;
          color: #fff;
        }
      }
    }
    .inner{
      height: 6rem;
      overflow: scroll;
      ul{
        display: flex;
        margin: 10px 0;
        align-items: center;
        position: relative;
        li:nth-child(1){
          width: 10%;
          height: 0.4rem;
          img{
            width: 100%;
            height: 100%;
          }
        }
        li:nth-child(2){
          max-width: 10%;
          padding: 2px 4px;
          background: #80bd01;
          border-radius: 3px;
          margin-left: 10px;
          color: #fff;
          font-size: 12px;
        }
        li:nth-child(3){
          max-width: 70%;
          display: -webkit-box; 
          -webkit-box-orient: vertical;
          vertical-align: middle;
          -webkit-line-clamp: 1;
          overflow: hidden;
          text-align: left;
          color: #333;
          font-size: 12px;
        }
        li:nth-child(4){
          position: absolute;
          bottom: -2px;
          left: 82px;
          text-align: left;
          line-height: 2em;
          font-size: 10px;
          span:nth-child(1){
            color: #9e78c0;
          }
          span:nth-child(2){
            color: #9e78c0;
            margin: 0 2px;
          }
          span:nth-child(3){
            color: #b4b4b4;
          }
        }
        li:nth-child(5){
          position: absolute;
          bottom: 0;
          right: 10px;
          font-size: .1em;
          text-align: right;
          min-width: 50px;
          display: inline-block;
          white-space: nowrap;
        }
      }
    }
    .return-to{
      right: 0px;
      bottom: 20px;
      display: block;
      background-color: #f5f5f5;
      border: 1px solid #ccc;
      border-right: 0;
      width: 24px;
      color: gray;
      padding: 12px 0 12px 5px;
      // display: none;
      position: fixed;
      cursor: pointer;
      text-align: center;
      z-index: 20;
      background-color: #fff;
      border-radius: 12px 0 0 12px;
    }
  }
</style> 

是不是很简单,不懂的可以私信,我会一一解答

 类似资料: