插槽的应用

2024-01-18 20:17:45 浏览数 (3)

最近在做的项目是智慧屏项目,用于公司的电视屏展示,它采用的技术栈是vue js sass,项目很多采用的都是组件化,用组件化的优点就是可复用性高,减少代码冗余,组件化的思想在开发中很常见也很重要。下面将这次项目中自己做的不足的点以及需要注意的点列举出来。感兴趣的朋友可以看看。

1.页面展示
2.组件化思想

简单来说,组件就是将一段UI样式和其对应的功能作为独立的整体去看待,无论这个整体放在哪里去使用,它都具有一样的功能和样式,从而实现复用,这种整体化的思想就是组件化。不难看出,组件化设计就是为了增加复用性,灵活性,提高系统设计,从而提高开发效率。

3.插槽
  • 需求1:点击底部的导航栏,出现一个弹窗; 思路:因为导航栏都是一样的,因此我把导航栏做成了一个组件,起名叫Footer.vue 因为点击头部的和底部的导航栏都会出现一个弹窗,因此把这做成了一个弹窗组件,起名叫DialogBox.vue。
  • 需求2:弹窗打开后,点击旁边的非弹窗组件都能关闭; 思路:这里用到的是插槽,打开弹窗后点击非弹窗的周边的时候,用一个方法去接收这个参数,将它返回。

关于插槽的详细内容可以看vue官方文档:https://cn.vuejs.org/v2/guide/components-slots.html

4.源代码

Footer.vue

代码语言:javascript复制
<template>
  <div class="Footer">
    <!-- 底部导航栏 -->
    <div class="FooterWrap">
      <div
        class="FooterNav"
        v-for="(item, index) in list"
        :key="index"
        @click="openDialog(index)"
      >
  //点击的时候,传入了导航组件的索引index
        <img :src="item.img" />
        <div class="title">{{ item.title }}</div>
      </div>
    </div>
      <!-- 弹窗 -->
    <DialogBox
      v-if="list[currentIndex].showDetail == true"
      @close="closeDialogBox"
    >
    //showDetail 是弹窗的状态
    //弹窗关闭绑定一个方法
      <div v-if="!isShow">
        <img :src="list[currentIndex].con" :class="popStyle[currentIndex]" />
      </div>
       //五个导航的图片展示
       // isShow为0显示图片,为1显示组件
       //注意:我写条件的思维是错的,应该先是v-if里面放一个变量,然后再在js里面定义它的初始变量,再到后面写的方法中重新拿这个变量写条件及方法!
      //这里有一个巧妙的地方就是:里面依次循环的图片宽高是不同的,给图片绑定一个类名,在js中做成一个数组依次读取它的样式。
      <SwitcHover v-if="isShow && DialogBoxStatus"></SwitcHover>
      //政策内容展示组件
      //DialogBoxStatus  政策内容弹窗状态
      //弹窗里面有两种情况:点击政策查询出现的是一个政策内容展示组件,点击其他五个导航是出现图片
    </DialogBox>
  </div>
</template>

<script>
import DialogBox from "./DialogBox.vue";
import SwitcHover from "./SwitcHover.vue";
export default {
  name: "Footer",
  components: {
    DialogBox,
    SwitcHover,
  },
  data() {
    return {
      DialogBoxStatus: false, // 政策内容弹窗状态显示隐藏标识
      popStyle: [
        "btn-img01",
        "btn-img02",
        "btn-img03",
        "btn-img04",
        "btn-img05",
        "btn-img06",
      ],
      list: [
        {
          title: "招商",
          img: require("../assets/footer1.png"),
          con: require("../assets/footerImg01.png"),
          showDetail: false,
        },
        {
          title: "政策查询",
          img: require("../assets/footer2.png"),
          con: require("../assets/footerImg03.png"),
          showDetail: false,
        },
        {
          title: "会议预定",
          img: require("../assets/footer3.png"),
          con: require("../assets/footerImg03.png"),
          showDetail: false,
        },
        {
          title: "咖啡厅",
          img: require("../assets/footer4.png"),
          con: require("../assets/footerImg04.png"),
          showDetail: false,
        },
        {
          title: "停车缴费",
          img: require("../assets/footer5.png"),
          con: require("../assets/footerImg05.png"),
          showDetail: false,
        },
        {
          title: "接驳巴士",
          img: require("../assets/footer6.png"),
          con: require("../assets/footerImg06.png"),
          showDetail: false,
        },
      ],
      currentIndex: 0,
      beforeIndex: 0,
      isShow: 0,
    };
  },
  mounted() {},
  methods: {
    // 弹窗关闭
    closeDialogBox() {
      this.DialogBoxStatus = false;    //里层的(政策内容的组件)
      this.list[this.currentIndex].showDetail = false; //外层的
    },

    //点击出现弹窗
    openDialog(index) {
      // isShow为0显示图片,为1显示组件
      if (index == 1) {
        this.isShow = true;
      } else {
        this.isShow = false;
      }
      this.DialogBoxStatus = true;
      // index,currentIndex:当前索引
      // beforeIndex:前一个对象的索引
      if (index != this.beforeIndex) {
        this.list[index].showDetail = true;
      } else {
        this.list[index].showDetail = !this.list[index].showDetail;
      }
      this.currentIndex = this.beforeIndex = index;
    },
  },
};
</script>

DialogBox.vue。

代码语言:javascript复制
<template>
  <!-- 弹出框 -->
  <div class="Dialog-box_wrapper" @click="close">
    <div class="contentWrap" @click.stop>
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "DialogBox",
  data() {
    return {};
  },
  mounted() {},
  methods: {
    close () {
      this.$emit('close');
    }
  },
};
</script>

<style lang="scss" scoped>
.Dialog-box_wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 300;
  width: 100%;
  height: 100%;
  background: rgba($color: #000000, $alpha: 0.5);
  .contentWrap {
    width: auto;
  }
}
</style>

在弹出框组件DialogBox.vue里面用了插槽,在它的外层容器(即非弹窗区)绑定了一个方法@click=“close”,并且在它的子元素阻止它冒泡,而在Footer.vue是 @close=“closeDialogBox” 接收这个东西。 在弹出框组件DialogBox.vue写方法close () { this.$emit(‘close’); }

$em

1 人点赞