day03-mobile
1.0 概述
1.1 复习
- 准备工作:
- 项目的开发流程
- 前端的职责
- 设计稿完成静态页面
- 接口文档完成数据的渲染
- 准备材料
- 技术的选型
- 搭建项目结构:
- 使用 vue-cli 完成了项目结构的搭建
- 优化结构
- 删除不必要的文件
- 添加一个些额外的文件夹
- 前置知识点:
- 在 vue 中使用 vant:
- a. 下载 vant
- b. 在 main.js 中
- 导入 vant
- 导入 vant 的样式
- 使用 vant
- c. 直接将 vant 的组件在页面中使用
- vant 中组件的使用
- a. 按钮组件的使用
- b. cell 组件的使用
- c. icon 组件的使用
- vant 中的插槽
- eslint
- 关键字后面必须有空格
- 方法名后面必须有空格
- 不能带分号
- 注释后面必须有空格
- 行末不能有空格
- 文件必须以空行结束
- 不能有冗余的变量
- 从全局对象中取出方法必须添加 window
- 在 vue 中使用 vant:
- 登录:
- 静态页面
- 逻辑功能:
- 数据合法性的验证
- 提交数据到服务器
- 将 axios 封装为一个单独的 js 文件
- 将网络请求单独封装为一个 js 文件
- 将服务器返回的信息保存起来
- vuex 中
- localstorage 中
- 操作 localstorage 的方法封装为一个单独的 js 文件
- 使用 async & await 来改造异步代码:
- async 用来修饰异步代码所在的函数
- await 用来修饰异步代码
- 异步代码返回的必须是一个 promise 对象
- 使用 try-catch 来捕获请求的异常
- 登录时添加一个登录加载效果
- 登录失败时使用 toast 添加失败信息
1.2 今日内容
- 首页
- 静态页面
- 功能逻辑
2.0 首页
2.1 静态页面
-
组件 & 路由
-
设置入口
- 将来如果用户请求根目录,直接跳转到 Home 下
-
完成结构 & 样式
-
头部导航
- 使用 vant 中的 navBar
-
频道区域
- 使用 vant 中的 tab 标签页
-
文章列表区域
- 功能:
- 下拉刷新
- 上拉加载更多
- 使用 vant 中的 list 完成上拉加载更多
- 属性:
- loading:
- list 组件的加载状态
- true:说明正在加载
- false:说明加载完成
- list 组件的加载状态
- finished:
- list 组件中的数据是否已经全部加载完毕
- true:说明数据已经全部加载完毕
- false:说明数据没有全部加载完毕
- list 组件中的数据是否已经全部加载完毕
- loading:
- 事件:
- load
- 执行时机:
- 当 list 组件被加载时会触发
- 当 list 组件被上拉触底时也会触发
- 特点:
- 每次 load 执行完成之后,在 load 事件内部会自动将当前 list 对应的 loading 改为 true
- 为了解决这个问题,每次设置完 load 事件之后,需要手动将 loading 改为 false
- 每次 load 执行完成之后,在 load 事件内部会自动将当前 list 对应的 loading 改为 true
- 执行时机:
- load
- 案例:
- a. 打开页面时需要 list 组件中显示 20 条数据
- b. 上拉过程中:每次数据显示完毕之后,再加载 20 条数据
- c. 当总数超过 100 条时,不再加载后续数据
- 属性:
- 使用 vant 中的 pullrefresh 完成下拉刷新
- 属性:
- isloading:下拉刷新的状态
- 事件:
- onRefresh:下拉刷新时会触发的事件
- 注意点:
- 当执行完 onRefresh 事件之后,组件内部会将 v-model 对应的属性设置为 true
- 执行完 onRefrsh 之后需要手动将 isLoading 设置为 false
- 注意点:
- onRefresh:下拉刷新时会触发的事件
- 案例:
- a. 下拉 list 中的数据时,需要重置数据源
- 在 pullrefresh 的刷新事件中将所有的数据进行重置
- a. 下拉 list 中的数据时,需要重置数据源
- 属性:
- 功能:
-
导航区域
注意点:这个导航区域除了首页有之外,还有其它的三个页面中也包含了。为了保存代码的简洁。我们可以:
a. 创建一个单独的 layout 组件
layout 组件中只放下面的导航
b. 将 layout 设置为 首页 & 问答 & 视频 & 我的 页面的父组件
- 使用 vant 中的 tabbar 来完成导航结构
- 使用 route 属性开启 tabbar 的路由模式
- 再给 tabbar 中的选项设置 to 属性进行跳转
- 使用 vant 中的 tabbar 来完成导航结构
-
2.2 完成功能
2.2.1 加载频道数据
- 功能分析:
- a. 打开页面时需要去服务器请求频道数据
- b. 将数据渲染到页面上
- 步骤:
- a. 在 home 添加一个函数: created
- b. 发送请求到服务器得到频道数据
- 服务器的接口
- url: /user/channels
- method: GET
- 参数:
- 请求头:
- Authorization :token
- 请求头:
- 返回数据
- 注意点:
- 不强制用户登录:
- 登录:返回登录用户的频道数据
- 不登录:返回系统的默认频道数据
- 不强制用户登录:
- 服务器的接口
- c. 将数据保存起来: channleList
- d. 将数据渲染到页面上
2.2.2 给请求设置 token
-
功能分析:
- a. 如果要得到用户自己的频道数据,需要在请求头中携带 token
-
步骤:
- a. 找到 http.js 的请求拦截器
- b. 在拦截器中判断用户是否登录:
- 如果登录:
- 在请求头中携带 token
- 如果未登录:
- 不管
- 如果登录:
-
注意点:
-
1)如果在 http.js 中要得到 store 需要单独导入
-
2)向请求头中添加 token 时需要以下面方式添加
config.headers.Authorization = `Bearer ${user.token}`
-
2.2.3 判断频道数据:
- 功能分析:
- a. 得到频道数据之前应该进行判断:
- 判断用户是否登录:
- 登录:
- 直接从服务器中获取频道数据(携带 token)
- 末登录:
- 之前操作过频道数据
- 说明 localstorage 中有频道数据
- 直接从 localstorage 中取得频道数据,并且渲染
- 之前没有操作过频道数据
- 说明 localstorage 中没有频道数据
- 直接从服务器中得到默认的频道数据
- 之前操作过频道数据
- 登录:
- 判断用户是否登录:
- a. 得到频道数据之前应该进行判断:
- 步骤:
- 在得到频道数据的方法中 created 中
- 判断 $store 中的 user 下面的 token 是否存在数据
- 如果存在
- 直接从服务器中得到频道数据
- 如果不存在
- 判断 localstorage 中是否存在频道数据
- 如果存在:
- 取出 localstorage ,渲染到页面上
- 如果不存在:
- 直接从服务器中得到频道数据
- 如果存在:
- 判断 localstorage 中是否存在频道数据
- 如果存在
- 判断 $store 中的 user 下面的 token 是否存在数据
- 在得到频道数据的方法中 created 中
2.2.4 将不同频道下的数据分开
-
功能分析:
- 由于不同频道下面使用的数据源是相同的,它们都使用了相同的
- loading :list 组件的加载状态
- finished:list 组件的完毕状态
- isloading:pullrefresh 组件的下拉状态
- list:显示的文章数据源
- 当得到频道数据之后,应该动态向每一个频道数据中添加额外的属性:
- loading & finished & isloading & list
- 由于不同频道下面使用的数据源是相同的,它们都使用了相同的
-
步骤:
-
当 created 中得到频道数据之后:
-
动态给每个频道数据添加额外属性
-
loading & finished & isloading & list
-
添加额外属性之前:
[ { id: 0, name: ‘推荐’ } ]
-
添加额外属性之后
[ { id: 0, name: ‘推荐’, loading: false, isloading: false, finished: false, list: []} ]
-
-
-
应该在页面上将额外属性渲染到结构中
-
2.2.4 渲染频道下的文章数据
-
功能分析:
- a. 打开页面先加载频道数据,频道数据默认选中的是推荐
- b. 打开页面时直接加载推荐下的文章数据
-
步骤:
-
a. 在 onload 事件中得到当前频道
-
b. 根据当前频道去服务器中得到频道下的数据源
- 服务器接口
- url:http://ttapi.research.itcast.cn/app/v1_1/articles
- method: GET
- 参数
- query:将来参数要放到路径上以 ? 的形式传递
- channel_id:当前频道的 id
- timestamp:当前时间戳
- with_top:是否置顶
- 0:不置顶
- 1:置顶
- query:将来参数要放到路径上以 ? 的形式传递
- 返回数据
- 服务器接口
-
c. 将数据保存起来
- 保存到当前频道下的 list 属性中
-
d. 将数据渲染到页面上
- 渲染当前频道下 list 中每个元素的属性
-
-
bug 合集
- bug1:
- 表现:数据请求出来不渲染
- 原因:动态添加的数据不会渲染
- 解决方案:通过 $set 添加
- bug2:
- 表现:一直处于加载中
- 原因:没有手动设置 loading 属性
- 解决方案:手动设置 loading
- bug3:
- 表现:内容一直变化
- 原因:
- 1.0 数据只有 10 条没有把页面撑开,会一直执行 list 的 onload 事件
- 2.0 数据请求回来之后直接将原来的数据进行覆盖
- 数据依旧只有 10 条
- bug1:
2.2.5 上拉加载更多
- 解决了
- 功能分析:
- 当数据加载完毕时,将 finished 设置为 true
- 步骤:
- a. 得到返回的数据,判断 results 的长度
- 如果为 0 说明数据已经加载完毕:将 finished 设置为 true
- a. 得到返回的数据,判断 results 的长度
2.2.6 下拉刷新:
- 功能分析:
- 在页面上下拉时,应该将之前的数据清除,拿到最新的数据
- 实现步骤:
- a. 在 pullrefresh 中添加一个事件: onrefresh
- b. 在 onrefresh 中:
- 清除当前选中频道中的所有的数据
- loading
- isloading
- finished
- list
- 清除当前选中频道中的所有的数据
- bug 集合:
- bug1:
- 表现:清除数据之后没有加载新的数据
- 原因:因为 onrefresh 事件中的逻辑需要是延迟执行
- 解决方案:
- 在 onrefresh 中再执行 onload 事件
- bug2:
- 表现:清除数据之后,无法进行上拉加载更多
- 原因:数据只能 10 条,无法触发 list 组件的上拉加载更多
- 解决方案:
- 给每个 cell 添加一个高度:150px 以上
- bug1:
扩展:
e1. $set
bug:
- 请求服务器中的数据源,保存之后动态渲染到页面上,发现渲染不上去
- 作用:动态添加属性 ,可以动态渲染到页面上
- 用法:this.$set(obj, key, value)