????????最近项目上出现了一个“收集用户反馈”需求,大概的执行流程就是:点击按钮,弹出对话框,在对话框中收集用户评价,最后再输出。正好这个项目是用的ElementUi,所以考虑使用Notification这个组件,但是在使用过程中遇到了一系列问题,踩了不少坑,这里做一下总结分享。
1、什么是Notification组件
????????Notification 组件提供通知功能,Element 注册了$notify 方法,接收一个options 字面量参数,在最简单的情况下,你可以设置title 字段和message 字段,用于设置通知的标题和正文。默认情况下,经过一段时间后 Notification 组件会自动关闭,但是通过设置duration ,可以控制关闭的时间间隔,特别的是,如果设置为0 ,则不会自动关闭。注意:duration 接收一个Number ,单位为毫秒,默认为4500 。
这是来自官方文档给出的解释,其具体的执行效果如下:
?2、Notification组件的基本使用
html部分:
<el-button plain @click="open"> 可自动关闭 </el-button>
?js部分:
open() {
this.$notify({
title: '提示', //标题
message: '这是一条不会自动关闭的消息', //内容
duration: 0, //设置弹框消失事件
position:'bottom-right', // 设置弹框在屏幕的哪个角弹出(只能设置4个角)
type: 'warning', //给标题前加一个小图标
offset: 100, //偏移量:距离四个角的偏移程度(默认偏移了16px)
dangerouslyUseHTMLString: true, //是否支持弹出框内传入 HTML 片段
message: '<strong>这是 <i>HTML</i> 片段</strong>', //开启后,这里可以写html
showClose: false, //隐藏关闭按钮(右上角的x 默认为true,显示)
close(){
console.log('弹框被关闭了')
} //点击关闭按钮的回调函数
});
}
Notification组件的执行过程
1)Notification组件是通过触发点击事件open事件发生的;
2)open这个方法执行Element上面注册的$notify的方法;
3)关于close回调函数的使用:
? ? ? ? 关闭某个弹框:this.$notify.close()? ?//想要关闭单个弹框的话需要传入弹框的ID
? ? ? ? 关闭全部弹框:this.$notify.closeAll()
注意:如果在Notification组件中传入Html片段,message里面的html子符串其实是脱离了vue,例如不能用@click方法绑定事件,因此,应该用js的操作dom来绑定。
3、实际案例
????????假设我们有这样一个需求:我们需要点击一个按钮,用来收集用户反馈,我们应该如何使用Notification组件呢?
案例效果:
?
需求分析:
1)我们页面上需要一个可以点击的按钮,来触发这个Notification组件;
2)在Notification组件我们需要输入Html片段;
3)每一个收集到的用户意见,需要自动弹出下一个问题(这里只需要将message的内容写成变量,就不需要再次产生一个弹框了)
注意事项:
1)在第一次触发弹框后,按钮不能再次被点击而触发下一次弹框;
2)在反馈过程中,点击关闭按钮后,能够点击按钮再次弹出第一个弹框,从而再次收集用户反馈;
3)弹框最后一个是“Thank you”内容,需要自动消失。
代码实现:
html部分:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- import CSS -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/theme-chalk/index.css">
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div id="app">
<template>
<el-button class="feedback" plain @click="open">
FEEDBACK
</el-button>
</template>
</div>
</body>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/index.js"></script>
</html>
?js部分:(使用vue2)
data: {
feedback: {
expericene: '',
information: '',
article: '',
useful: false,
},
tittle: '',
message: '',
},
methods: {
open() {
that = this
document.querySelector('.el-button').disabled = true
this.$notify({
title: 'How would you rate your experience?',
message: '这是第一条消息',
duration: 0,
dangerouslyUseHTMLString: true,
message: `<ul class="rectangle-content">
<li id="0" class="first"></li>
<li id="1" class="second"></li>
<li id="2" class="third"></li>
<li id="3" class="fourth"></li>
<li id="4" class="fifth"></li>
</ul>`,
onClose() {
document.querySelector('.el-button').disabled = false
console.log('that.feedback', that.feedback)
}
});
let rectangle = document.querySelectorAll(".rectangle-content li")
var expericene = ['like1', 'like2', 'like3', 'like4', 'like5']
rectangle.forEach((value) => {
var that = this
value.onclick = function () {
this.className = this.className + '-light'
that.feedback.expericene = expericene[this.id]
if (that.feedback.expericene != '') {
that.getInformation()
}
}
})
},
getInformation() {
this.title = 'Were you able to find the information you were looking for?'
this.message = `<div class="rectangle-box">
<div class="box-no">NO</div>
<div class="box-yes">YES</div>
</div>`
var notifyTitle = document.querySelector('.el-notification__title')
var notifyBox = document.querySelector('.el-notification__content p')
notifyTitle.innerHTML = this.title
notifyBox.innerHTML = this.message
let box = document.querySelectorAll(".rectangle-box div")
let information = ''
for (i = 0; i < box.length; i++) {
var that = this
box[i].onclick = function () {
that.feedback.information = this.innerHTML.toLowerCase()
if (that.feedback.information != '') {
that.getArticle()
}
}
}
},
getArticle() {
this.title = 'How useful was this article?'
this.message = `<ul class="artic-content"">
<li class="first">1</li>
<li class="second">2</li>
<li class="third">3</li>
<li class="fourth">4</li>
<li class="fifth">5</li>
</ul>
<div class="useful">
<span class="left">Not useful</span>
<span class="right">Very useful</span>
</div`
var notifyTitle = document.querySelector('.el-notification__title')
var notifyBox = document.querySelector('.el-notification__content p')
notifyTitle.innerHTML = this.title
notifyBox.innerHTML = this.message
let artic = document.querySelectorAll(".artic-content li")
let article = ''
for (i = 0; i < artic.length; i++) {
var that = this
artic[i].classList.remove('colorAdd')
artic[i].onclick = function () {
this.classList.add('colorAdd')
that.feedback.article = this.innerHTML
if (that.feedback.article != '') {
that.getEnd()
}
}
}
},
getEnd() {
this.feedback.useful = true
this.title = 'Thank you for sharing your feedback with us.'
this.message = `<span class='rectangle_detail'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor.</span>`
var notifyTitle = document.querySelector('.el-notification__title')
var notifyBox = document.querySelector('.el-notification__content p')
notifyTitle.innerHTML = this.title
notifyBox.innerHTML = this.message
console.log('first', this.feedback)
if (this.feedback.useful) {
this.feedback = {
expericene: '',
information: '',
article: '',
useful: false,
}
setTimeout(() => {
this.$notify.closeAll()
document.querySelector('.el-button').disabled = this.feedback.useful
}, 1000)
}
},
},
css部分:(此处涉及一些图标,可以自己找一些替换一下)
.feedback {
position: fixed;
right: 0;
bottom: 29%;
width: 49px;
height: 150px;
background-color: #e62f46;
color: white;
border-radius: 0;
}
.feedback span {
display: inline-block;
font-size: 16px;
width: 62.5px;
margin-left: -27px;
transform: rotate(-90deg);
letter-spacing: 0.89px;
position: relative;
}
.feedback:hover,
.feedback:active,
.feedback:focus {
background: #e62f46 !important;
border-color: #e62f46 !important;
color: white !important;
}
.feedback span::after {
position: absolute;
top: -3px;
right: 68px;
content: '';
display: inline-block;
width: 20px;
height: 20px;
background: url(./img/smail.jpg) no-repeat;
background-size: contain;
transform: rotate(90deg);
}
.rext {
display: none;
}
.el-notification {
/* display: block !important; */
top: 70% !important;
width: 450px;
height: 180px;
box-shadow: 4px 4px 22px 0 rgba(0, 0, 0, 0.2);
background-color: var(--white);
text-align: center;
box-sizing: border-box;
overflow: hidden;
border-radius: 0;
border: none;
right: 60px !important;
justify-content: center;
}
.el-notification .el-notification__title {
/* max-width: 330px; */
padding: 0 10px;
font-size: 20px;
font-weight: 550;
margin: 20px auto 23px;
color: #19516c;
letter-spacing: -1.4px;
}
.el-notification .rectangle-content {
display: flex;
justify-content: center;
padding: 0;
margin: 0;
margin-top: 23px;
}
.el-notification .el-icon-close:before {
content: '';
display: inline-block;
width: 20px;
height: 20px;
background: url(./img/icon-close-default.png) no-repeat;
background-size: cover;
}
.el-notification .rectangle-content li {
width: 42px;
height: 42px;
list-style: none;
margin: 0 15px;
cursor: pointer;
text-align: center;
}
.el-notification .rectangle-content .first {
background: url(./img/first_dark.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .first-light {
background: url(./img/first.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .first:hover {
background: url(./img/first.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .first::before,
.el-notification .rectangle-content .first-light::before {
display: none;
content: 'Like';
font-size: 12px;
transform: translateY(46px);
color: rgba(0, 0, 0, 0.2);
}
.el-notification .rectangle-content .first:hover::before,
.el-notification .rectangle-content .first-light:hover::before {
display: block;
}
.el-notification .rectangle-content .second {
background: url(./img/second_dark.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .second-light {
background: url(./img/second.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .second:hover {
background: url(./img/second.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .second::before,
.el-notification .rectangle-content .second-light::before {
display: none;
content: 'Like';
font-size: 12px;
transform: translateY(46px);
color: rgba(0, 0, 0, 0.2);
}
.el-notification .rectangle-content .second:hover::before,
.el-notification .rectangle-content .second-light:hover:before {
display: block;
}
.el-notification .rectangle-content .third {
background: url(./img/third_dark.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .third-light {
background: url(./img/third.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .third:hover {
background: url(./img/third.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .third::before,
.el-notification .rectangle-content .third-light::before {
display: none;
content: 'Like';
font-size: 12px;
transform: translateY(46px);
color: rgba(0, 0, 0, 0.2);
}
.el-notification .rectangle-content .third:hover::before,
.el-notification .rectangle-content .third-light:hover::before {
display: block;
}
.el-notification .rectangle-content .fourth {
background: url(./img/fifth_dark.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .fourth-light {
background: url(./img/fifth.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .fourth:hover {
background: url(./img/fourth.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .fourth::before,
.el-notification .rectangle-content .fourth-light::before {
display: none;
content: 'Like';
font-size: 12px;
transform: translateY(46px);
color: rgba(0, 0, 0, 0.2);
}
.el-notification .rectangle-content .fourth:hover::before,
.el-notification .rectangle-content .fourth-light:hover::before {
display: block;
}
.el-notification .rectangle-content .fifth {
background: url(./img/fifth_dark.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .fifth-light {
background: url(./img/fifth.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .fifth:hover {
background: url(./img/fifth.jpg) no-repeat;
background-size: contain;
}
.el-notification .rectangle-content .fifth::before,
.el-notification .rectangle-content .fifth-light::before {
display: none;
content: 'Like';
font-size: 12px;
transform: translateY(46px);
color: rgba(0, 0, 0, 0.2);
}
.el-notification .rectangle-content .fifth:hover::before,
.el-notification .rectangle-content .fifth-light:hover::before {
display: block;
}
/* second */
.el-notification .rectangle-box {
display: flex;
justify-content: center;
text-align: center;
}
.el-notification .rectangle-box .box-no {
width: 125px;
height: 50px;
box-sizing: border-box;
margin: 0 30px 0 0;
background-color: #19516c;
font-size: 16px;
letter-spacing: 0.53px;
font-weight: 550;
color: white;
line-height: 50px;
cursor: pointer;
}
.el-notification .rectangle-box .box-yes {
width: 125px;
height: 50px;
box-sizing: border-box;
background-color: #e62f46;
font-size: 16px;
letter-spacing: 0.53px;
font-weight: 550;
color: white;
line-height: 50px;
cursor: pointer;
}
/* third */
.el-notification .artic-content {
display: flex;
justify-content: center;
padding: 0;
margin: 0;
cursor: pointer;
margin-bottom: 10px;
text-align: center;
}
.el-notification .artic-content li {
width: 65px;
height: 50px;
box-sizing: border-box;
margin: 0 7px;
line-height: 50px;
background-color: #f0f0f0;
list-style: none;
font-size: 18px;
font-weight: 550;
color: #19516c;
}
.el-notification .artic-content li.colorAdd {
background-color: #19516c;
color: white;
}
.el-notification .artic-content li:hover {
background-color: #19516c;
color: white;
}
.el-notification .useful {
display: flex;
justify-content: center;
text-align: center;
}
.el-notification .useful span {
color: #777777;
font-size: 16px;
line-height: 22px;
letter-spacing: 0.53px;
}
.el-notification .useful span.left {
margin-right: 200px;
}
/* fourth */
.el-notification .rectangle_detail {
margin-top: -10px;
padding: 0 35px;
display: block;
font-size: 16px;
color: black;
line-height: 24px;
text-align: center;
}
@media screen and (max-width:750px) {
body {
margin: 0;
}
.feedback {
position: fixed;
bottom: 40%;
}
.el-notification {
display: block;
right: 0 !important;
top: 65% !important;
left: 50%;
transform: translateX(-50%);
width: 330px;
height: 170px;
}
.el-notification .rectangle-content .first::before,
.el-notification .rectangle-content .second::before,
.el-notification .rectangle-content .third::before,
.el-notification .rectangle-content .fourth::before,
.el-notification .rectangle-content .fifth::before {
transform: translateY(24px);
}
.el-notification .el-notification__title {
font-size: 16px;
}
.el-notification .rectangle-content li {
width: 35px;
height: 35px;
margin: 0px 10px;
}
.el-notification .rectangle_icon {
width: 18px;
height: 18px;
}
.el-notification .rectangle_title {
max-width: 275px;
font-size: 16px;
}
.el-notification .rectangle-box .box-no,
.el-notification .rectangle-box .box-yes {
width: 118px;
height: 40px;
line-height: 40px;
font-size: 15px;
}
.el-notification .artic-content {
padding: 0 10px;
}
.el-notification .artic-content li {
width: 50px;
}
.el-notification .useful span {
font-size: 15px;
display: inline-block;
width: 85px;
}
.el-notification .useful span.left {
margin-right: 66px;
}
.el-notification .useful span.right {
width: 90px;
}
.el-notification .rectangle_detail {
padding: 0 15px;
}
}
如果小伙伴们在开发过程中遇到其他相关问题,欢迎评论区大家一起讨论起来!!!?
|