当前位置: 首页 > news >正文

黑马头条vue2.0项目实战(四)——首页—文章列表

目录

1. 头部导航栏

1.1 页面布局

1.2 样式调整中遇到的问题

2. 频道列表

2.1 页面布局

2.2 样式调整

2.3 展示频道列表

3. 文章列表

3.1 思路分析

3.2 使用 List 列表组件

3.3 加载文章列表数据

3.4 下拉刷新

3.5 设置上下padding固定头部和频道列表

3.6 记住列表的滚动位置

4. 文章列表项

4.1 准备组件

4.2 展示列表项内容

4.3 样式调整

4.4 关于第三方图片资源403问题

4.5 处理相对时间


1. 头部导航栏

1.1 页面布局

  • 使用导航栏组件(NavBar 导航栏)

  • 在导航栏组件中插入按钮:文本、图标
  • 样式调整:宽高、背景色、边框、文本大小、图标大小

1.2 样式调整中遇到的问题

  • 问题:给 button 按钮按照设计图设置样式之后,但是在网页中无法生效,显示不全,如下图所示。

  • 原因:检查元素发现 button 按钮的父级元素的父级使用了flex布局,并且给 button 按钮的宽度设置了最大宽度为 60%,而 button 按钮的宽度大于父级元素的最大宽度 60%,所以导致 button 按钮显示不全,如下图所示。
    • 此时在 css 中给button 按钮的父级元素的最大宽度设置为 80% ,完成样式覆盖即可。
    • 但设置的最大宽度为 80% 无法生效,检查元素发现 button 按钮的父级元素的最大宽度依然是 60%,无法完成样式覆盖。

  • 解决方法:由于 Vant 组件库可能有更高优先级的样式,可以使用深度选择器来确保样式覆盖。

2. 频道列表

2.1 页面布局

使用 Tab 标签页组件

  • 通过 animated 属性可以开启切换标签内容时的转场动画。

  • 通过 swipeable 属性可以开启滑动切换标签页。

2.2 样式调整

① 基础样式调整

  • 标签项:右边框、下边框、宽高、文字大小、文字颜色

  • 底部条:宽高、颜色、位置

② 处理汉堡按钮

  • 使用插槽插入内容
  • 样式调整:定位、内容居中、宽高、背景色、透明度、字体图标大小
  • 使用伪元素设置渐变边框:定位、宽高、背景图、背景图填充模式

2.3 展示频道列表

思路:

        ① 找数据接口

        ② 把接口封装为请求方法

        ③ 在组件中请求获取数据

        ④ 模板绑定

3. 文章列表

3.1 思路分析

你的思路可能是这样的:

        ① 找到数据接口

        ② 封装请求方法

        ③ 在组件中请求获取数据,将数据存储到 data 中

        ④ 模板绑定展示

根据不同的频道加载不同的文章列表,你的思路可能是这样的:

  • 有一个 list 数组,用来存储文章列表

  • 查看 a 频道:请求获取数据,让 list = a 频道文章

  • 查看 b 频道:请求获取数据,让 list = b 频道文章

  • 查看 c 频道:请求获取数据,让 list = c 频道文章

思路没有问题,但是并不是我们想要的效果。

我们想要的效果是:加载过的数据列表不要重新加载

实现思路也非常简单,就是我们准备多个 list 数组,每个频道对应一个,查看哪个频道就把数据往哪个频道的列表数组中存放,这样的话就不会导致覆盖问题

可是有多少频道就得有多少频道文章数组,我们都一个一个声明的话会非常麻烦,所以这里的建议是利用组件来处理。

具体做法就是:

  • 封装一个文章列表组件

  • 然后在频道列表中把文章列表遍历出来

因为文章列表组件中请求获取文章列表数据需要频道 id,所以 频道 id 应该作为 props 参数传递给文章列表组件,为了方便,我们直接把频道对象传递给文章列表组件就可以了。

在文章列表中请求获取对应的列表数据,展示到列表中。

最后把组件在频道列表中遍历出来,就像下面这样。

  • 创建 src/views/home/components/article-list.vue(因为该组件不是多个页面都会用到的组件,只有在home中用到,所以方便管理,可以在当前文件夹下创建组件)
  • home/index.vue 中注册使用
  • 使用 keepAlive 组件缓存技术提高性能

为什么标签内容是懒渲染的?

  • 因为这是 Tab 标签页组件本身支持的默认功能,如果不需要可以通过配置 :lazy-render="false" 来关闭这个效果。

3.2 使用 List 列表组件

List 列表组件:瀑布流滚动加载,用于展示长列表。

List 组件通过 loading 和 finished 两个变量控制加载状态, 当组件初始化或滚动到到底部时,会触发 load 事件并将 loading 设置成 true,此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。 若数据已全部加载完毕,则直接将 finished 设置成 true 即可。

  • load 事件

    • List 初始化后会触发一次 load 事件,用于加载第一屏的数据。

    • 如果一次请求加载的数据条数较少,导致列表内容无法铺满当前屏幕,List 会继续触发 load 事件,直到内容铺满屏幕或数据全部加载完成。

  • loading 属性:控制加载中的 loading 状态

    • 非加载中,loading 为 false,此时会根据列表滚动位置判断是否触发 load 事件(列表内容不足一屏幕时,会直接触发)

    • 加载中,loading 为 true,表示正在发送异步请求,此时不会触发 load 事件

  • finished 属性:控制加载结束的状态

    • 在每次请求完毕后,需要手动将 loading 设置为 false,表示本次加载结束

    • 所有数据加载结束,finished 为 true,此时不会触发 load 事件

3.3 加载文章列表数据

实现思路:

  • 找到数据接口

  • 封装请求方法

    • 创建 src/api/article.js 封装获取文章列表数据的接口

  • 请求获取数据

    • 然后在首页文章列表组件 onload 的时候请求加载文章列表

  • 模板绑定

3.4 下拉刷新

这里主要使用到 Vant 中的 PullRefresh 下拉刷新 组件。

思路:

  • 注册下拉刷新事件(组件)的处理函数

  • 发送请求获取文章列表数据

  • 把获取到的数据添加到当前频道的文章列表的顶部

  • 关闭下拉刷新的 loading 状态

  • 提示用户刷新成功!

下拉刷新时会触发组件的 refresh 事件,在事件的回调函数中可以进行同步或异步操作,操作完成后将 v-model 设置为 false,表示加载完成。

3.5 设置上下padding固定头部和频道列表

  • 在 home/index.vue 的根节点上设置上下的 padding,保证列表数据完全显示。
  • 固定头部导航栏和频道列表的位置

头部导航栏固定定位:

频道列表固定定位:

  •  sticky  是否使用粘性定位布局

  • offset-top v2.8.7 粘性定位布局下与顶部的最小距离,支持 px vw vh rem 单位,默认 px

    • postcssrc 不能转换行内样式中的 px,所以页面多少,行内样式写多少

3.6 记住列表的滚动位置

  • 问题:如下图所示,在频道为 c++ 页面向下滚动列表到某个位置,如《手把手教你mockjs实际项目快速搭建》的位置。

        此时切换到其他频道查看列表数据,如 css 频道,再次切回 c++ 频道的时候,发现列表又回到的初始的位置,造成用户体验效果不好。我们希望记住某个频道列表滚动的位置,这样在用户查看某个频道下的数据,来回切换列表的时候,该频道下显示的依然是用户刚刚滚动过的列表的位置。

  • 为什么列表滚动会相互影响?

    • 因为他们并不是在自己内部进行滚动,而是在整个 body 页面在滚动。

    • 无论你是在 a 频道还是在 b 频道,其实滚动的都是 body 元素。

  • 这里分享一个小技巧:如何快速找到是那个元素产生的滚动?

        把下面的代码粘贴到浏览器调试工具中运行一下,然后滚动页面,就可以看到是那个元素产生的滚动了。

function findScroller(element) {element.onscroll = function() {console.log(element)}Array.from(element.children).forEach(findScroller)
}findScroller(document.body)

        如下图所示,浏览器输出的元素为 body 标签,说明滚动的元素 body。

  • 解决方案: 让每一个标签内容文章列表产生自己的滚动容器,这样就不会相互影响了。
  • 如何让标签内容文章列表产生自己的滚动容器呢?
    • 固定高度: height: xxx
    • 溢出滚动: overflow-y: auto
  • 然后给我们的文章列表组件的根节点样式设置如下:
.article-list {height: 100%;overflow: auto;
}
  • 但是我们发现设置高 100% 的话没有用,这是为什么?
    • 因为百分比是相对于父元素,而我们通过审查元素发现所有的父元素都没有高,那么肯定没有作用了。

  • 难道我们为了让这个子元素高度百分百,就一个一个的把所有的父元素都设置高百分百吗?
    • 虽然可以但是不可取,太麻烦了。
  • 最优解决方案:
    • css3 中新增了一种视口单位 vw 和 vh,何谓视口,就是根据你的浏览器窗口的大小的单位,不受父元素的影响。
    • 在移动端,视口单位相对于布局视口。

    • 1 vw = 可视窗口宽度的百分之一,比如窗口的宽度是 750,则 1 vw = 7.5 px。

    • 1 vh = 可视窗口高度的百分之一,比如窗口的高度是 667,则 1 vw = 6.67 px。

    • 使用它唯一需要注意的就是他的兼容性:pc 端已经兼容到了 IE 9,在移动端 iOS 8 以上以及 Android 4.4 以上获得支持,并且在微信 x5 内核中也得到了完美的全面支持,vue 本身值都只兼容到了 IE 9,所以可以使用这个视口单位。

    • 所以最终的设置的代码如下:

      • height: 79vh,是根据调试工具调试而来,也就是文章列表实际的所占的视口高度大小。

4. 文章列表项

4.1 准备组件

在我们项目中有好几个页面中都有这个文章列表项内容,如果我们在每个页面中都写一次的话不仅效率低而且维护起来也麻烦。所以最好的办法就是我们把它封装为一个组件,然后在需要使用的组件中加载使用即可。

① 创建 src/components/article-item/index.vue 组件

② 在文章列表组件中注册使用文章列表项组件

4.2 展示列表项内容

  • 使用 Cell 单元格组件

  • 展示标题

  • 展示底部信息

4.3 样式调整

vant 内置样式:Vant 中默认包含了一些常用样式,可以直接通过 className 的方式使用。

如:

其他的看文档。

4.4 关于第三方图片资源403问题

  • 为什么文章列表数据中的好多图片资源请求失败返回 403?
    • 这是因为我们项目的接口数据是后端通过爬虫抓取的第三方平台内容,而第三方平台对图片资源做了防盗链保护处理。
  • 第三方平台怎么处理图片资源保护的?
    • 服务端一般使用 Referer 请求头识别访问来源,然后处理资源访问。

  • Referer 是什么东西?
    • 扩展参考: HTTP Referer 教程 - 阮一峰的网络日志
    • Referer 是 HTTP 请求头的一部分,当浏览器向 Web 服务器发送请求的时候,一般会带上 Referer,它包含了当前请求资源的来源页面的地址。服务端一般使用 Referer 请求头识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。
    • 需要注意的是 referer 实际上是 "referrer" 误拼写。参见 HTTP referer on Wikipedia (HTTP referer 在维基百科上的条目)来获取更详细的信息。
  • 怎么解决?
    • 不要发送 referrer ,对方服务端就不知道你从哪来的了,姑且认为是你是自己人吧。
  • 如何设置不发送 referrer?
    • <a><area><img><iframe><script> 或者 <link> 元素上的 referrerpolicy 属性为其设置独立的请求策略,例如:
    • 或者直接在 HTMl 页面头中通过 meta 属性全局配置:

4.5 处理相对时间

推荐两个第三方库:

  • Moment.js

  • Day.js

两者都是专门用于处理时间的 JavaScript 库,功能差不多,因为 Day.js 的设计就是参考的 Moment.js。但是 Day.js 相比 Moment.js 的包体积要更小一些,因为它采用了插件化的处理方式。

Day.js 是一个轻量的处理时间和日期的 JavaScript 库,和 Moment.js 的 API 设计保持完全一样,如果您曾经用过 Moment.js, 那么您已经知道如何使用 Day.js 。

  • Day.js 可以运行在浏览器和 Node.js 中。

  • 🕒 和 Moment.js 相同的 API 和用法

  • 💪 不可变数据 (Immutable)

  • 🔥 支持链式操作 (Chainable)

  • 🌐 国际化 I18n

  • 📦 仅 2kb 大小的微型库

  • 👫 全浏览器兼容

使用步骤:

        ① 安装:npm i dayjs 或者 yarn add dayjs

        ② 创建 utils/dayjs.js。具体使用配置以及用到的哪些插件或方法,看文档。

        ③ 在 main.js 中加载初始化

        ④ 使用全局过滤器

相关文章:

黑马头条vue2.0项目实战(四)——首页—文章列表

目录 1. 头部导航栏 1.1 页面布局 1.2 样式调整中遇到的问题 2. 频道列表 2.1 页面布局 2.2 样式调整 2.3 展示频道列表 3. 文章列表 3.1 思路分析 3.2 使用 List 列表组件 3.3 加载文章列表数据 3.4 下拉刷新 3.5 设置上下padding固定头部和频道列表 3.6 记住列…...

UE5.4内容示例(4)UI_UMG - 学习笔记

https://www.unrealengine.com/marketplace/zh-CN/product/content-examples 《内容示例》是学习UE5的基础示例&#xff0c;可以用此熟悉一遍UE5的功能 UI示例 UI_UMG &#xff1a;基本UMGUI_CommonUI &#xff1a;UMG多层应用UI_SlatePostBuffer UI &#xff1a;FX的示例&…...

C#实现数据采集系统-配置文件化

系统优化-配置 配置信息ip端口,还有点位信息,什么的都是直接在代码里直接写死,添加点位,修改配置,比较麻烦,每次修改都需要重新生成打包。 所以将这些配置都改成配置文件,这样只需要修改配置文件,程序无须修改,即可更新。 配置代码: 如果我们有100个采集,一个个去…...

Java面试题 -- 为什么重写equals就一定要重写hashcode方法

在回答这个问题之前我们先要了解equals与hascode方法的本质是做什么的 1. equals方法 public boolean equals(Object obj) {return (this obj);}我们可以看到equals在不重写的情况下是使用判断地址值是否相同 所以默认的 equals 的逻辑就是判断的双方是否引用了一个对象&am…...

J031_使用TCP协议支持与多个客户端同时通信

一、需求文档 使用TCP协议支持与多个客户端同时通信。 1.1 Client package com.itheima.tcp2;import java.io.DataOutputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner;public class Client {public static void main(String[] a…...

二分查找(精确查找、范围搜索)

目录 1. 二分查找概述2. 精确查找2.1 【left&#xff0c;right】2. 2 【left&#xff0c;right&#xff09; 3. 范围查找总结 1. 二分查找概述 二分查找法&#xff0c;也称为二分搜索法或折半查找法&#xff0c;是一种在有序数组中查找特定元素的搜索算法。其基本思想是&#x…...

软件工程简记

文章目录 一、软件工程要点之软件设计二、UML(Unified Modeling Language,统一建模语言)(一)UML 的整体分类与部分功能(二)UML 各类图的具体内容三、开发模型(一)多种开发模型的特点与问题四、设计模式(一)设计模式的总体概念与原则(二)软件结构设计原则(三)常见…...

【深度学习】【语音TTS】OpenVoice v2,测评,中英文语料,Docker镜像,对比GPT-SoVITS、FishAudio、BertVITS2

https://github.com/myshell-ai/OpenVoice/blob/main/docs/USAGE.md 实际体验OpenVoice v2的TTS效果。 文章目录 环境启动 jupyter代码代码分析主要模块和功能测试一些别的中文和中英文混合总结优点缺点对比GPT-SoVITS、FishAudio、BertVITS2使用我的Docker镜像快速体验OpenVo…...

Kotlin OpenCV 图像图像50 Haar 级联分类器模型

Kotlin OpenCV 图像图像50 Haar 级联分类器模型 1 OpenCV Haar 级联分类器模型2 Kotlin OpenCV Haar 测试代码 1 OpenCV Haar 级联分类器模型 Haar级联分类器是一种用于对象检测&#xff08;如人脸检测&#xff09;的机器学习算法。它由Paul Viola和Michael Jones在2001年提出…...

嗖嗖移动业务大厅(Java版)

首先对此项目说明一下&#xff0c;我只完成了项目的基本需求&#xff0c;另外增加了一个用户反馈的功能&#xff0c;但是可能项目中间使用嗖嗖这个功能还有一些需要完善的地方&#xff0c;或者还有一些小bug&#xff0c;就当给大家参考一下了&#xff0c;希望谅解。代码我也上传…...

hcia复习笔记

一、OSI 七层模型 应用层&#xff1a;为应用程序提供服务&#xff0c;如文件传输、电子邮件等。 表示层&#xff1a;数据格式转换、加密解密、压缩解压缩。 会话层&#xff1a;建立、维护和管理会话。 传输层&#xff1a;提供端到端的可靠或不可靠的数据传输服务&#xff0…...

pycharm中安装、使用扩展工具,以QT Designer为例

pycharm中安装、使用扩展工具&#xff0c;以QT Designer为例 第一步&#xff0c;下载QT Designer安装包。找到QT Designer.exe所在位置&#xff0c;复制路径 第二步&#xff0c;打开Pycharm&#xff0c;选择Setting&#xff0c;找到扩展工具&#xff08;External Tools&#xf…...

【Rust光年纪】Rust语言实用库汇总:从机器翻译到全文搜索引擎

优秀的Rust语言库探索&#xff1a;机器翻译、音频编解码和全文搜索引擎 前言 Rust语言在近年来迅速崛起&#xff0c;成为了一种备受欢迎的系统级编程语言。随着其生态系统的不断丰富&#xff0c;涌现出了许多优秀的库和工具。本文将重点介绍几个用于Rust语言的重要库&#xf…...

学习笔记 - 二极管的参数与选型

二极管 普通二极管&#xff1a; 1N4148(高频开关二极管) 整流二极管&#xff1a; 1N4007 1A 1000V1N5408 3A 1000V 肖特基二极管 &#xff08;白线边为阴极&#xff09; SS14 SS34 SS54 常见肖特基二极管参数 快恢复二极管 FR107 FR207 FR307 UF4007 可以用快恢复二…...

PMP--冲刺--易混概念

文章目录 十大知识领域一、整合管理项目管理计划与项目文件的区分&#xff1a; 二、范围管理三、进度管理赶工与快速跟进的区分&#xff1a;赶工增加资源&#xff0c;以最小的成本代价来压缩进度工期&#xff1b;快速跟进&#xff0c;将正常情况下按顺序进行的活动或阶段改为至…...

Resolving Maven dependencies

Maven是一种项目管理和构建工具&#xff0c;通常用于Java项目。这个过程包括下载项目所需的所有外部库和插件&#xff0c;并将它们添加到项目的构建路径中。具体来说&#xff0c;它正在处理名为“AAS_byBasyx”的项目或模块的依赖项。这种任务通常在你打开一个新的Maven项目或更…...

【Spring】SSM框架整合Spring和SpringMVC

目录 1.项目结构 2.项目的pom.xml文件 3.spring.xml和springMVC配置文件 4.database.properties和mybatis.xml配置文件 5. 代码编写 6.测试整合结果 1.项目结构 首先创建一个名为ssm_pro的Mavew项目&#xff0c;然后再在主目录和资源目录下&#xff0c;创建如下所示的结…...

优维2024年中思考:大模型赋予新一代运维的“非产品性”启示

近年来&#xff0c;人工智能在各个行业的应用大幅增加&#xff0c;人工智能技术取得重大进步的领域之一是IT运维。 去年四季度&#xff0c;优维科技敏锐地提出“新一代运维核心系统提供商”的战略新定位&#xff0c;决定将“DevOps及运维”回归到“运维”本身&#xff0c;但我…...

【中药网络药理学】筛选细胞衰老和预后相关基因(附分类代码和画图代码)

1、衰老相关基因 从HAGR和msigdb数据获取细胞衰老相关基因&#xff0c;将两者取交集后构建基因蛋白互作网络 HAGR数据库 该库本身提供了下载链接&#xff0c;我在下载后对其进行了清洗 msigdb数据库 以"aging"作为关键词&#xff0c;Search Filters中collection…...

华为的流程体系

缘由 2010年&#xff0c;华为销售额为1850亿元&#xff0c;其中国际市场占65%&#xff0c;净利润238亿元。当时&#xff0c;公司员工达11万人&#xff0c;公司处理合同达5万多个&#xff0c;290万个订单&#xff0c;大量的工作是手工处理&#xff0c;没有统一的流程支持&#…...

算法——长度最小的子数组209 对比代码随想录题解中对于result取值为Integer.MAX_VALUE的思考

具体解题过程可看代码随想录&#xff0c;我主要是对于为什么result也就是子数组和初始化要为Integer.MAX_VALUE有一个疑惑&#xff0c;为什么不是其他值&#xff0c;经过思考后我发现: 情况一&#xff1a;如果result为负数的话是不符合数组长度取值的一个规范的。 情况二&…...

图像处理案例03

HOGSVM数字识别 1 . 步骤2 . 代码 1 . 步骤 读入数据&#xff0c;把数据划分为训练集和测试集用hog提取特征用SVM训练数据测试、评价模型保存模型加载模型&#xff0c;应用模型 2 . 代码 import os import cv2 import sklearn import numpy as np from skimage.feature impo…...

【Kubernetes】k8s集群中kubectl的陈述式资源管理

目录 一.k8s集群资源管理方式分类 1.陈述式资源管理方式 2.声明式资源管理方式 二.陈述式资源管理方法 三.kubectl命令 四.项目生命周期 1.创建 kubectl create命令 2.发布 kubectl expose命令 3.更新 kubectl set 4.回滚 kubectl rollout 5.删除 k…...

串---顺序串实现

顺序串详解 本文档将详细介绍顺序串的基本概念、实现原理及其在 C 语言中的具体应用。通过本指南&#xff0c;读者将了解如何使用顺序串进行各种字符串操作。 1. 什么是顺序串&#xff1f; 顺序串是一种用于存储字符串的数据结构&#xff0c;它使用一组连续的内存空间来保存…...

吴恩达机器学习WEEK2

COURSE1 WEEK2 多维特征 在线性回归中&#xff0c;往往特征不止一个&#xff0c;而是具有多维特征 例如&#xff0c;在预测房价的例子中&#xff0c;我们知道更多的信息&#xff1a; x 1 x_1 x1​&#xff1a;房屋的面积 x 2 x_2 x2​&#xff1a;卧室的数目 x 3 x_3 x3​&a…...

yield and generator in python

首先&#xff0c;假设大家都对于pytyhon的List comprehension的使用有了一定经验&#xff08;它可以用于list&#xff0c;set&#xff0c;和dict哦&#xff09; 不熟悉的参考介绍&#xff1a; Comprehending Python’s Comprehensions – dbader.org generator generator是哦…...

spring原理(自学第六天)

Aware 接口及 InitializingBean 接口 今天将会学到Aware 接口及 InitializingBean 接口 我们可以先了解他们的作用&#xff1a; 1. Aware 接口用于注入一些与容器相关信息, 例如 a. BeanNameAware 注入 bean 的名字 b. BeanFactoryAware 注入…...

案例分享—国外优秀ui设计作品赏析

国外UI设计创意迭出&#xff0c;融合多元文化元素&#xff0c;以极简风搭配动态交互&#xff0c;打造沉浸式体验&#xff0c;色彩运用大胆前卫&#xff0c;引领界面设计新风尚 同时注重用户体验的深度挖掘&#xff0c;通过个性化定制与智能算法结合&#xff0c;让界面不仅美观且…...

【C++】简约与清晰的编程艺术

C编程的艺术&#xff1a;简约与清晰的实践之道 一、基础之美&#xff1a;基本类型与数据结构的力量二、函数与库类的艺术三、简约与清晰的实践之道 在C这一既古老又充满活力的编程语言世界里&#xff0c;程序员们常常面临着一个重要的选择&#xff1a;是追求代码的极致抽象与封…...

java之WIFI信号模块

开发步骤分为以下几点&#xff1a; 1.在 AndroidManifest 中声明相关权限&#xff08;网络和文件读写权限&#xff09; 声明权限: <uses-permission android:name"android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name"android.…...