今日はポップアップレイヤーをカプセル化して親コンポーネントで呼び出し、ポップアップレイヤーにカルーセルを表示したいと思います。
まず、サブコンポーネントのカプセル化
<template>
<el-dialog
v-model="dialogVisible"
:title="title"
width="1000px"
style="height: 80vh"
custom-class="openAnimAbcd"
draggable
>
<div class="change-img" @mouseover="stopChange" @mouseleave="startChange">
<div class="img-container">
<img
:src="img"
alt=""
v-for="(img, index) in props.images"
:key="index"
/>
</div>
<div class="prev" @click="goPrev">《</div>
<div class="next" @click="goNext">》</div>
<ul class="icon">
<li
v-for="(item, index) in images"
:key="index"
@click="changeImg(index)"
ref="indexRef"
>
{
{ index }}
</li>
</ul>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">下次再提醒</el-button>
<el-button @click="dialogVisible = false"> 不再提醒 </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
const props = defineProps({
images: {
type: [String, Array],
// default: NaN,
},
title: {
type: String,
default: "",
},
});
const currentIndex = ref(0);
const dialogVisible = ref(false);
const t = ref(null);
// 轮播图自动切换:每隔2秒切换图片
function autoChange() {
t.value = setInterval(() => {
if (currentIndex.value === props.images.length - 1) {
currentIndex.value = 0;
} else {
currentIndex.value++;
}
changeImg(currentIndex.value);
}, 5000);
}
// 切换图片
function changeImg(i) {
document.querySelector(".img-container").style.transform = `translate(${
-900 * i
}px)`;
changeIcomColor(i);
}
// 鼠标移入容器内,停止自动切换图片
function stopChange() {
clearInterval(t.value);
}
// 鼠标移出容器内,继续自动切换图片
function startChange() {
autoChange();
}
// 点击上一张图片
function goPrev() {
if (currentIndex.value === 0) {
currentIndex.value = props.images.length - 1;
} else {
currentIndex.value--;
}
changeImg(currentIndex.value);
}
// 点击下一张图片
function goNext() {
if (currentIndex.value === props.images.length - 1) {
currentIndex.value = 0;
} else {
currentIndex.value++;
}
changeImg(currentIndex.value);
}
// 切换图片,同时执行索引按钮显示红色的函数
// 根据当前图片索引,对应按钮变成红色
function changeIcomColor(i) {
this.$refs.indexRef.forEach((l) => {
l.style.backgroundColor = "";
});
this.$refs.indexRef[i].style.backgroundColor = "red";
}
const open = () => {
dialogVisible.value = true;
};
defineExpose({
open,
});
autoChange();
</script>
<style scoped>
/* 轮播图 */
.change-img {
width: 900px;
height: 65%;
position: relative;
overflow: hidden;
}
.img-container {
/* 图片列表容器宽度:图片高度*图片个数 */
width: 2700px;
height: 450px;
display: flex;
}
.img-container img {
width: 900px;
height: 100%;
}
.change-img .prev,
.change-img .next {
position: absolute;
top: 45%;
width: 20px;
height: 30px;
background: #666;
color: #fff;
line-height: 30px;
cursor: pointer;
}
.change-img .prev {
left: 5px;
text-align: left;
}
.change-img .next {
right: 5px;
text-align: right;
}
.change-img .icon {
position: absolute;
bottom: 10px;
right: 25%;
}
.change-img .icon li {
float: left;
list-style: none;
width: 20px;
height: 20px;
background: #666;
color: #fff;
margin-left: 10px;
text-align: center;
line-height: 20px;
border-radius: 50%;
overflow: hidden;
cursor: pointer;
}
</style>
必要な内容を詳しく説明します サブコンポーネントには vue2 の props に相当する const props=defineProps ({}) が必要です 中括弧内に受け取る具体的な値を記述します また、親コンポーネントから渡された値が導入されるので、.valueは追加する必要はありませんが、props.xxxは追加する必要があります。
const props=defineProps({
images: {
type: [String, Array],
default: NaN,
},
title: {
type: String,
default: "",
},
});
const DialogVisible = ref(false); ポップアップレイヤーの表示を定義していますが、vue2 での定義とは異なり、vue3 ではそのまま使用するように定義されています。ポップアップレイヤーを表示するための open メソッドを記述します。defineExpose を記述する必要があることに注意してください。そうしないと、親コンポーネントが呼び出されません~
const open = () => {
dialogVisible.value = true;
};
defineExpose({
open,
});
次に親コンポーネントを起動します
登録不要で通常導入後すぐにご利用いただけます。
<SlideShow ref="childRef" :images="images" :title="title" /> の使用
const childRef = ref(null); //これはjsに登録する必要があります
onMounted(() => {
setTimeout(() => {
//タイマーをセットする
childRef.value.open(); 子コンポーネントのメソッドを呼び出してポップアップ レイヤーを開きます。
}, 1000);
});