黑马头条vue2.0项目实战(七)——文章详情

因为奋斗超太帅啦 2024-09-09 11:03:01 阅读 79

目录

1. 创建组件并配置路由

2. 页面布局

3. 展示文章详情

3.1 请求文章详情数据接口

4. 关于后端返回数据中的大数字问题

4.1 请求文章详情返回 404 问题

4.2 大整数解决方案

5. 处理内容加载状态

​编辑

6. 关于文章正文的样式

7. 图片点击预览

8. 关注用户

8.1 视图处理与功能处理

8.2 loading 效果

8.3 组件封装

9. 文章收藏

9.1 封装组件

9.2 处理视图

9.3 功能处理

10. 文章点赞

11. 分享功能

12. 组件中的 v-model

12.1 $event 就是传递过来的参数

12.2 v-model 默认方式

12.3 自定义 v-model 的属性名和事件名


fee531b4d2214cabb89eb82fc9b00f30.png

1. 创建组件并配置路由

① 创建 views/article/index.vue 组件

② 然后将该页面配置到根级路由

根据文章的 id 获取文章的详情内容

开启 prop传参,就是把路由中 params 传递的参数映射为组件中的 props 参数。

虽然通过 $route.params.articleId 的方式也能拿到,但是这个 articleId 需要再组件能频繁使用,所以可以使用该种快捷方式映射参数

官方文档:路由 props 传参

传递过来的参数可能是 number 类型也可能是 string 类型

如果通过点击文章列表项进来(to 路由的方式跳转过来),那么传递的过来的 id 的类型就是 number 类型,因为原始的 id 就是 number 类型

但是如果是通过地址的方式直接访问该页面,那么就是 string 类型,如:http://localhost:8080/#/article/11502073-e4c5-4254-887f-17eba7f1ba88

JSONBig.parse() 转化出来的大数字是一个对象,所以也可能是 object 类型

10e3e7fc98b8487d9b9ad51ce4d0da58.png

36c187b0b3454b8892968be7863e9a70.png

2. 页面布局

使用到的 Vant 中的组件:

NavBar 导航栏

Loading 加载

Cell 单元格

Button 按钮

Image 图片

Divider 分割线

Icon 图标

3. 展示文章详情

思路:

找到数据接口

封装请求方法

请求获取数据

模板绑定

3.1 请求文章详情数据接口

① 在 api/article.js 中新增封装接口方法

d72f21852e9c4a3a9bab2ed01188a245.png

② 在组件中调用获取文章详情

eb2c3a4e97c346e289658052b0f499cd.png

③ 在created 生命周期函数中调用

db9dfdb73b234680a58261fe3ff63b09.png

④ 模板绑定

4. 关于后端返回数据中的大数字问题

4.1 请求文章详情返回 404 问题

之所以请求文章详情返回 404 是因为我们请求发送的文章 ID (article.art_id)不正确。JavaScript 能够准确表示的整数范围在-2^532^53之间(不含两个端点),超过这个范围,无法精确表示这个值,这使得 JavaScript 不适合进行科学和金融方面的精确计算。

9cbc74dc499446cf97c1a159e108f0b0.png

上面代码中,超出 2 的 53 次方之后,一个数就不精确了。 ES6 引入了Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。

20b225e3e8de44619d118a637dfeb4b4.png

上面代码中,可以看到 JavaScript 能够精确表示的极限。

后端返回的数据一般都是 JSON 格式的字符串

e83acc4f8a8e4b28b1698872b6717b0d.png

47437736d4704051880b0192967177e3.png

如果这个字符不做任何处理,你能方便的获取到字符串中的指定数据吗?非常麻烦。所以我们要把它转换为 JavaScript 对象来使用就很方便了。幸运的是 axios 为了方便我们使用数据,它会在内部使用 JSON.parse() 把后端返回的数据转为 JavaScript 对象。

// { id: 9007199254740996, name: 'Jack', age: 18 }

JSON.parse('{ "id": 9007199254740995, "name": "Jack", "age": 18 }')

可以看到,超出安全整数范围的 id 无法精确表示,这个问题并不是 axios 的错。

4.2 大整数解决方案

了解了什么是大整数的概念,接下来的问题是如何解决?

json-bigint 是一个第三方包,它可以帮我们很好的处理这个问题。使用步骤:

使用它的第一步就是把它安装到你的项目中。

npm i json-bigint导入到项目中

import JSONBig from 'json-bigint'

a233e5b213b84943a8fff077e0dc8b9e.png

JSONBig.parse() 把 JSON 格式的字符串转化为 js 对象

JSONBig.stringify() 把 js 对象转为 JSON 格式的字符串

JSONBig与原始 JSON 方法的区别就是上面的两个可以处理大数字的问题,不丢失精度

json-bigint 会把超出 JS 安全整数范围的数字转为一个 BigNumber 类型的对象,对象数据是它内部的一个算法处理之后的,我们要做的就是在使用的时候转为字符串来使用。

8d622769dee840edab6fdad5af9c3a16.png

通过 Axios 请求得到的数据都是 Axios 处理(JSON.parse)之后的,我们应该在 Axios 执行处理之前手动使用 json-bigint 来解析处理。Axios 提供了自定义处理原始后端返回数据的 API:transformResponse

axios官网GitHub - axios/axios: Promise based HTTP client for the browser and node.js:GitHub - axios/axios: Promise based HTTP client for the browser and node.js

f6ca3a6e7d9d43d4b46f22188e78f1ac.png

复制上述的代码,在 src/utils/request.js 下导入 json-bigint 进行配置

cc3a549f403e4ae6af9659277a6df346.png

扩展:ES2020 BigInt

ES2020 引入了一种新的数据类型 BigInt(大整数),来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

参考链接:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/BigInt

ES6 入门教程

5. 处理内容加载状态

需求:

加载中,显示 loading

加载成功,显示文章详情

加载失败,显示错误提示

如果 404,提示资源不存在

其它的,提示加载失败,用户可以点击重试重新加载

58f8aad544144436bf26160ebb9e26df.png

e291d2a68f4a4ad6889ff147175afcdc.png

5cf25fa401ce4450a061dc0dcdaddcab.png

6. 关于文章正文的样式

9ed77edf546b4e1e980058588e14e011.png

文章正文包括各种数据:段落、标题、列表、链接、图片、视频等资源。

将 github-markdown-css 样式文件下载到项目中

e3034379a75b4f35a1bf1b15b9aed893.png

引入下载的 css 文件,添加作用的 class 类名

6aa8c648ccc849ca9d97822e7763d4e8.png

e214480a6f61474782c76205f5cad059.png

在 postcss 中配置不要转换样式文件中的字号

4cfe47828b704065b23a0df174a8bf38.png

7. 图片点击预览

① ImagePreview 图片预览 的使用

ddeb051a0b1a4374b16946f3350c173f.png

c722b174f0754fc99828d93af0207278.png

② 处理图片点击预览

思路:

从文章内容中获取到所有的 img DOM 节点获取文章内容中所有的图片地址遍历所有 img 节点,给每个节点注册点击事件在 img 点击事件处理函数中,调用 ImagePreview 预览

代码实现:

预览图片效果函数

9cfb2836402841bfb49aef10a60007e7.png

50022e931bdf4996a8bfaf24ba80ea2a.png

6aaf6a345c0645db9d4353cdab0e6e6e.png

console.log(this.$refs.article_content) // undefined

原因:拿不到,因为 Vue 更新 DOM 是异步的,此时使用 $nextTick 解决 或者使用延时函数延时 0秒

解决方案一:延时函数

11591061b4654c61aac9c3ffcd97d3b8.png

解决方案二:$nextTick 解决,一次拿不到就两次。

3779a0d3ef43417fb1c8e24a37dcea16.png

8. 关注用户

思路:

给按钮注册点击事件

在事件处理函数中

如果已关注,则取消关注

如果没有关注,则添加关注

下面是具体实现。

8.1 视图处理与功能处理

视图处理

82853c4baa924387a69ec5fb1fe75efa.png

功能处理

找到数据接口

封装请求方法

请求调用

视图更新

① 在 api/follow.js 中添加封装请求方法

dc239284214d4b798c7a1bd04f30f1c2.png

② 给关注/取消关注按钮注册点击事件

6daa4ec147be4e5c84ce51f4e7f36536.png

③ 在事件处理函数中

04e2e6dfed0b422496d03d74528b3df9.png

8.2 loading 效果

两个作用:

交互反馈

防止网络慢用户多次点击按钮导致重复触发点击事件

4888ba5dae1e493a90fca4dbb9b804b2.png

8.3 组件封装

9439998e03964497b43f1c1b3ff852fb.png

9. 文章收藏

9.1 封装组件

5eead81d8dc04783be4c63ac7e736b1e.png

9.2 处理视图

890a0dd9e47c41ef979a6510474d4bb3.png

42ee23e4cff144f39d063ebb24b032e4.png

9.3 功能处理

思路:

给收藏按钮注册点击事件

如果已经收藏了,则取消收藏

如果没有收藏,则添加收藏

下面是具体实现。

① 在 api/article.js 添加封装数据接口

75567b98a1334213874c30d455108ecf.png

② 给收藏按钮注册点击事件

③ 处理函数

6d519b164dbe440a806d9f03b88caca6.png

10. 文章点赞

article 中的 attitude 表示用户对文章的态度

-1 无态度

0 不喜欢

1 已点赞

思路:

给点赞按钮注册点击事件

如果已经点赞,则请求取消点赞

如果没有点赞,则请求点赞

① 添加封装数据接口

2ae871b9b2aa4d2aa389a8ab9c960a36.png

② 封装组件

ba890665d36b42e79be1db1beb315499.png

③ 给点赞按钮注册点击事件

9ca072bdd53a4ee9b5b271e47ff63807.png

④ 处理函数

f8bf9bf806c84b7ebe2d2b215d690d89.png

11. 分享功能

ShareSheet 分享面板: Vant 2 - Mobile UI Components built on Vue

9358838c1c334b2aa3dc2569a9a0a6df.png

ca8d3ef599c64b2d846b13f7a9403596.png

12. 组件中的 v-model

12.1 $event 就是传递过来的参数

子组件:

e8f0c8607e3148a98a365c148b517e3f.png

父组件:

e6ee1ad2d13746ada0aa4eec710cb7b7.png

12.2 v-model 默认方式

当我们传递给子组件的数据既要使用还有修改的时候,

传递: props修改:自定义事件

简写方式:在父组件组件上使用 v-model

默认传递 :value="count"

默认监听:@input="count = $event"

父组件:

fdccce0d88934cd79884b9c3db95014a.png

子组件:

2d2ae90656db411b8c849e44f6fbbb7b.png

12.3 自定义 v-model 的属性名和事件名

如果需要修改 v-model 的规则名称,可以通过子组件的 model 属性来配置修改。一个组件上只能使用一次 v-model

父组件:

20e598d502794c34a089773cc1b3cfb8.png

子组件:

1192508c3865408287a2197a8954c776.png

12.4 .sync 修饰符

如果有多个数据需要保持同步,使用 .sync 修饰符,因为 v-model 在组件中只能使用一次。

子组件内使用不变。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。