html
<el-dialog v-model="creativeVisible" title="创意素材预览" width="700px" :destroy-on-close="true">
<div class="text-center" v-if="creativeVisible">
<el-carousel height="500px" :autoplay="false" indicator-position="outside" :key="carouselKey">
<el-carousel-item v-for="(material, index) in currentAdMaterials" :key="index">
<div class="flex flex-col items-center justify-center h-full p-4">
<span class="text-gray-600 mb-2">{{ material.name }}</span>
<div class="h-[420px] w-full flex items-center justify-center bg-gray-50 rounded">
<video v-if="material.type === 'video'" :src="material.url" controls class="max-h-full max-w-full object-contain"></video>
<img v-else-if="material.type === 'image'" :src="material.url" class="max-h-full max-w-full object-contain">
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
</el-dialog>
| 属性/组件 | 功能 |
|-----------|------|
| `el-dialog` | 模态对话框容器 |
| `v-model="creativeVisible"` | 双向绑定控制对话框显示/隐藏 |
| `destroy-on-close` | 关闭时销毁组件,释放内存 |
| `el-carousel` | 走马灯/轮播组件,用于滑动切换素材 |
| `autoplay="false"` | 禁用自动播放,需手动切换 |
| `indicator-position="outside"` | 指示器(圆点)显示在外部 |
| `:key="carouselKey"` | 强制刷新轮播组件(解决切换广告时素材不更新问题)|
// 打开创意预览的方法
const openCreative = async (ad: Ad) => {
currentAd.value = ad
carouselKey.value++ // 触发key更新,强制刷新轮播
creativeVisible.value = true
await nextTick() // 等待DOM更新后再显示
}
```
数据流程
```
用户点击"已选: X个素材"链接
↓
调用 openCreative(row.ad) 方法
↓
保存当前广告对象到 currentAd
↓
递增 carouselKey(强制刷新轮播组件)
↓
设置 creativeVisible = true 显示对话框
↓
currentAdMaterials 计算属性自动计算
↓
遍历素材列表,通过 el-carousel 展示
```
关键设计点
-
**`carouselKey` 的作用**:当用户从广告A切换到广告B时,素材可能不同。通过递增 `carouselKey` 强制 Vue 销毁并重新创建轮播组件,确保素材正确更新。
-
**`destroy-on-close`**:对话框关闭时销毁组件,避免残留状态影响下次打开。
-
**`await nextTick()`**:确保 DOM 更新后再显示对话框,防止首次显示时出现渲染问题。
-
**素材类型判断**:模板中通过 `v-if="material.type === 'video'"` 区分视频和图片,使用不同的标签渲染。
这是一个典型的 **广告素材预览组件**,用于在广告创建/编辑页面预览已选中的创意素材。