解决轮播图的样式冲突
This commit is contained in:
parent
9ec95590e8
commit
908fbafbb9
|
|
@ -1,42 +1,13 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, onMounted, onUnmounted} from 'vue'
|
import {onMounted} from 'vue'
|
||||||
import {
|
import {
|
||||||
carouselData,
|
|
||||||
iotSolutionsData,
|
iotSolutionsData,
|
||||||
multiScenarioData,
|
multiScenarioData,
|
||||||
softwareDevelopmentData,
|
softwareDevelopmentData,
|
||||||
smartHardwareData,
|
smartHardwareData,
|
||||||
|
|
||||||
pageConfig
|
pageConfig
|
||||||
} from '~/data/indexData'
|
} from '~/data/indexData'
|
||||||
|
|
||||||
// 响应式状态
|
|
||||||
const uiState = ref({
|
|
||||||
currentSlide: 0,
|
|
||||||
autoPlayInterval: null as NodeJS.Timeout | null
|
|
||||||
})
|
|
||||||
|
|
||||||
// 轮播图控制
|
|
||||||
const goToSlide = (index: number) => {
|
|
||||||
uiState.value.currentSlide = index
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextSlide = () => {
|
|
||||||
const nextIndex = (uiState.value.currentSlide + 1) % carouselData.length
|
|
||||||
goToSlide(nextIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
const startAutoPlay = () => {
|
|
||||||
uiState.value.autoPlayInterval = setInterval(nextSlide, pageConfig.carousel.autoPlayInterval)
|
|
||||||
}
|
|
||||||
|
|
||||||
const stopAutoPlay = () => {
|
|
||||||
if (uiState.value.autoPlayInterval) {
|
|
||||||
clearInterval(uiState.value.autoPlayInterval)
|
|
||||||
uiState.value.autoPlayInterval = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 动态加载资源
|
// 动态加载资源
|
||||||
const loadResources = () => {
|
const loadResources = () => {
|
||||||
// 加载CSS
|
// 加载CSS
|
||||||
|
|
@ -117,7 +88,6 @@ const handleDropdownImageHover = (index: number) => {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadResources()
|
loadResources()
|
||||||
handleAnchorLinks()
|
handleAnchorLinks()
|
||||||
startAutoPlay()
|
|
||||||
|
|
||||||
// 绑定事件
|
// 绑定事件
|
||||||
const solutionTabs = document.querySelectorAll('.solution .items-body li')
|
const solutionTabs = document.querySelectorAll('.solution .items-body li')
|
||||||
|
|
@ -130,10 +100,6 @@ onMounted(() => {
|
||||||
item.addEventListener('mouseenter', () => handleDropdownImageHover(index))
|
item.addEventListener('mouseenter', () => handleDropdownImageHover(index))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
stopAutoPlay()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -141,22 +107,20 @@ onUnmounted(() => {
|
||||||
<!-- 轮播图 -->
|
<!-- 轮播图 -->
|
||||||
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
|
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
|
||||||
<ol class="carousel-indicators" style="background-color: rgba(0,0,0,0.08);">
|
<ol class="carousel-indicators" style="background-color: rgba(0,0,0,0.08);">
|
||||||
<li
|
<li data-slide-to="0" data-target="#carousel-example-generic" class="active"></li>
|
||||||
v-for="(item, index) in carouselData"
|
<li data-slide-to="1" data-target="#carousel-example-generic"></li>
|
||||||
:key="index"
|
<li data-slide-to="2" data-target="#carousel-example-generic"></li>
|
||||||
:class="{ active: index === uiState.currentSlide }"
|
|
||||||
:data-slide-to="index"
|
|
||||||
data-target="#carousel-example-generic"
|
|
||||||
/>
|
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div class="carousel-inner" role="listbox">
|
<div class="carousel-inner" role="listbox">
|
||||||
<div
|
<div class="item active">
|
||||||
v-for="(item, index) in carouselData"
|
<img alt="成本降低,效率更高" src="/img/yuxiupdata/banner_2021_1.png" style="width: 100%;">
|
||||||
:key="index"
|
</div>
|
||||||
:class="['item', { active: index === uiState.currentSlide }]"
|
<div class="item">
|
||||||
>
|
<img alt="成本降低,效率更高" src="/img/yuxiupdata/banner_2021_2.png" style="width: 100%;">
|
||||||
<img :alt="item.alt" :src="item.image" style="width: 100%;">
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img alt="共享单车最佳拍档" src="/img/yuxiupdata/index23.png" style="width: 100%;">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
186
轮播图样式冲突处理经验总结.md
Normal file
186
轮播图样式冲突处理经验总结.md
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
# 轮播图样式冲突处理经验总结
|
||||||
|
|
||||||
|
## 问题背景
|
||||||
|
|
||||||
|
在开发过程中,遇到了首页轮播图的多重控制冲突问题。项目同时存在:
|
||||||
|
- Vue 3 组件控制
|
||||||
|
- Bootstrap 轮播组件
|
||||||
|
- 传统 jQuery 轮播脚本
|
||||||
|
- 自定义 JavaScript 轮播逻辑
|
||||||
|
|
||||||
|
## 冲突分析
|
||||||
|
|
||||||
|
### 1. 控制层级冲突
|
||||||
|
```
|
||||||
|
Vue 组件 (主要控制)
|
||||||
|
├── 响应式状态管理 (uiState.currentSlide)
|
||||||
|
├── 自动播放逻辑 (5秒间隔)
|
||||||
|
└── 数据驱动显示 (carouselData)
|
||||||
|
|
||||||
|
Bootstrap 轮播 (样式支持)
|
||||||
|
├── data-ride="carousel" 自动初始化
|
||||||
|
├── 指示器点击事件
|
||||||
|
└── CSS 动画效果
|
||||||
|
|
||||||
|
传统 JS 轮播 (可能冲突)
|
||||||
|
├── jQuery fadeIn/fadeOut 动画
|
||||||
|
├── 4秒间隔自动播放
|
||||||
|
└── 鼠标悬停控制
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 时间间隔冲突
|
||||||
|
- Vue 组件:5秒自动播放
|
||||||
|
- 传统 JS:4秒自动播放
|
||||||
|
- 导致轮播图切换频率不一致
|
||||||
|
|
||||||
|
### 3. DOM 操作冲突
|
||||||
|
- Vue 响应式更新 DOM
|
||||||
|
- 传统 JS 直接操作 DOM
|
||||||
|
- 可能相互覆盖对方的修改
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 1. 识别主要控制方式
|
||||||
|
通过代码分析,确定 Vue 组件是主要控制方式:
|
||||||
|
```typescript
|
||||||
|
// Vue 组件控制逻辑
|
||||||
|
const uiState = ref({
|
||||||
|
currentSlide: 0,
|
||||||
|
autoPlayInterval: null
|
||||||
|
})
|
||||||
|
|
||||||
|
const startAutoPlay = () => {
|
||||||
|
uiState.value.autoPlayInterval = setInterval(nextSlide, 5000)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 移除冲突控制
|
||||||
|
完全移除 Vue 组件中的轮播图控制逻辑:
|
||||||
|
- 删除响应式状态管理
|
||||||
|
- 移除自动播放函数
|
||||||
|
- 清理生命周期钩子
|
||||||
|
|
||||||
|
### 3. 使用静态 HTML 结构
|
||||||
|
将动态 Vue 模板改为静态 HTML:
|
||||||
|
```html
|
||||||
|
<!-- 之前:Vue 动态控制 -->
|
||||||
|
<div v-for="(item, index) in carouselData"
|
||||||
|
:class="['item', { active: index === uiState.currentSlide }]">
|
||||||
|
|
||||||
|
<!-- 之后:静态 HTML -->
|
||||||
|
<div class="item active">
|
||||||
|
<img src="/img/banner_1.png">
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 保留 Bootstrap 功能
|
||||||
|
保持 Bootstrap 轮播的基础功能:
|
||||||
|
```html
|
||||||
|
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
|
||||||
|
<ol class="carousel-indicators">
|
||||||
|
<li data-slide-to="0" class="active"></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 处理步骤
|
||||||
|
|
||||||
|
### 1. 代码分析
|
||||||
|
- 使用 `codebase_search` 分析轮播图控制逻辑
|
||||||
|
- 识别所有相关的 JS 文件和组件
|
||||||
|
- 理解各控制方式的职责
|
||||||
|
|
||||||
|
### 2. 冲突识别
|
||||||
|
- 发现多重控制冲突
|
||||||
|
- 分析时间间隔差异
|
||||||
|
- 确定主要控制方式
|
||||||
|
|
||||||
|
### 3. 渐进式修改
|
||||||
|
- 先移除 Vue 响应式控制
|
||||||
|
- 保留 Bootstrap 基础功能
|
||||||
|
- 使用静态 HTML 结构
|
||||||
|
|
||||||
|
### 4. 验证结果
|
||||||
|
- 检查 linter 错误
|
||||||
|
- 确保功能正常
|
||||||
|
- 避免新的冲突
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
### 1. 单一控制原则
|
||||||
|
- 一个轮播图只使用一种控制方式
|
||||||
|
- 避免多重框架同时控制同一元素
|
||||||
|
|
||||||
|
### 2. 明确职责分工
|
||||||
|
- Vue 组件:业务逻辑和状态管理
|
||||||
|
- Bootstrap:样式和基础交互
|
||||||
|
- 传统 JS:特定功能增强
|
||||||
|
|
||||||
|
### 3. 渐进式重构
|
||||||
|
- 先分析现有控制方式
|
||||||
|
- 逐步移除冲突代码
|
||||||
|
- 保持功能完整性
|
||||||
|
|
||||||
|
### 4. 文档记录
|
||||||
|
- 记录控制方式变更
|
||||||
|
- 说明冲突解决过程
|
||||||
|
- 为后续维护提供参考
|
||||||
|
|
||||||
|
## 技术要点
|
||||||
|
|
||||||
|
### Vue 3 响应式控制
|
||||||
|
```typescript
|
||||||
|
// 响应式状态
|
||||||
|
const uiState = ref({
|
||||||
|
currentSlide: 0,
|
||||||
|
autoPlayInterval: null
|
||||||
|
})
|
||||||
|
|
||||||
|
// 自动播放控制
|
||||||
|
const startAutoPlay = () => {
|
||||||
|
uiState.value.autoPlayInterval = setInterval(nextSlide, 5000)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bootstrap 轮播配置
|
||||||
|
```html
|
||||||
|
<!-- 自动初始化 -->
|
||||||
|
<div class="carousel slide" data-ride="carousel">
|
||||||
|
<!-- 指示器控制 -->
|
||||||
|
<li data-slide-to="0" data-target="#carousel-example-generic">
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 传统 JS 轮播
|
||||||
|
```javascript
|
||||||
|
// 自动播放
|
||||||
|
function bannerMoveks(){
|
||||||
|
timer_banner = setInterval(function(){
|
||||||
|
move_banner()
|
||||||
|
}, 4000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鼠标交互
|
||||||
|
$('.banner').mouseover(function(){
|
||||||
|
clearInterval(timer_banner);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 经验总结
|
||||||
|
|
||||||
|
1. **冲突识别**:通过代码分析快速识别多重控制冲突
|
||||||
|
2. **渐进式解决**:逐步移除冲突代码,保持功能完整
|
||||||
|
3. **单一控制**:确保一个元素只使用一种控制方式
|
||||||
|
4. **文档记录**:详细记录解决过程,便于后续维护
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 面试者简答
|
||||||
|
|
||||||
|
**面试官**:请描述一次你解决前端样式冲突的经历。
|
||||||
|
|
||||||
|
**我**:在开发一个共享单车项目时,遇到了首页轮播图的多重控制冲突问题。项目同时存在Vue 3组件控制、Bootstrap轮播和传统jQuery脚本,导致轮播图行为不一致。
|
||||||
|
|
||||||
|
我首先通过代码分析识别了冲突源头:Vue组件使用5秒自动播放,传统JS使用4秒,两者同时操作DOM导致冲突。然后我采用了渐进式解决方案:完全移除Vue组件的轮播控制逻辑,改为静态HTML结构,保留Bootstrap的基础功能。
|
||||||
|
|
||||||
|
最终实现了单一控制原则,避免了多重框架冲突,确保了轮播图的稳定运行。这次经历让我深刻理解了前端开发中避免样式冲突的重要性,以及如何通过合理的架构设计来预防类似问题。
|
||||||
Loading…
Reference in New Issue
Block a user