AlloyTeam(腾讯全端博客)

简介: AlloyTeam(腾讯全端博客)

效果概述

列表页面显示数据,点击跳转到对应的详情页,实现分页效果,点击回到顶部

具体效果

1.移动端适配
2.样式符合ui效果
3.处理时间格式
4.分页效果(上一页,下一页)
5.点击回到顶部效果(详情页和列表页都需实现)
6.解决接口跨域请求访问问题
7.路由跳转无bug
8.列表页面显示数据,点击跳转到对应的详情页

实现后效果图:

image.png

AlloyTeam(腾讯全端博客)

大致代码思路:

  • 根页面:
使用 div 标签实现更多
router-view 标签接收数据
使用 router-link 实现回到顶部

列表页:

在 main.js 页面引入 axios 插件

在 main.js 页面引入 rem 移动端适配代码

在 main.js 页面引入 dayjs 处理时间格式插件

通过 rem 进行移动端适配

通过 axios 接口地址请求数据

通过 dayjs 处理时间格式

把请求到的数据赋值给data里的选项

在 html 代码中通过 v-for 实现循环,把数据渲染至视图中

通过正则获取到对象里的所有数字

用编程式导航实现跳转功能,并把列表的 id 通过 query 传递至跳转后的页面

通过 router-link 实现分页效果的跳转

通过路由滚动行为实现回到顶部效果


详情页:

使用 this.$route.query.id 获取上个页面通过 query 传递的 id 值

使用 axios 接口地址和接收到的 id 值请求详细数据

把请求到的数据赋值给data里的选项

把数据渲染到视图中

main.js代码:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 引入rem适配
import '@/rem'
// 引入 axios
import axios from 'axios'
//可以全局使用$axios
Vue.prototype.$axios = axios
// 引入dayjs
import dayjs from "dayjs"
//可以全局使用dayjs
Vue.prototype.dayjs = dayjs;
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

rem 适配页面代码:

const WIDTH = 375//如果是尺寸的设计稿在这里修改
const setView = () => {
    //设置html标签的fontSize
    document.documentElement.style.fontSize = (100 * document.documentElement.clientWidth / WIDTH) + 'px'
}
window.onresize = setView
setView()

跨域问题,在vue.config.js里添加代码

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  // 下面是解决跨域问题需要添加的内容
  devServer:{
    proxy:{
      '/api':{
        target:'http://118.190.39.123:8877/ ',  // http://118.190.39.123:8877/  === /api
        pathRewrite:{
          '^/api':''  // 重写
        }
      }
    }
  }
})

实现路由跳转页代码:

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeOne from '../views/HomeOne.vue'
Vue.use(VueRouter)
const routes = [
  {
    path: '/',
    name: 'HomeOne',
    component: HomeOne
  },
  {
    path: '/Details',
    name: 'Details',
    component: ()=>import('@/views/Details.vue')
  },
]
const router = new VueRouter({
  // 只有调用了history.pushState()的时候才会触发这个方法
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
  // 使用这个方法实现期望滚动到哪一位置,
  scrollBehavior (to, from, savedPosition) {
    console.log(to,from,savedPosition);
    // 滚动到锚点
    if (to.hash) {
      return {
        selector: to.hash,
        // 平滑滚动
        behavior: 'smooth',
      }
    }
  }
})
export default router

根页面代码:

<template>
  <div id="app">
    <!-- 头部 -->
    <div class="HomeTop">
      <!-- 更多 -->
      <div class="dian">
        <span></span>
      </div>
    </div>
    <!-- 返回顶部 -->
    <router-link tag="div" to="#app" class="back">▲</router-link>
    <router-view></router-view>
    <!-- 底部 -->
    <div class="bottom">Copyright © 2022 AlloyTeam</div>
  </div>
</template>
<script>
export default {};
</script>
<style lang="scss">
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-size: 16px;
}
</style>
<style lang="scss" scoped>
#app {
  .HomeTop {
    width: 100%;
    height: 0.42rem;
    padding: 0 0.15rem;
    // background-color: red;
    border-bottom: 1px solid #ece7e7;
    display: flex;
    align-items: center;
    .dian {
      width: 0.17rem;
      height: 0.15rem;
      border-top: 1px solid black;
      border-bottom: 1px solid black;
      display: flex;
      align-items: center;
      span {
        display: inline-block;
        width: 100%;
        height: 1px;
        background-color: black;
      }
    }
  }
  .back {
    width: 0.4rem;
    height: 0.4rem;
    text-align: center;
    line-height: 0.4rem;
    background-color: rgba(0, 0, 0, 0.1);
    position: fixed;
    bottom: 0.4rem;
    right: 0.15rem;
    font-size: 0.17rem;
  }
  .bottom {
    color: rgba(0, 0, 0, 0.44);
    font-size: 0.12rem;
    text-align: center;
    margin: 0.4rem 0 0.1rem;
  }
}
</style>

列表页代码:

<template>
  <div class="box">
    <div class="HomeTitle">
      <h1>AlloyTeam</h1>
      <p>腾讯全端 AlloyTeam 团队 Blog</p>
    </div>
    <ul class="HomeList">
      <!-- 循环 -->
      <li v-for="item in list" :key="item.id">
        <!-- 文章标签 数组转换为字符串 -->
        <p class="web">{{ item.tags.toString() }}</p>
        <!-- 标题,点击跳转到详情 -->
        <h1 class="title" @click="next(item.id)">{{ item.title }}</h1>
        <!-- 作者和图片 -->
        <span class="author">
          <!-- <img :src="item.avatar" alt="" /> -->
          {{ item.author }}
        </span>
        <p class="separator">
          <!-- 使用dayjs转换时间格式 -->
          {{ dayjs(item.date).format("YYYY-MM-DD") }} /
          <!-- 用正则方法获取浏览次数 -->
          {{ item.separator.match(/\d+/g).toString() }} 次浏览
        </p>
        <!-- 概述 -->
        <p class="content">{{ item.summary }}</p>
      </li>
    </ul>
    <div class="bottom">
      <!-- 跳转到上一页 -->
      <router-link
        :to="{ name: 'HomeOne', query: { id: this.id } }"
        class="next"
        v-show="nextds"
        ><button @click="nextd">上一页</button></router-link
      >
      <!-- 跳转到下一页 -->
      <router-link
        :to="{ name: 'HomeOne', query: { id: this.id } }"
        class="next"
        v-show="nextss"
        ><button @click="nexts">下一页</button></router-link
      >
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [],
      id: localStorage.getItem("id") || [1],
      nextds: false,
      nextss: true,
    };
  },
  created() {
    localStorage.setItem("id", this.id);
    // 进入时直接调用 axios 接口
    this.request();
    // 进入时直接调用 上下页按钮是否显示
    this.click();
  },
  methods: {
    nexts() {
      // 页数加一
      this.id++;
      // 存储至本地
      localStorage.setItem("id", this.id);
      // 调用 axios 请求
      this.request();
      // 调用上下页按钮是否显示
      this.click();
      // 回到顶部
      document.documentElement.scrollTop = 0;
    },
    // 上一页
    nextd() {
      // 页数减一
      this.id--;
      // 存储至本地
      localStorage.setItem("id", this.id);
      // 调用 axios 请求
      this.request();
      // 调用上下页按钮是否显示
      this.click();
      // 回到顶部
      document.documentElement.scrollTop = 0;
    },
    // 点击上下页按钮是否显示
    click() {
      // 判断上一页点击按钮是否显示
      this.id >= 2 ? (this.nextds = true) : (this.nextds = false);
      // 判断下一页点击按钮是否显示
      this.id >= 3 ? (this.nextss = false) : (this.nextss = true);
    },
    request() {
      // axios 请求 页面1,每个页面5个
      this.$axios
        .get(`/api/articles?page=${localStorage.getItem("id")}&limit=5`)
        .then(({ data }) => {
          console.log(data.results);
          // 请求的值赋值给list
          this.list = data.results;
        });
    },
    // 点击进入详情
    next(id) {
      // console.log(id);
      this.$router.push({
        name: "Details",
        query: { id: id },
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.box {
  width: 100%;
  height: 100%;
  .HomeTitle {
    width: 100%;
    // height: 2rem;
    margin: 0.6rem 0;
    // background-color: pink;
    text-align: center;
    overflow: hidden;
    h1 {
      font-size: 0.41rem;
      margin: 0 0 0.1rem;
    }
    p {
      font-size: 0.14rem;
      color: #818181;
      text-transform: uppercase;
      letter-spacing: 0.02rem;
    }
  }
  .HomeList {
    li {
      padding: 0.15rem;
      text-align: center;
      border-bottom: 1px solid #f2f2f2;
      .web {
        font-size: 0.1rem;
        color: #c39f76;
        text-transform: uppercase;
        letter-spacing: 0.02rem;
      }
      .title {
        font-size: 0.2rem;
        margin: 0.13rem 0;
      }
      .author {
        color: #939393;
      }
      .separator {
        margin: 0.12rem 0;
        font-size: 0.1rem;
        color: #939393;
      }
      .content {
        margin: 0.12rem 0 0.13rem;
        text-align: left;
        color: rgba(0, 0, 0, 0.7);
        display: -webkit-box; //对象作为弹性伸缩盒子模型显示
        overflow: hidden; //溢出隐藏
        -webkit-box-orient: vertical; //设置伸缩盒子对象的子元素的排列方式
        -webkit-line-clamp: 3; //设置 块元素包含的文本行数
      }
    }
  }
  .bottom {
    margin: 0.15rem;
    position: relative;
    .next:first-child {
      position: absolute;
      left: 0;
    }
    .next:last-child {
      position: absolute;
      right: 0;
    }
  }
}
</style>

列表页分页效果

看 axios 的页数显示显示几页
按页数判断上下页按钮是否显示
并把页数保存至本地

详情页代码:

<template>
  <div class="box">
    <!-- 文章标签 数组转换为字符串 -->
    <p class="web">{{ list.tags.toString() }}</p>
    <!-- 标题 -->
    <h1 class="title">{{ list.title }}</h1>
    <!-- 图片和作者 -->
    <span class="author">
      <!-- <img :src="list.avatar" alt="" /> -->
      {{ list.author }}
    </span>
    <!-- 使用dayjs转换时间格式 -->
    <p class="separator">
      {{ dayjs(list.date).format("YYYY-MM-DD") }} /
      <!-- 用正则方法获取浏览次数 -->
      {{ list.separator.match(/\d+/g).toString() }} 次浏览
    </p>
    <!-- 内容,里面有其他标签使用v-html输出 -->
    <p v-html="list.content" class="content"></p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [],
    };
  },
  created() {
    // 进入时直接调用
    this.request();
  },
  methods: {
    request() {
      // axios 请求 点击列表的详情
      this.$axios
        .post(`/api/articles/${this.$route.query.id}`)
        .then(({ data }) => {
          console.log(data);
          // 请求到的值赋值给list
          this.list = data;
        });
    },
  },
};
</script>
<style lang="scss" scoped>
.box {
  text-align: center;
  .content {
    text-align: left;
    padding: 0.44rem 0.15rem 0;
    overflow: hidden;
    img {
      display: inline-block;
      width: 3.75rem;
    }
  }
  .web {
    font-size: 0.1rem;
    color: #c39f76;
    text-transform: uppercase;
    letter-spacing: 0.02rem;
  }
  .title {
    font-size: 0.2rem;
    margin: 0.13rem 0;
  }
  .author {
    color: #939393;
  }
  .separator {
    margin: 0.12rem 0;
    font-size: 0.1rem;
    color: #939393;
  }
}
</style>

以上就是AlloyTeam(腾讯全端博客)的代码,不懂得也可以在评论区里问我,以后会持续添加一些新的功能,敬请关注。

相关文章
|
10月前
|
分布式计算 安全 算法
「隐语开源社区开放日」全场精华合集(附视频+原文稿件)
「隐语开源社区开放日」全场精华合集(附视频+原文稿件)
118 0
「隐语开源社区开放日」全场精华合集(附视频+原文稿件)
|
12月前
《淘宝交付之道》出版!大淘宝技术36个月匠心之作
《淘宝交付之道》出版!大淘宝技术36个月匠心之作
|
程序员
2019 CSDN博客之星第三名,感谢各位支持
2019 CSDN博客之星第三名,感谢各位支持
2019 CSDN博客之星第三名,感谢各位支持
|
JavaScript Java 应用服务中间件
从 0 开始搭建一个技术博客,私藏干货~
技术博客的选型有很多种,如:博客园、CSDN、开源中国、简书、知乎等……都可以用来写文章,形成自己的技术博客。 上面的博客都是第三方的,有没有方式搭建自己的服务器、自己的域名的博客呢?栈长知道的成熟方案有:WordPress, Hexo 等,栈长的博客就是用 Hexo 搭建的。
876 0
从 0 开始搭建一个技术博客,私藏干货~
|
新零售 搜索推荐 NoSQL
今日头条这么牛逼,用了什么技术?
今日头条创立于2012年3月,到目前仅 6 年时间。从十几个工程师开始研发,到上百人,再到200余人。产品线由内涵段子,到今日头条,今日特卖,今日电影等产品线。
3652 0
|
编解码 网络协议 视频直播
腾讯技术分享:微信小程序音视频技术背后的故事
1、引言 微信小程序自2017年1月9日正式对外公布以来,越来越受到关注和重视,小程序上的各种技术体验也越来越丰富。而音视频作为高速移动网络时代下增长最快的应用形式之一,在微信小程序中也当然不能错过。
3339 0
|
JavaScript 开发工具 git
搭建自己的个性博客平台
每次百度问题看到别人的个性博客,都纳闷是怎么来的,本教程教你搭建一个自己的个性博客平台。采用当前流行的博客开源框架hexo+oschina,别问为啥不用github~~~支持国产,哈哈哈 1、准备工作 本地安装nodejs环境 oschina帐号...
1186 0