主题
面经 H5 端:Vant 与项目搭建(四)
本页对应 面经 H5 端:Vant 与项目搭建,共 6 段视频,约 1 小时 17 分。
学习目标
- 能够将接口返回的分页数据(
res.data.rows)存入组件data的list中,并能通过 Vue DevTools 按组件name搜索定位组件、核对数据是否正确挂载。 - 能够基于 van-cell 的插槽(title、label、default 等)定制面经条目结构,将其抽离封装为 ArticleItem 组件并在
main.js中注册为全局组件以供多页面复用。 - 能够通过
props接收父组件传入的item对象,正确书写类型校验与对象默认值(默认值必须写成函数返回),并在模板中渲染标题、作者、时间、简介、点赞量与浏览量等字段。 - 能够使用
v-for遍历list渲染 ArticleItem 并绑定唯一key,完成父组件向子组件的数据传递。 - 能够使用 van-list 包裹循环列表,定义
loading、finish数据与onLoad方法,并说明 van-list 首次会自动触发onLoad因而无需在created中手动调用。 - 能够实现上拉加载更多:请求页码自增、用展开运算符
push累加数据、请求完成后重置loading、页码超过总页数时将finish置为true并显示"没有更多"。 - 能够根据 401 状态码、Network 面板请求头
Authorization(Bearer 拼写与空格、localStorage key 不一致)、模块或包找不到(路径/文件名/loader 缺失)等报错信息定位并修复常见错误。
知识点
组件库的价值与选型
组件库是第三方封装好了很多组件的集合,整合到一起就是一个组件库。日历、键盘、打分、登录等常见模块,如果每个项目都重写,既慢又难统一交互和样式。为什么需要:复用成熟组件,减少重复造轮子。怎么想:先按端选库,PC 与移动端不要混用;再查文档确认版本和 API。怎么做:移动端 Vue2 项目可看 vant-ui,PC 端常见有 element-ui、element-plus、iview、ant-design;移动端还有 Mint UI、Cube UI。
易错点:组件库不是唯一的,别背组件名,要会看文档的 API、插槽和示例;注意 Vue2/Vue3 版本差异。
用 Vant Cell 搭面经条目
面经列表每一项结构相似,适合用 van-cell 做骨架。为什么需要:自己写 div 也能做,但 Cell 已处理标题、内容、图标等基础布局。怎么想:先看基础用法,再看插槽:title 放左侧标题,默认插槽放右侧内容,label 放标题下方内容,right-icon 放右侧图标。怎么做:先用双标签写 Cell,再用 <template #title>、<template #label> 和默认插槽定制。转写稿里“万杠线”就是 van-cell,“插锁”是插槽,“井号”是 #,即 v-slot: 的简写。易错点:要传插槽内容就不能用单标签;#title 要写在 template 上;不确定插槽位置时,按文档逐个试并观察页面。
把接口数据存进 data 并用调试工具核对
接口返回的往往不是直接数组,而是分页对象。为什么需要:列表只渲染当前页数据,不能把整个响应乱塞。怎么想:先打印 res,确认数据在 res.data.rows,总页数在分页配置里。怎么做:
js
this.list = res.data.rows然后在模板里 v-for 遍历。调试时打开 Vue 调试工具,按当前组件的 name 搜索,别在别的组件里找数据。易错点:存错层级;看错组件;把“当前页、每页条数、总页数”混在一起。转写稿里反复强调“存到 data 中”“看 Vue 调试工具”,就是为了先确认数据到底有没有拿到。
封装 ArticleItem 组件实现复用
面经列表、收藏页、喜欢页都可能复用同一条面经结构。为什么需要:复制多份结构会导致改一处漏多处。怎么想:把 van-cell 这一整块结构和对应样式抽成子组件,再注册为全局组件。怎么做:在 components 下新建 ArticleItem.vue,把 Cell 结构及样式剪切过去;在 main.js 导入并 Vue.component 注册;父组件循环并传值:
vue
<ArticleItem v-for="item in list" :key="item.id" :item="item" />子组件接收:
js
props: {
item: {
type: Object,
default: () => ({})
}
}易错点:父组件传的是 :item,子组件 props 必须同名;对象默认值必须写成函数,箭头函数直接返回对象时要加小括号 () => ({}),否则会被当成函数体;抽组件时样式类名要一起迁移。
用 Vant List 做滚动加载更多
移动端滚动到底部加载下一页,自己监听滚动很麻烦,Vant 提供了 List。为什么需要:统一“加载中、没有更多”的状态。怎么想:用 van-list 包裹循环项,准备 loading、finished,在 @load 触发的 onLoad 中请求下一页。怎么做:每页数据回来不要覆盖,而是累加:
js
this.list.push(...res.data.rows)
this.loading = false
this.page++页码超过总页数后把 finished 设为 true。易错点:push 整个数组要展开,否则会变成嵌套数组;onLoad 要与文档事件对应;请求中 loading 为 true 防止重复加载;最后一页要停止加载。转写稿里“非历史”应纠正为 finished,“落点”应纠正为 loading。
接口与资源报错排查
为什么需要:401、找不到模块是高频问题,不会排查会一直卡住。怎么想:接口错先看 Network,资源错先看控制台报错。怎么做:401 一定是权限/token 问题,看请求头 Authorization 是否为 Bearer + 空格 + token,并核对 localStorage 键名是否与代码一致;请求地址、GET/POST 方法要和接口文档一致。找不到模块时,检查路径、文件名、单词拼写;提示缺少 sass-loader 而样式写了 lang="scss",就安装对应包,或改成已支持的 less。易错点:Bearer 拼错、漏空格、token 键名写错;把接口地址随意加字符;用了 SCSS 却没装 loader。转写稿中故意改错 token、看 401、看请求头,再改回正确值,就是完整调试过程。
本节目标与结论

本节要明确的是:全部导入和按需导入到底差在哪里。笔记给出的结论很直接:全部导入会引起项目打包后的体积变大,进而影响用户访问网站的性能;按需导入只会导入你使用的组件,进而节约资源。
为什么需要:项目上线后,包体积会直接影响首屏加载和访问速度。怎么想:不是“功能能跑就行”,而要判断某个导入是否真的被当前页面使用。怎么做:先区分“全部导入”和“按需导入”,再按项目所用组件库的官方文档选择引入方式;项目内组件也尽量做到用到才引入、能复用就抽离。易错点:把“全局注册”误当成“按需导入”,或者按需引入后忘了引入对应样式,导致页面样式缺失。
全部导入:为什么体积会变大
为什么需要:全部导入会把整个组件库或大量未使用代码一起打进包里,用户访问时下载量变大。怎么想:如果当前页面只用了少数几个组件,却把整套组件都引入,打包体积自然不划算。怎么做:理解全部导入的代价,检查项目是否真的需要一次性引入全部内容;如果只是少量页面使用,应优先考虑按需方式。易错点:只看开发时是否方便,不看打包结果;以为“代码写在入口文件里”就一定被使用,实际上未使用代码也可能增加体积。
按需导入:只拿当前用到的组件
为什么需要:按需导入的目标是只把当前用到的组件和资源引入,减少无关代码。怎么想:先看页面实际用了什么,再决定引入什么;不是“先全拿进来,后面再说”。怎么做:按组件库文档做按需引入;项目内组件也一样,用到哪个就导入哪个。转写稿里把面经列表中的 van-cell 结构抽成 ArticleItem,再在 main.js 中导入并注册为全局组件,体现的就是“把复用的部分单独拿出来、需要的地方再使用”的思路:
js
import ArticleItem from './components/ArticleItem.vue'
Vue.component('ArticleItem', ArticleItem)易错点:转写稿中“慢点GS”实际是 main.js,“companist”实际是 components,“RRT艾特/阿吉艾”实际是 ArticleItem。导入路径、文件名大小写、单词拼错,都会导致“找不到模块”。
用组件抽离理解“按需”的工程价值
为什么需要:面经列表、收藏页、喜欢页都可能复用同一条面经结构,如果每个页面都复制一遍,代码重复且难维护。怎么想:把 van-cell 这一块抽成独立组件,哪个页面需要就引入哪个组件。怎么做:把模板和对应样式剪切到 ArticleItem 中,注册后在列表页循环使用:
html
<ArticleItem
v-for="item in list"
:key="item.id"
:item="item"
/>易错点:父传子时属性名要一致,子组件用 props 接收;转写稿里反复强调“必须叫 item”,否则接收不到。默认值是对象时,default 要写成函数返回对象;箭头函数直接返回对象时,外层要加小括号,否则 {} 会被当成函数体。
调试与验证:别把“按需”做成“缺依赖”
为什么需要:按需引入后,最常见的问题不是“概念不懂”,而是路径、依赖、token、样式 loader 等细节出错。怎么想:先看控制台报错,再看 Network 面板;401 优先查 token。怎么做:转写稿中排查 401 时,要看请求头里的 Authorization 是否为 Bearer 加空格,再看本地存储的 key 是否写成了 mobile-token;找不到模块就看路径和单词,缺 sass/sass-loader 就补依赖或改 lang。列表加载更多时,数据要累加而不是覆盖:
js
this.list.push(...res.data.rows)同时用 loading 控制“加载中”,用 finished 控制“没有更多”。易错点:转写稿里的“rose/roose”实际是 rows,“beer/B2”实际是 Bearer,“Ororization”实际是 Authorization,“莫贝尔刚偷看”实际是 mobile-token;只看报错不点开请求详情,很难定位真正原因。
小结
全部导入和按需导入的核心差别不是写法花哨,而是打包体积和资源利用:全部导入省事但可能把不用的代码也带上;按需导入只拿当前使用的组件,更利于性能。项目内把 ArticleItem 抽出来、用到再引入,也是同一种“按需”思想。真正落地时,既要按文档配置,也要用 Network、控制台和打包结果验证,避免把“按需”做成“缺依赖”。
先安装 Vant:把组件库变成项目依赖
为什么需要:本节要使用 Vant 的按钮等组件,第一步必须把组件库安装到项目依赖里;没有安装,后面的 import Vant from 'vant' 就找不到包。
怎么想:转写稿里排查“找不到模块”时反复强调,先判断是第三方包没装,还是自己写的文件路径/单词错了。这里属于前者,所以先在项目根目录安装。
怎么做:在项目根目录执行下面命令,二选一即可:
bash
yarn add vant@latest-v2
// 或者 npm i vant@latest-v2易错点:命令要在项目根目录执行,不要在随便一个文件夹里执行;注意包名是 vant,不要被口误写成别的词。若控制台报 Cannot find module,先按转写稿思路核对:包是否安装、package.json 是否更新、终端是否在正确目录。
在 main.js 中全部导入并注册
为什么需要:Vant 有很多组件,若每个页面都单独导入、注册,初学阶段代码会显得零散;本节先采用“全部导入”,让所有组件一次性可用,便于快速跑通页面。
怎么想:转写稿里说得很直白:把 Vant 整个导入,再通过 Vue.use(Vant) 注册,之后模板里就能直接写 van-button 等标签。注意这里导入的是组件库和它的样式,不是某个单独组件。
怎么做:在 main.js 中写:
js
import Vant from 'vant';
import 'vant/lib/index.css';
// 把vant中所有的组件都导入了
Vue.use(Vant)易错点:第一,样式文件 vant/lib/index.css 不要漏,否则组件可能结构在、样式不对;第二,import 语句要集中放在文件上部,转写稿里提到过“所有导入要求放在一起”,不要把注册代码夹在多个 import 中间;第三,注意正确拼写 Vant、main.js、Vue.use(Vant),不要被同音口误带成“VE点company”之类。保存后若报错,先看控制台是“找不到包”还是“路径/单词不一致”。
在页面中直接使用 Vant 组件
为什么需要:全部导入并注册后,要验证组件是否真的可用;最直观的方式就是写几个按钮看渲染效果。
怎么想:既然已经 Vue.use(Vant),页面模板里就不需要再局部注册按钮组件,直接写 Vant 规定的标签即可。
怎么做:在页面模板中写:
jsx
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>渲染效果可对照下图:

易错点:若按钮出现但样式不对,优先检查 vant/lib/index.css 是否导入;若页面报“未知组件”,检查 main.js 中是否真的执行了 Vue.use(Vant),以及当前页面是否在 Vue 应用挂载范围内。转写稿中的调试经验是:不要一看到报错就慌,先看控制台错误类型,再核对导入、注册、标签名和单词拼写。
全部导入的代价:先跑通,再考虑优化
为什么需要:全部导入虽然方便,但笔记最后明确提醒:“vant-ui提供了很多的组件,全部导入,会导致项目打包变得很大。”这句话是本节最重要的工程意识。
怎么想:初学阶段目标是先让组件可用、页面跑通;但要知道全量注册会把很多当前页面没用到的组件也带进构建结果。转写稿里也提到,组件抽离、全局注册是为了复用方便,但复用和体积要平衡。
怎么做:本节先按上面的方式完成安装、全量导入、注册和使用;当项目进入优化阶段,再考虑按需引入或局部注册。当前不要为了“看起来高级”提前改乱 main.js。
易错点:不要把“全部导入”理解成“永远这样最好”;也不要因为打包大就立刻删样式或乱改导入。先保证功能正确,再根据构建提示和实际使用情况优化。若改完 main.js 后项目报错,按转写稿的排查顺序:看控制台错误、核对包是否安装、核对导入路径和单词、确认导入语句位置是否规范。
课件图示








代码示例
示例一:全部导入 vant(main.js + App.vue)
js
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 1. 导入 vant 组件库
import Vant from 'vant'
// 2. 导入 vant 的样式文件(不导入样式,组件长得就是“裸”的)
import 'vant/lib/index.css'
// 3. 注册:把 vant 里所有的组件一次性全部注册到 Vue 上
Vue.use(Vant)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')vue
<!-- App.vue -->
<template>
<div id="app">
<!-- 注册完就能直接当标签用,不用再 import -->
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>关键行与易错点
- 安装:
yarn add vant@latest-v2(或npm i vant@latest-v2),本节用的是 vant 2.x,不要装成 3.x/4.x。 Vue.use(Vant)是全部导入,所有组件一次性进来,项目打包体积会变大;按需导入只引入你用到的组件,能节约资源。import 'vant/lib/index.css'这一行不能漏,漏了组件能用但没样式。- 组件标签在模板里是
van-button、van-cell这种短横线写法,不要写成VantButton。 - 全部导入后组件已全局注册,页面里不需要再 import,再 import 反而会重复打包。
示例二:封装单个面经单元格 ArticleItem.vue(van-cell + 插槽 + props)
vue
<!-- components/ArticleItem.vue -->
<template>
<div class="article-item">
<van-cell>
<!-- title 插槽:左侧放小图,右侧放标题/作者/发布时间 -->
<template #title>
<div class="title-box">
<img class="avatar" :src="item.avatar" alt="" />
<div class="info">
<p class="title">{{ item.stem }}</p>
<p class="author">作者:{{ item.creator }}</p>
<p class="time">发布时间:{{ item.created_at }}</p>
</div>
</div>
</template>
<!-- label 插槽:标题下方的简介 + 点赞量 + 浏览量 -->
<template #label>
<div class="label-box">
<p class="content">{{ item.content }}</p>
<p class="other">
<span>点赞 {{ item.likeCount }}</span>
<span>浏览 {{ item.views }}</span>
</p>
</div>
</template>
</van-cell>
</div>
</template>
<script>
export default {
name: 'ArticleItem',
props: {
// 父组件 v-for 循环时把每一行的小对象传进来
item: {
type: Object,
// 对象/数组的默认值必须写成函数,箭头函数返回对象还要再包一层小括号
default: () => ({})
}
}
}
</script>
<style lang="scss" scoped>
.article-item {
.title-box {
display: flex;
align-items: center;
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
.title {
font-size: 14px;
color: #333;
}
.author,
.time {
font-size: 12px;
color: #999;
}
}
.label-box {
.content {
font-size: 12px;
color: #666;
}
.other {
font-size: 12px;
color: #999;
}
}
}
</style>关键行与易错点
- 用插槽就必须写双标签(
<van-cell> ... </van-cell>),自闭合标签是没法往里传内容的。 - 插槽简写
#title等价于v-slot:title;vant 的 van-cell 支持title(左侧)、label(标题下方)、default(右侧)、value、icon、right-icon等插槽,文档里都列了,不确定位置就挨个试一下。 default是自定义右侧内容,本例没用到,所以默认插槽不传值也完全正常。- props 名字必须和父组件传的一模一样:父组件传
:item,子组件就得接item,叫别的名字就接不到。 - 默认值易错点:
default: {}会直接报错,必须写成函数default: () => ({});如果省掉小括号写成() => {},大括号会被当成函数体而不是返回对象,等于返回undefined。 <style lang="scss">需要项目里装了sass和sass-loader,否则报Can't resolve 'sass-loader';不想装就改成lang="less"或不写 lang。
示例三:面经列表循环渲染 + van-list 加载更多(Article.vue)
vue
<!-- views/Article.vue -->
<template>
<div class="article-page">
<!-- van-list 负责监听滚动到底部,自动触发 load 事件 -->
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<!-- 循环渲染封装的单元格组件,父传子 :item -->
<article-item
v-for="item in list"
:key="item.id"
:item="item"
/>
</van-list>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'ArticlePage',
data () {
return {
list: [], // 已加载的所有面经数据(多页累加)
loading: false, // 是否正在加载中,由 van-list 自动置 true
finished: false, // 是否已全部加载完毕
count: 1, // 当前请求的页码
pageTotal: 0 // 总页数,接口返回
}
},
methods: {
// 方法名必须叫 onLoad,和 van-list 的 @load 对应
async onLoad () {
// 1. 拿当前页数据
const res = await axios.get('http://localhost:3000/api/articles', {
params: { page: this.count }
})
// 2. res.data.data 里才有 rows(数据数组)和 pageTotal(总页数)
const { rows, pageTotal } = res.data.data
// 3. 累加到 list 里,注意用展开运算符,不能直接赋值
this.list.push(...rows)
// 4. 页码 +1,为下一页做准备
this.count++
this.pageTotal = pageTotal
// 5. 本次加载结束,loading 必须复位,否则不会再触发下一次 load
this.loading = false
// 6. 页码超过总页数,说明数据加载完了
if (this.count > this.pageTotal) {
this.finished = true
}
}
}
}
</script>js
// main.js 中把 ArticleItem 注册成全局组件(放在 vant 那几行 import 的下面,别夹在 import 中间)
import ArticleItem from '@/components/ArticleItem'
Vue.component('ArticleItem', ArticleItem)关键行与易错点
van-list必须把v-for的那一段包在中间,和普通列表写法一样,只是外面多套一层。v-model="loading"、:finished="finished"这两个变量必须有:loading为 true 表示正在请求、不允许重复加载;finished为 true 表示没有下一页了。- 数据累加是本节最容易错的地方:要
this.list.push(...rows)。写this.list = rows会把前一页数据覆盖掉;写this.list.push(rows)会变成数组套数组,渲染就崩了。 - 页码自增
this.count++不能忘,忘了就永远请求第一页。 loading = false必须复位,否则滚到底也只“加载中”不请求下一页。- 判断结束用
this.count > this.pageTotal,超过总页数就finished = true,否则会一直请求 42、43 页拿到空数组。 - 用
van-list后,created里手动调一次请求要删掉:组件挂载时@load会自动执行一次,手动再调会重复请求第一页。 - 调试接口报错先看 Network:状态码 401 一定是 token 问题(看请求标头里的
Authorization,Bearer拼写和空格都要对,本地存储的 key 也要对得上);Can't resolve之类的是路径/单词写错或缺包。
常见错误
现象:一进面经列表页就报一片网络错误,控制台状态码全是 401。 原因:请求头里的 token 拼装有问题——
Bearer单词拼错、后面漏空格、或从 localStorage 取值时 key 名与写入时不一致(如mobel-token写成mobile-token),最终取到null。 修法:打开 Network → 选中失败请求 → 看「请求标头」里的Authorization,逐字核对前缀拼写、空格、token 值;再回代码核对 localStorage 的 key 与取值写法。记住 401 一定是鉴权问题,不用去翻业务代码。现象:控制台报
Cannot find module ...或Failed to resolve ...,页面白屏或组件不渲染。 原因:导入路径/文件名拼写不一致(如components写成compfiies、组件名大小写不符),或引用了未安装的第三方包。 修法:先判断这是"自己写的文件"还是"第三方包"。是自己的文件 → 对照目录树逐个字母核对路径与文件名,两边改成一致;是第三方包 → 安装对应依赖。凡是这类报错,原因只有"路径错、单词错、包没装"三种,不要盲改。现象:新建
.vue文件后编译报找不到sass-loader。 原因:编辑器模板默认把<style lang="scss">写上了,但项目没装sass与sass-loader。 修法:要么装上sass+sass-loader,要么把lang改成less(并装 less 相关包),要么直接去掉lang用普通 CSS。用哪个预处理器就必须装对应的 loader,二者要配套。现象:给 props 写默认值
default: {}后报"默认值必须是函数"。 原因:对象/数组类型的默认值必须用工厂函数返回,直接写字面量会被所有实例共享。 修法:写成default: () => ({})。注意箭头函数直接返回对象时外层必须加小括号,否则{}会被当成函数体而不是返回值。现象:上拉加载第二页后,列表只剩 10 条,第一页数据没了。 原因:拿到新一页数据后写成了
this.list = res.data.rows,直接覆盖;或push时把整个数组塞进去,变成二维嵌套数组。 修法:改为this.list.push(...res.data.rows),用展开运算符把新数组里的小对象逐个追加。同时每页成功后this.page++,否则会反复请求同一页。现象:用了 List 组件,滚到底部有"加载中"动画,但数据不增加,或一直转圈停不下来。 原因:回调方法名没写成
onLoad(组件只认这个事件名);或请求完成后忘了把loading置回false。 修法:方法统一命名为onLoad;请求成功、数据追加完成后立即this.loading = false;当页码超过接口返回的总页数时this.finish = true,避免继续请求不存在的页。另外 List 首次渲染会自动触发一次onLoad,created里不要再手动调一次。现象:Vue 调试工具里翻遍组件树也找不到
list数据。 原因:数据定义在哪个组件,就必须去哪个组件里看;组件多时容易点错。 修法:用调试工具面板顶部的搜索框,输入组件的name(有 name 优先按 name 匹配,没有才用组件名),直接定位到目标组件再看 data。现象:
v-for渲染出 10 条,但每条内容一模一样。 原因:只做了循环,没把当次遍历的item传给子组件,子组件也没用 props 接收。 修法:父组件:item="item"传值,子组件用props按同名接收(父传的名字和子接的名字必须一致),模板里全部改成item.xxx读取。
练习
故障复现与排查:故意把请求头的
Bearer改错(拼写、空格、token 取值各错一处),刷新页面后只用 Network 面板把三处问题依次找出来并修好,记录每一步看的是哪个面板、哪一栏。组件抽离:把面经列表里的单条单元格结构抽成独立组件,注册为全局组件,并在列表页用
v-for渲染,要求父传子把每条数据对象传进去,子组件用 props 接收并声明类型与默认值。加载更多闭环:用 List 组件实现滚动加载,要求做到:新数据追加而非覆盖、页码自增、加载完重置
loading、到达总页数后显示"没有更多了"。完成后在 Network 里核对每次请求的页码是否依次递增。导入方式对比:先用全部导入跑通一个按钮组件,再改成按需导入,分别打包并对比产物体积,写出结论。
扩展挑战:参照文档自行实现下拉刷新,说明它与"重新请求第一页"在实现上的差别。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 把面经列表数据存到data中 | 05:05 |
| 2 | 封装单个ArticleItem组件 | 19:11 |
| 3 | 错误排查小结 | 14:32 |
| 4 | 遍历渲染面经列表数据 | 10:44 |
| 5 | list组件初步使用 | 16:54 |
| 6 | 应用list组件完成加载更多 | 11:07 |
小结
- 组件库的学习路径是"读文档 → 抄基础用法 → 试插槽 → 配自己的样式",课上讲不完所有 API,能自己看文档试出来才是目标。
- 遇到不认识的插槽不要猜,写一段内容挨个插进去看渲染位置,一次就能建立位置感。
- 页面里重复出现、且多个页面都要用的结构,先抽成组件再注册全局,复用成本最低——判断标准是"这东西在别的页面会不会再出现"。
- 列表分页只有三件事:页码自增、数据累加(展开后 push)、结束标志;任何一件漏了都会表现为"数据不对"或"一直转圈"。
- 排错顺序固定:先看控制台第一条红字 → 再看 Network → 再看状态码 → 最后对照接口文档。状态码本身就是答案,401 查鉴权,404 查地址。
- 判断"对错"的基准是接口文档,不是自己的记忆;和文档一致就是对的,不一致就是错的,若一致仍报错则问题在后端。
- 前端报错绝大多数逃不出三类:路径/单词拼错、依赖没装、状态没重置。按这三类逐条排除,比漫无目的改代码快得多。
- 别一遇错就问人,先自己走一遍上面的排查流程——排错能力是练出来的,不是听出来的。