仿今日头条项目

您所在的位置:网站首页 仿今日头条导航 仿今日头条项目

仿今日头条项目

2023-08-19 07:22| 来源: 网络整理| 查看: 265

1.创建组件并配置路由

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

文章详情 export default { name: 'ArticleIndex', components: {}, props: { articleId: { type: [Number, String], required: true } }, data () { return {} }, computed: {}, watch: {}, created () {}, mounted () {}, methods: {} }

2、然后将该页面配置到根级路由 因为篇文章跳转路径不同,因此使用动态路由:       path: '/article/:articleId',

并用props传参!!!!(props解耦)

{ path: '/article/:articleId', name: 'article', component: () => import('@/views/article'), // 将路由动态参数映射到组件的 props 中,更推荐这种做法 props: true }

3.在首页的文章cell区域添加to属性实现路径跳转

...

其他两种to属性写法(拼接):

1. :to="'/article/' + article.art_id" 

2. :to="`/article/${article.art_id}`" 

2. 页面布局

3.请求获取文章数据

1.找到数据接口

2.封装请求方法

/** * 根据 id 获取指定文章 */ export const getArticleById = articleId => { return request({ method: 'GET', url: `/app/v1_0/articles/${articleId}` }) }

3.请求获取数据

import { getArticleById } from '@/api/article' export default { name: 'ArticlePage', components: {}, props: { articleId: { type: String, required: true } }, data () { return { article: {} // 文章详情 } }, computed: {}, watch: {}, created () { this.loadArticle() }, mounted () {}, methods: { async loadArticle () { try { const { data } = await getArticleById(this.articleId) this.article = data.data } catch (err) { console.log(err) } } } }

bug:404报错(大整数)

因为我们请求发送的文章 ID (article.art_id)不正确

JavaScript 能够准确表示的整数范围在`-2^53`到`2^53`之间(不含两个端点),超过这个范围,无法精确表示这个值,这使得 JavaScript 不适合进行科学和金融方面的精确计算。

解决:json-bigint(第三方包)

1)下载

2)使用

import axios from 'axios' import jsonBig from 'json-bigint' var json = '{ "value" : 9223372036854775807, "v2": 123 }' console.log(jsonBig.parse(json)) const request = axios.create({ baseURL: 'http://ttapi.research.itcast.cn/', // 接口基础路径 // transformResponse 允许自定义原始的响应数据(字符串) transformResponse: [function (data) { try { // 如果转换成功则返回转换的数据结果 return jsonBig.parse(data) } catch (err) { // 如果转换失败,则包装为统一数据格式并返回 return { data } } }] }) export default request

4.模板绑定

4.处理内容加载状态 

- 加载中,显示 loading - 加载成功,显示文章详情 - 加载失败,显示错误提示   - 如果 404,提示资源不存在   - 其它的,提示加载失败,用户可以点击重试重新加载

5.正文样式 

文章正文包括各种数据:段落、标题、列表、链接、图片、视频等资源。 1.github-markdown-css:样式文件下载到项目中 2.配置不要转换样式文件中的字号

6.图片点击预览 

 

1、从文章内容中获取到所有的 img DOM 节点

2、获取文章内容中所有的图片地址

3、遍历所有 img 节点,给每个节点注册点击事件

4、在 img 点击事件处理函数中,调用 ImagePreview 预览

bug:在图片加载成功的时候获取节点(this.$refs['article-content'])不能马上显示,因为数据驱动视图这件事不是立即的

解决:settimeout(function(){},0)

async loadArticle() { // 展示 loading 加载中 this.loading = true try { const { data } = await getArticleById(this.articleId) // if (Math.random() > 0.5) { // JSON.parse('dsankljdnskaljndlkjsa') // } // 数据驱动视图这件事儿不是立即的 this.article = data.data // 初始化图片点击预览 // console.log(this.$refs['article-content']) setTimeout(() => { this.previewImage() }, 0) // 请求成功,关闭 loading // this.loading = false } catch (err) { if (err.response && err.response.status === 404) { this.errStatus = 404 } // this.loading = false // console.log('获取数据失败', err) } // 无论成功还是失败,都需要关闭 loading this.loading = false }, previewImage() { // 得到所有的 img 节点 const articleContent = this.$refs['article-content'] const imgs = articleContent.querySelectorAll('img') // 获取所有 img 地址 const images = [] imgs.forEach((img, index) => { images.push(img.src) // 给每个 img 注册点击事件,在处理函数中调用预览 img.onclick = () => { ImagePreview({ // 预览的图片地址数组 images, // 起始位置,从 0 开始 startPosition: index }) } }) },

 

7.关注用户

- 给按钮注册点击事件 - 在事件处理函数中   - 如果已关注,则取消关注   - 如果没有关注,则添加关注

已关注 关注

1.找到数据接口

2.在 `api/user.js` 中添加封装请求方法

/** * 添加关注 */ export const addFollow = userId => { return request({ method: 'POST', url: '/app/v1_0/user/followings', data: { target: userId } }) } /** * 取消关注 */ export const deleteFollow = userId => { return request({ method: 'DELETE', url: `/app/v1_0/user/followings/${userId}` }) }

3.请求调用并更新视图

import { addFollow, deleteFollow } from '@/api/user' ... async onFollow () { // 开启按钮的 loading 状态 this.isFollowLoading = true try { // 如果已关注,则取消关注 const authorId = this.article.aut_id if (this.article.is_followed) { await deleteFollow(authorId) } else { // 否则添加关注 await addFollow(authorId) } // 更新视图 this.article.is_followed = !this.article.is_followed } catch (err) { console.log(err) this.$toast.fail('操作失败') } // 关闭按钮的 loading 状态 this.isFollowLoading = false }

因多处使用,考虑封装组件!!

优化:模板中的 $event 是事件参数,当我们传递给子组件的数据既要使用还要修改。

传递:props                            :is-followed="article.is_followed"

修改:自定义事件                  @update-is_followed="article.is_followed = $event"

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

value="article.is_followed"

@input="article.is_followed = $event"

(如果需要修改 v-model 的规则名称,可以通过子组件的 model 属性来配置修改)

(一个组件上只能使用一次 v-model,如果有多个数据需要实现类似于 v-model 的效果,可以使用属性的 .sync 修饰符)

8.文章收藏

1、在 `api/article.js` 添加封装数据接口

2、给收藏按钮注册点击事件

3、处理函数

async onCollect () { // 这里 loading 不仅仅是为了交互提示,更重要的是请求期间禁用背景点击功能,防止用户不断的操作界面发出请求 this.$toast.loading({ duration: 0, // 持续展示 toast message: '操作中...', forbidClick: true // 是否禁止背景点击 }) try { // 如果已收藏,则取消收藏 if (this.article.is_collected) { await deleteCollect(this.articleId) // this.article.is_collected = false this.$toast.success('取消收藏') } else { // 添加收藏 await addCollect(this.articleId) // this.article.is_collected = true this.$toast.success('收藏成功') } this.article.is_collected = !this.article.is_collected } catch (err) { console.log(err) this.$toast.fail('操作失败') } } 9.文章点赞

1、添加封装数据接口

2、给点赞按钮注册点击事件

3、处理函数  

async onLike () { // 两个作用:1、交互提示 2、防止网络慢用户连续不断的点击按钮请求 this.$toast.loading({ duration: 0, // 持续展示 toast message: '操作中...', forbidClick: true // 是否禁止背景点击 }) try { // 如果已经点赞,则取消点赞 if (this.article.attitude === 1) { await deleteLike(this.articleId) this.article.attitude = -1 this.$toast.success('取消点赞') } else { // 否则添加点赞 await addLike(this.articleId) this.article.attitude = 1 this.$toast.success('点赞成功') } } catch (err) { console.log(err) this.$toast.fail('操作失败') } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3