最近在做的项目是智慧屏项目,用于公司的电视屏展示,它采用的技术栈是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