1. 针对 background 属性
background: url("@/assets/img/home/loading-bg.png") 0 0/ 100% 100%
结构分解
background: url("...") [position] / [size] [repeat] [attachment] [origin] [clip];
0 0
:背景定位值(position)/
:分隔符(用于区分 position 和 size)100% 100%
:背景尺寸值(size)
1. 背景定位 0 0
-
语法:
background-position: x-axis y-axis;
-
作用:设定背景图片在容器中的起始位置。
-
值解析:
- 第一个
0
:水平方向(x轴)的起点为容器左边缘。 - 第二个
0
:垂直方向(y轴)的起点为容器上边缘。
- 第一个
-
等价写法:
left top
(左上角对齐)。
2. 背景尺寸 100% 100%
-
语法:
background-size: width height;
-
作用:设定背景图片的宽度和高度。
-
值解析:
- 第一个
100%
:图片宽度拉伸至容器宽度的 100%。 - 第二个
100%
:图片高度拉伸至容器高度的 100%。
- 第一个
-
效果:图片会完全填满容器,但可能导致图片变形(如果容器宽高比与图片原始宽高比不一致)。
关键细节
-
分隔符
/
的作用:/
是必需的,用于区分background-position
和background-size
。- 如果省略
/
,浏览器会将100% 100%
误认为是background-position
的一部分,导致错误。
-
默认行为:
- 如果省略
background-size
,图片会按原始尺寸显示。 - 如果省略
background-repeat
,图片默认会平铺重复(需显式添加no-repeat
禁止平铺)。
- 如果省略
-
替代尺寸方案(避免变形):
cover
:拉伸图片以覆盖容器,保持比例,可能裁剪图片。contain
:拉伸图片至容器内完整显示,保持比例,留白。
完整等效代码
.element {
background-image: url("@/assets/img/home/loading-bg.png");
background-position: 0 0; /* 左上角对齐 */
background-size: 100% 100%; /* 拉伸填满容器 */
background-repeat: no-repeat; /* 建议添加,防止平铺 */
}
示例对比
代码 | 效果 |
---|---|
0 0/ 100% 100% | 图片从左上角开始,拉伸填满容器(可能变形) |
center/cover | 图片居中,等比例拉伸覆盖容器(无变形,可能裁剪) |
left top/contain | 图片左上角对齐,等比例拉伸至容器内完整显示(无变形,可能留白) |
2. 关于v-show
的理解与掌握
一、核心特性
-
本质
v-show
通过 CSS 的display
属性切换元素的显示状态,不会移除 DOM 元素- 条件为
true
→display: block
(或元素默认的显示方式,如inline
、flex
等) - 条件为
false
→display: none
- 条件为
-
语法
<div v-show="condition">内容</div>
condition
是一个布尔值或返回布尔值的表达式
-
适用场景
- 需要频繁切换显示/隐藏状态(如选项卡、折叠面板)
- 初始渲染成本较高的元素(如表单复杂组件)
二、与 v-if
的关键区别
特性 | v-show | v-if |
---|---|---|
DOM 操作 | 不销毁元素,仅切换 display | 条件为 false 时移除 DOM 元素 |
初始渲染开销 | 无论条件如何,总会渲染元素 | 条件为 false 时不会渲染 |
切换性能 | 高(仅切换 CSS 属性) | 低(涉及 DOM 增删) |
适用场景 | 频繁切换显示状态 | 条件很少改变或需要懒加载内容 |
三、性能优化建议
-
优先
v-show
的场景- 元素需要频繁切换(如每秒多次)
- 元素包含复杂子组件(避免重复初始化开销)
-
优先
v-if
的场景- 条件在初始化后很少改变
- 需要减少初始 DOM 数量(如权限控制隐藏敏感内容)
四、常见问题
-
为什么
v-show="false"
的元素仍占用空间?
display: none
会隐藏元素但保留 DOM 结构,若需要彻底移除空间,需用v-if
-
如何实现过渡动画?
使用<transition>
包裹元素,结合 CSS 过渡或动画实现显示/隐藏效果<transition name="fade"> <div v-show="isVisible">内容</div> </transition>
3. 关于页面加载 缓存 的问题解决
- 在自己封装的 request 函数请求里面,用特定的变量去修改针对这个状态
-
利用 拦截器,请求拦截,相应拦截, 如果你发现某些逻辑需要在大多数请求中重复实现,拦截器可能就是最佳解决方案!
这个图片的是 实例 设置的拦截器(只能给实例设置拦截器)
注意: 在 new 的时候,会调用实例方法,例如,A 的时候,会调用 B 构造方法, this.instance是新的对象实例
拦截器的设置方式:
在自己定义的对象实例里面,拦截器的设置形式,要有两个回调函数
1、实现拦截器的常见方式
以最常用的 HTTP 库 Axios
为例:
1. 请求拦截器
axios.interceptors.request.use(
(config) => {
// 请求发送前的处理
config.headers.Authorization = 'Bearer ' + getToken(); // 添加 Token
if (config.showLoading) {
showLoading(); // 显示 Loading
}
return config; // 必须返回修改后的配置
},
(error) => {
// 请求错误处理
return Promise.reject(error);
}
);
2. 响应拦截器
axios.interceptors.response.use(
(response) => {
// 响应成功处理(状态码 2xx)
if (response.config.showLoading) {
hideLoading(); // 隐藏 Loading
}
return response.data; // 直接返回核心数据
},
(error) => {
// 响应错误处理(状态码非 2xx)
if (error.response.status === 401) {
router.push('/login'); // 跳转登录页
}
return Promise.reject(error); // 继续抛出错误
}
);
2、拦截器的核心特点
- 链式调用:可以注册多个拦截器,按顺序执行。
- 异步支持:可以在拦截器中执行异步操作(如 Token 刷新)。
- 灵活配置:通过
config
参数实现请求级别的个性化配置。
3、实际应用场景示例
场景 1:Token 自动刷新
axios.interceptors.response.use(null, async (error) => {
if (error.response.status === 401 && !error.config._retry) {
error.config._retry = true;
await refreshToken(); // 异步刷新 Token
return axios(error.config); // 重试原请求
}
return Promise.reject(error);
});
场景 2:统一 API 响应格式
axios.interceptors.response.use((response) => {
if (response.data.code === 200) {
return response.data.data; // 返回业务数据
} else {
return Promise.reject(response.data.message); // 抛出业务错误
}
});
3、高级技巧
-
拦截器执行顺序
- 请求拦截器:先添加的先执行
- 响应拦截器:后添加的先执行
-
移除拦截器
const interceptor = axios.interceptors.request.use(...); axios.interceptors.request.eject(interceptor);
-
实例专属拦截器
const instance = axios.create(); instance.interceptors.request.use(...);
4、注意事项
- 避免在拦截器中处理业务核心逻辑(保持单一职责)
- 谨慎修改跨域的请求头(如
Content-Type
可能触发 CORS 预检) - 确保正确处理异步操作(如 Token 刷新需要阻塞请求重试)