VUE组件封装部分:Dialog.vue
<!-- 弹框组件组件 -->
<template>
<div :class="dialogClass" class="warmPrompt">
<van-dialog
v-model="dialogShow"
:closeOnClickOverlay="closeOnClickOverlay"
:overlay="overlay"
:show-confirm-button="false"
width="3rem"
>
<div class="warmPrompt_content">
<div class="warmPrompt_content_title">{{ title }}</div>
<div ref="content_static_wrapper" :style="boxShadow" class="warmPrompt_content_text">
<div ref="content_scroll_wrapper" :style="{'textAlign': textAlign}">
<div v-if="text">{{ text }}</div>
<div v-if="textMini !== ''" class="warmPrompt_content_text--mini">{{ textMini }}</div>
<div v-if="textHtml" v-html="textHtml"></div>
</div>
</div>
<div class="warmPrompt_content_button">
<van-button v-if="cancelButtonShow"
:color="cancelBtnColor"
block
class="cancelButton"
plain
@click="cancel">
{{ cancelButtonText }}
</van-button>
<van-button :color="confirmBtnColor"
block
class="confirmButton"
plain @click="confirm">
{{ confirmButtonText }}
</van-button>
</div>
</div>
</van-dialog>
</div>
</template>
<script>
export default {
name: 'Dialog',
props: {
show: {
type: Boolean,
default: false
},
title: {
type: String,
default: '温馨提示'
},
text: {
type: String,
default: ''
},
textHtml: {
type: String,
default: ''
},
textMini: {
type: String,
default: ''
},
textAlign: {
type: String,
default: 'left'
},
confirmButtonText: {
type: String,
default: '确认'
},
cancelButtonShow: {
type: Boolean,
default: true
},
cancelButtonText: {
type: String,
default: '取消'
},
overlay: {
type: Boolean,
default: true
},
closeOnClickOverlay: {
type: Boolean,
default: false
},
closeOnPopstate: {
type: Boolean,
default: false
},
cancelBtnColor: {
type: String,
default: '#212634'
},
confirmBtnColor: {
type: String,
default: '#FF4536'
},
dialogClass: {
type: String,
default: ''
}
},
data () {
return {
boxShadow: '' // 内容可滚动阴影
}
},
computed: {
dialogShow: {
get () {
return this.show
},
set (val) {
this.$emit('update', val)
}
}
},
watch: {
// 监控内容数据判断是否产生阴影
textHtml: {
handler (newVal, oldVal) {
if (newVal) {
this.$nextTick(() => {
let height1 = this.$refs.content_static_wrapper.getBoundingClientRect()
.height
let height2 = this.$refs.content_scroll_wrapper.getBoundingClientRect()
.height
if (height2 > height1) {
this.boxShadow = 'box-shadow: 0 -0.1rem 0.1rem -0.1rem #d3d4d6 inset;'
} else {
this.boxShadow = ''
}
})
}
},
immediate: true
},
text: {
handler (newVal, oldVal) {
if (newVal) {
this.$nextTick(() => {
let height1 = this.$refs.content_static_wrapper.getBoundingClientRect()
.height
let height2 = this.$refs.content_scroll_wrapper.getBoundingClientRect()
.height
if (height2 > height1) {
this.boxShadow = 'box-shadow: 0 -0.1rem 0.1rem -0.1rem #d3d4d6 inset;'
} else {
this.boxShadow = ''
}
})
}
},
immediate: true
},
textMini: {
handler (newVal, oldVal) {
if (newVal) {
this.$nextTick(() => {
let height1 = this.$refs.content_static_wrapper.getBoundingClientRect()
.height
let height2 = this.$refs.content_scroll_wrapper.getBoundingClientRect()
.height
if (height2 > height1) {
this.boxShadow = 'box-shadow: 0 -0.1rem 0.1rem -0.1rem #d3d4d6 inset;'
} else {
this.boxShadow = ''
}
})
}
},
immediate: true
}
},
// 方法集合
methods: {
// 点击确认按钮
confirm () {
this.$emit('click')
},
// 点击取消按钮
cancel () {
this.$emit('close')
}
}
}
</script>
<style lang='scss' scoped>
/* 使用$符号可以标识一个变量;@import url(); 引入公共css类 */
@import "src/styles/variable";
.warmPrompt {
font-size: 0.14rem;
text-align: center;
line-height: 1;
&_content {
// padding: 0.2rem 0.2rem 0;
::-webkit-scrollbar {
display: none;
}
&_title {
font-size: 0.18rem;
font-weight: 700;
color: #212634;
letter-spacing: 0.02rem;
padding: 0.3rem 0.15rem 0.1rem;
}
&_text {
font-size: 0.16rem;
color: #7A7D85;
letter-spacing: 0.0015rem;
line-height: 1.5;
max-height: 3.8rem;
overflow-y: scroll;
text-align: left;
padding: 0 0.2rem;
pointer-events: all;
word-wrap: break-word;
/deep/ p {
margin: 0 0 0.1rem;
// margin-block-start: 0.1rem;
// margin-block-end: 0;
}
&--mini {
margin-top: 0.1rem !important;
font-size: 0.12rem;
color: #666666;
letter-spacing: 0.0013rem;
}
}
&_button {
padding: 0.16rem 0 0.06rem;
display: flex;
justify-content: space-between;
align-items: center;
/deep/ .van-button::before {
background-color: unset;
}
/deep/ .van-button--block {
height: 0.36rem;
line-height: 0.36rem;
font-size: 0.16rem;
padding: 0;
}
}
}
}
.newDialogClass {
/deep/ .van-dialog {
border-radius: 12 * $px3;
width: 320 * $px3 !important;
}
.warmPrompt_content {
&_title {
padding: 30 * $px3 15 * $px3 10 * $px3;
letter-spacing: 0;
}
&_text {
color: #212634;
}
&_button {
display: flex;
flex-direction: column-reverse;
justify-content: center;
align-items: center;
padding: 20 * $px3 0 30 * $px3;
.confirmButton {
height: 48 * $px3;
width: 240 * $px3;
background-image: linear-gradient(90deg, #FF3F3F 3%, #FB234D 100%);
border-radius: 100 * $px3;
font-size: 18 * $px3 !important;
color: #FFFFFF !important;
font-weight: 700;
}
.cancelButton {
margin-top: 20 * $px3;
height: 20 * $px3;
width: 240 * $px3;
font-size: 18 * $px3 !important;
color: #7A7D85 !important;
font-weight: 700;
}
}
}
}
</style>
js封装部分:dialog-plugin.js
import Dialog from '@/components/WarmPrompt'
let $vm
const defaultOptions = {
show: false,
title: '温馨提示',
text: '',
textHtml: '',
textMini: '',
textAlign: '',
confirmButtonText: '确认',
cancelButtonText: '取消',
cancelButtonShow: true,
closeOnPopstate: true,
overlay: true, // 是否展示遮罩层
closeOnClickOverlay: false, // 是否在点击遮罩层后关闭弹窗
onClick: null,
onClose: null,
bgColor: '#D23228',
cancelBtnColor: '#212634', // 取消按钮颜色
confirmBtnColor: '#FF4536', // 确认按钮颜色
dialogClass: '' // 弹框类名(新的按钮弹框样式)
}
Dialog.install = function (Vue, options = {}) {
Vue.component(Dialog.name, Dialog)
if (!$vm) {
const PropsData = Object.assign({}, defaultOptions, options)
const {
show,
title,
text,
textHtml,
textMini,
textAlign,
confirmButtonText,
cancelButtonText,
cancelButtonShow,
closeOnPopstate,
overlay,
closeOnClickOverlay,
bgColor,
cancelBtnColor,
confirmBtnColor,
dialogClass
} = PropsData
$vm = new Vue({
el: document.createElement('div'),
data () {
return {
showAttr: show,
titleAttr: title,
textAttr: text,
textHtmlAttr: textHtml,
textMiniAttr: textMini,
textAlignAttr: textAlign,
confirmButtonTextAttr: confirmButtonText,
cancelButtonTextAttr: cancelButtonText,
cancelButtonShowAttr: cancelButtonShow,
closeOnPopstateAttr: closeOnPopstate,
overlayAttr: overlay,
closeOnClickOverlayAttr: closeOnClickOverlay,
bgColorAttr: bgColor,
cancelBtnColorAttr: cancelBtnColor,
confirmBtnColorAttr: confirmBtnColor,
dialogClassAttr: dialogClass
}
},
render (h) {
const {
showAttr,
titleAttr,
textAttr,
textHtmlAttr,
textMiniAttr,
textAlignAttr,
confirmButtonTextAttr,
cancelButtonTextAttr,
cancelButtonShowAttr,
closeOnPopstateAttr,
overlayAttr,
closeOnClickOverlayAttr,
onClick,
onClose,
bgColorAttr,
cancelBtnColorAttr,
confirmBtnColorAttr,
dialogClassAttr
} = this
return h(Dialog, {
attrs: {
show: showAttr,
title: titleAttr,
text: textAttr,
textHtml: textHtmlAttr,
textMini: textMiniAttr,
textAlign: textAlignAttr,
confirmButtonText: confirmButtonTextAttr,
cancelButtonText: cancelButtonTextAttr,
cancelButtonShow: cancelButtonShowAttr,
closeOnPopstate: closeOnPopstateAttr,
overlay: overlayAttr,
closeOnClickOverlay: closeOnClickOverlayAttr,
bgColor: bgColorAttr,
cancelBtnColor: cancelBtnColorAttr,
confirmBtnColor: confirmBtnColorAttr,
dialogClass: dialogClassAttr
},
on: {
click: () => {
if (onClick) onClick()
},
close: () => {
this.showAttr = false
if (onClose) onClose()
},
update: (val) => {
this.showAttr = val
}
}
})
},
methods: {
show (opt = {}) {
console.log('已经调用了show方法')
const mergeObj = Object.assign({}, PropsData, { show: true }, opt)
const {
onClick,
onClose,
...otherProps
} = mergeObj
Object.keys(otherProps).forEach(key => {
this[`${key}Attr`] = otherProps[key]
})
this.onClick = onClick
this.onClose = onClose
},
hide () {
this.showAttr = false
},
isShow () {
return this.showAttr
},
update (val) {
this.showAttr = val
}
}
})
document.body.appendChild($vm.$el)
}
const { show, hide, isShow, update } = $vm
Vue.dialog = Vue.prototype.$dialog = {
show,
hide,
isShow,
update
}
}
export default Dialog
添加自定义组件:main.js
/* 添加自定义dialog插件 */
import Dialog from '@/plugins/dialog-plugin'
Vue.use(Dialog)
调用Dialog弹框组件
this.$dialog.show({
title: '弹框名称',
textHtml: `<div>
<div style="font-size: 0.14rem; color: #222222; margin-top: 0.1rem; text-align: left">这是一段富文本</div>
</div>`,
confirmButtonText: '确认按钮',
cancelButtonText: '取消按钮',
onClick: () => {
// 确认按钮点击操作
this.$dialog.hide() // 隐藏弹框
},
onClose: () => {
// 取消按钮点击操作
}
})