Vue3: Communication between parent and child components, encapsulating the pop-up layer of the carousel

Today I want to encapsulate a pop-up layer and call it in the parent component. I want to display the carousel in the pop-up layer.

First, the encapsulation of subcomponents

<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>

Let's talk about the necessary content in detail. const props=defineProps ({}) is required for subcomponents, which is equivalent to the props of vue2. The specific values ​​received are written in the curly braces. In addition, the value passed from the parent component is introduced. You don’t need to add .value, but you need to add props.xxx

const props=defineProps({
  images: {
    type: [String, Array],
    default: NaN,
  },
  title: {
    type: String,
    default: "",
  },
});

const dialogVisible = ref(false); defines the display of the pop-up layer, which is different from the definition in vue2, and vue3 is defined as it is used. Write an open method to make the pop-up layer appear. It should be noted that you must write defineExpose, otherwise the parent component will not be called~

const open = () => {
  dialogVisible.value = true;
};
defineExpose({
  open,
});

Next, start the parent component

It can be used directly after the normal introduction without registration.

   <SlideShow ref="childRef" :images="images" :title="title" />    使用

const childRef = ref(null); //This must be registered in js

onMounted(() => {

  setTimeout(() => {

    //set timer

    childRef.value.open(); Call the method of the child component to open the popup layer

  }, 1000);

});

Guess you like

Origin blog.csdn.net/weixin_47194802/article/details/130357237