这是我参与「第四届青训营 」笔记创作活动的第8天.
背景:
在同一个父组件中有两个子组件,其中一个子组件作为弹窗被隐藏,而另一个子组件中的按钮能够触发该弹窗子组件.
弹窗子组件:
html部分:
<template>
<!-- 收藏列表 -->
<div class="CollectList">
<div class="title">
<h1>选择收藏集</h1>
<div class="sub_title">选择或创建你想添加的收藏集</div>
</div>
</div>
</template>
js部分:
<script>
export default {
name: "CollectList",
}
</script>
css部分:
<style>
.CollectList {
width: 520px;
height: 486px;
background: red;
}
</style>
触发弹窗组件的子组件
html部分:
<template>
<!-- 详情页左侧 -->
<div class="DetailPageLeft">
<div class="DetailPageLeft_container">
<!-- 点赞按钮 -->
<div class="good">
<div @mouseenter="good_enter" @mouseleave="good_leave" @click="good_num_click" class="img_container"
:data_good_num="good_num_this">
<img v-if="good_flag" src="../../assets/DetailPageLeft/good.png">
<img v-if="!good_flag" src="../../assets/DetailPageLeft/good_active.png">
</div>
</div>
<!-- 评论按钮 -->
<div class="suggest">
<div class="img_container" @mouseenter="suggest_enter" @mouseleave="suggest_leave"
:data_suggest_num="suggest_num">
<img v-if="suggest_flag" src="../../assets/DetailPageLeft/suggest.png">
<img v-if="!suggest_flag" src="../../assets/DetailPageLeft/suggest_active.png">
</div>
</div>
<!-- 收藏按钮 -->
<div class="collect">
<div class="img_container" @click="collect_click" @mouseenter="collect_enter" @mouseleave="collect_leave">
<img v-if="collect_flag" src="../../assets/DetailPageLeft/collect.png">
<img v-if="!collect_flag" src="../../assets/DetailPageLeft/collect_active.png">
</div>
</div>
<!-- 分享按钮 -->
<div class="share">
<div class="img_container" @mouseenter="share_enter" @mouseleave="share_leave">
<img v-if="share_flag" src="../../assets/DetailPageLeft/share.png">
<img v-if="!share_flag" src="../../assets/DetailPageLeft/share_active.png">
</div>
</div>
<!-- 举报按钮 -->
<div class="report">
<div class="img_container" @mouseenter="report_enter" @mouseleave="report_leave">
<img v-if="report_flag" src="../../assets/DetailPageLeft/report.png">
<img v-if="!report_flag" src="../../assets/DetailPageLeft/report_active.png">
</div>
</div>
<!-- 阅读模式按钮 -->
<div class="book">
<div class="img_container" @mouseenter="book_enter" @mouseleave="book_leave">
<img v-if="book_flag" src="../../assets/DetailPageLeft/book.png">
<img v-if="!book_flag" src="../../assets/DetailPageLeft/book_active.png">
</div>
</div>
</div>
</div>
</template>
其中触发蒙版及弹唱的部分是收藏按钮部分.
js部分:
<script>
export default {
name: "DetailPageLeft",
data() {
return {
// flag_list: [true, true, true, true, true, true,],
//判断光标是否进入各个图片按钮.
good_flag: true,
suggest_flag: true,
collect_flag: true,
share_flag: true,
report_flag: true,
book_flag: true,
good_num_this: this.good_num,
good_num_flag_this: this.good_flag,
}
},
//接收点赞次数和留言数量.
props: {
good_num: {
type: Number, //类型判断
required: true, //必要性
},
suggest_num: {
type: Number,
required: true,
},
//之前是否为本文章点赞.
good_num_flag: {
type: Boolean, //类型判断
required: true, //必要性
}
},
methods: {
//光标按钮进入事件,用于改变图片.
good_enter() {
this.good_flag = false;
},
good_leave() {
this.good_flag = true;
},
suggest_enter() {
this.suggest_flag = false;
},
suggest_leave() {
this.suggest_flag = true;
},
collect_enter() {
this.collect_flag = false;
},
collect_leave() {
this.collect_flag = true;
},
share_enter() {
this.share_flag = false;
},
share_leave() {
this.share_flag = true;
},
report_enter() {
this.report_flag = false;
},
report_leave() {
this.report_flag = true;
},
book_enter() {
this.book_flag = false;
},
book_leave() {
this.book_flag = true;
},
//点击事件
//点赞事件
good_num_click() {
if (!this.good_num_flag_this) {//还未点过赞.
this.good_num_this++;
this.good_num_flag_this = !this.good_num_flag_this;
} else {
this.good_num_this--;
this.good_num_flag_this = !this.good_num_flag_this;
}
},
//点击评论按钮.
suggest_click() {//可尝试用组件通信,利用a标签定位实现.
},
collect_click() {//点击该按钮,将原有页面增加蒙版,然后跳出收藏夹组件
// height: 100px;
// background-color: #fff;
// filter: Alpha(Opacity=60);
// opacity: 0.6;
this.$emit('get_collect_open_flag', true)
},
},
}
</script>
其中collect_click()实现了父子组件之间的通信,该子组件通过$emit向父组件传递名为get_collect_open_flag的true信息.告诉父组件要开启蒙版,弹出弹窗子件.
css部分:
<style>
.DetailPageLeft {
width: 70px;
height: 700px;
color: #000;
/* background: red; */
padding-left: 30px;
}
.img_container {
background: white;
width: 50px;
height: 50px;
border: 0;
border-radius: 50%;
}
.DetailPageLeft_container {
position: absolute;
top: 200px;
}
.good,
.suggest,
.collect,
.share,
.report,
.book {
margin-bottom: 20px;
position: relative;
}
.DetailPageLeft_container img {
margin-top: 12px;
width: 25px;
height: 25px;
}
/*::after伪类选择器,为点赞按钮和评论按钮右上角增加数据*/
.good .img_container::after {
content: attr(data_good_num);
}
.suggest .img_container::after {
content: attr(data_suggest_num);
}
.img_container::after {
position: absolute;
border-radius: 9px;
background-color: #c2c8d1;
line-height: 17px;
left: 75%;
padding: 0 4px;
/*增加padding 让背景更宽阔*/
}
</style>
父组件:
html:
<template>
<!-- 文章详情页 -->
<div class="DetailPage" id="DetailPage">
<DetailPageLeft :suggest_num="suggest_num" :good_num="good_num" :good_num_flag="good_num_flag"
@get_collect_open_flag="collect_open_flag"></DetailPageLeft>
<CollectList v-if="collect_open_flag_this" class="CollectList"></CollectList>
<button @click="close_collect">关闭蒙版</button>
</div>
</template>
其中用v-if="collect_open_flag_this"来控制弹窗组件是否渲染,用 @get_collect_open_flag="collect_open_flag"来接收子组件的信息,知道该开启弹窗了.并且触发js的collect_open_flag();
js部分:
<script>
import DetailPageLeft from './DetailPageLeft.vue';
import CollectList from './CollectList.vue';
export default {
name: "DetailPage",
components: { DetailPageLeft, CollectList },
data() {
return {
suggest_num: 13,
good_num: 2,
good_num_flag: true,
collect_open_flag_this: false,
}
},
methods: {
// 打开蒙版
collect_open_flag() {
console.log(this.collect_open_flag_this);
// console.log(document.getElementsByClassName('DetailPage'));
document.getElementById('DetailPage').classList.add('masking');
this.collect_open_flag_this = !this.collect_open_flag_this;
document.getElementById('CollectList').classList.remove('masking');
},
// 关闭蒙版同时关闭收藏列表
close_collect() {
document.getElementById('DetailPage').classList.remove('masking');
this.collect_open_flag_this = !this.collect_open_flag_this;
}
},
}
</script>
collect_open_flag_this: false变量控制着弹窗是否出现.collect_open_flag()打开弹窗创建蒙版,close_collect()关闭弹窗消去蒙版.其中通过this.collect_open_flag_this = !this.collect_open_flag_this;来改变变量的值来了控制弹窗. 而通过document.getElementById('DetailPage').classList.add('masking');来为容器标签增加类型,再通过css达到蒙版效果.
css:
<style>
.DetailPage {
background: #e4e6eb;
width: 200px;
position: relative;
}
/*蒙版统一样式*/
.masking {
background-color: #fff;
filter: Alpha(Opacity=60);
opacity: 0.6;
}
/* 收藏列表 */
.CollectList {
position: fixed;
top: 200px;
left: 450px;
}
</style>
通过该类名达到创建蒙版的效果.
.masking {
background-color: #fff;
filter: Alpha(Opacity=60);
opacity: 0.6;
}
效果图:
点击收藏按钮后