Browse Source

全局提示组件

zq-popup
zq 1 day ago
parent
commit
97d9142155
  1. BIN
      src/assets/message_Success.png
  2. BIN
      src/assets/message_Warning.png
  3. BIN
      src/assets/message_error.png
  4. 4
      src/components/Footer.vue
  5. 170
      src/components/GuipMessage/GuipMessage.vue
  6. 94
      src/components/GuipMessage/index.js
  7. 8
      src/main.js
  8. 2
      src/style/theme/common.scss
  9. 26447
      src/style/theme/index.css
  10. 31
      src/views/elementGroups.vue

BIN
src/assets/message_Success.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/message_Warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/message_error.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

4
src/components/Footer.vue

@ -10,10 +10,10 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: #626573 color: #626573;
a{ a{
text-decoration: none; text-decoration: none;
color: #006AFF; color: #006AFF !important;
} }
} }
</style> </style>

170
src/components/GuipMessage/GuipMessage.vue

@ -0,0 +1,170 @@
<template>
<transition name="fade">
<div v-if="visible" class="custom-message" :class="[type, position]">
<img v-if="showImage" :src="imageUrl" class="message-image" />
<i v-else :class="iconClass"></i>
<span class="message-content">{{ message }}</span>
</div>
</transition>
</template>
<script>
export default {
name: 'CustomMessage',
props: {
type: {
type: String,
default: 'info',
validator: value => ['success', 'warning', 'error', 'info'].includes(value)
},
message: {
type: String,
required: true
},
duration: {
type: Number,
default: 3000
},
position: {
type: String,
default: 'top-center',
validator: value => ['top-center', 'top-right', 'top-left', 'bottom-center', 'bottom-right', 'bottom-left'].includes(value)
},
showImage: {
type: Boolean,
default: false
},
imageUrl: {
type: String,
default: ''
},
iconClass: {
type: String,
default: ''
}
},
data() {
return {
visible: false
}
},
mounted() {
this.visible = true
this.startTimer()
},
methods: {
startTimer() {
if (this.duration > 0) {
setTimeout(() => {
this.close()
}, this.duration)
}
},
close() {
this.visible = false
setTimeout(() => {
this.$destroy()
this.$el.parentNode.removeChild(this.$el)
}, 300)
}
}
}
</script>
<style scoped>
.custom-message {
position: fixed;
z-index: 9999;
display: flex;
align-items: center;
padding: 14px 21px;
transition: all 0.3s;
font-size: 14px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.08em;
color: #626573;
border-radius: 4px;
background: #FFFFFF;
/* 阴影/低阴影 */
box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.16);
}
/* 位置样式 */
.top-center {
top: 20px;
left: 50%;
transform: translateX(-50%);
}
.top-right {
top: 20px;
right: 20px;
}
.top-left {
top: 20px;
left: 20px;
}
.bottom-center {
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.bottom-right {
bottom: 20px;
right: 20px;
}
.bottom-left {
bottom: 20px;
left: 20px;
}
/* 类型样式 */
/* .success {
background-color: #f6ffed;
border: 1px solid #b7eb8f;
color: #52c41a;
}
.info {
background-color: #e6f7ff;
border: 1px solid #91d5ff;
color: #1890ff;
}
.warning {
background-color: #fffbe6;
border: 1px solid #ffe58f;
color: #faad14;
}
.error {
background-color: #fff2f0;
border: 1px solid #ffccc7;
color: #f5222d;
} */
.message-image {
width: 18px;
height: 18px;
margin-right: 10px;
}
/* 动画效果 */
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s, transform 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.fade-enter.top-center, .fade-leave-to.top-center {
transform: translate(-50%, -20px);
}
.fade-enter.top-right, .fade-leave-to.top-right,
.fade-enter.top-left, .fade-leave-to.top-left {
transform: translateY(-20px);
}
.fade-enter.bottom-center, .fade-leave-to.bottom-center {
transform: translate(-50%, 20px);
}
.fade-enter.bottom-right, .fade-leave-to.bottom-right,
.fade-enter.bottom-left, .fade-leave-to.bottom-left {
transform: translateY(20px);
}
</style>

94
src/components/GuipMessage/index.js

@ -0,0 +1,94 @@
import Vue from 'vue'
import GuipMessage from './GuipMessage.vue'
// 默认图标配置
const defaultIcons = {
success: 'icon-success', // 替换为你的图标类名
info: 'icon-info',
warning: 'icon-warning',
error: 'icon-error'
}
// 默认图片配置
const defaultImages = {
success: require('@/assets/message_Success.png'),
info: require('@/assets/message_Warning.png'),
warning: require('@/assets/message_Warning.png'),
error: require('@/assets/message_error.png')
}
const MessageConstructor = Vue.extend(GuipMessage)
// let messageInstance = null
let messageQueue = []
function showMessage(options) {
if (typeof options === 'string') {
options = {
message: options
}
}
// 合并默认配置
const config = {
type: 'info',
duration: 3000,
position: 'top-center',
showImage: true,
...options
}
// 设置图标或图片
if (config.showImage) {
config.imageUrl = options.imageUrl || defaultImages[config.type]
} else {
config.iconClass = options.iconClass || defaultIcons[config.type]
}
// 创建实例
const instance = new MessageConstructor({
propsData: config
})
// 挂载到DOM
instance.$mount()
document.body.appendChild(instance.$el)
// 添加到队列
messageQueue.push(instance)
// 返回关闭方法
return {
close: () => instance.close()
}
}
function install(Vue, options = {}) {
// 合并默认配置
if (options.icons) {
Object.assign(defaultIcons, options.icons)
}
if (options.images) {
Object.assign(defaultImages, options.images)
}
// 添加全局方法
Vue.prototype.$Message = showMessage
Vue.prototype.$Message.closeAll = () => {
messageQueue.forEach(instance => instance.close())
messageQueue = []
}
// 添加快捷方法
const types = ['success', 'info', 'warning', 'error']
types.forEach(type => {
Vue.prototype.$Message[type] = (message, options = {}) => {
return showMessage({
message,
type,
...options
})
}
})
}
export default { install }

8
src/main.js

@ -9,12 +9,14 @@ import './style/theme/index.css'
import './style/theme/common.scss' import './style/theme/common.scss'
import 'core-js/stable'; import 'core-js/stable';
import 'regenerator-runtime/runtime'; import 'regenerator-runtime/runtime';
import LoadingService from './services/loading' import LoadingService from './services/loading';
import { directive as clickaway } from 'vue-clickaway'; import { directive as clickaway } from 'vue-clickaway';
Vue.prototype.$loadingFn = LoadingService import GuipMessage from '@/components/GuipMessage/index';
Vue.config.productionTip = false Vue.prototype.$loadingFn = LoadingService;
Vue.config.productionTip = false;
Vue.prototype.$http = request; Vue.prototype.$http = request;
Vue.use(ElementUI); Vue.use(ElementUI);
Vue.use(GuipMessage)
Vue.directive('clickaway', clickaway); Vue.directive('clickaway', clickaway);
new Vue({ new Vue({

2
src/style/theme/common.scss

@ -279,6 +279,7 @@ body {
background: #FFFFFF; background: #FFFFFF;
border: 1px solid #006AFF; border: 1px solid #006AFF;
&:hover{ &:hover{
color: #006AFF;
background: #F2F7FF; background: #F2F7FF;
border: 1px solid #006AFF; border: 1px solid #006AFF;
} }
@ -308,6 +309,7 @@ body {
border: 1px solid #DFE2E6; border: 1px solid #DFE2E6;
&:hover{ &:hover{
background: #FFFFFF; background: #FFFFFF;
color: #006AFF;
border: 1px solid #006AFF; border: 1px solid #006AFF;
} }
} }

26447
src/style/theme/index.css

File diff suppressed because it is too large

31
src/views/elementGroups.vue

@ -271,6 +271,13 @@
<GuipButton type="primary" :btnstyle="btnstyleObj">宽高自定义</GuipButton> <GuipButton type="primary" :btnstyle="btnstyleObj">宽高自定义</GuipButton>
</div> </div>
<div class="ele-item">
<label for="">提示</label>
<GuipButton type="system" @click="openMessage('success')">成功提示</GuipButton>
<GuipButton type="system" @click="openMessage('error')"> 失败提示</GuipButton>
<GuipButton type="system" @click="openMessage('info')">警告提示</GuipButton>
</div>
<div style="width: 600px;"> <div style="width: 600px;">
<h3>表单左右布局直接使用封装好的input</h3> <h3>表单左右布局直接使用封装好的input</h3>
<!-- 表单左右布局 --> <!-- 表单左右布局 -->
@ -617,6 +624,30 @@ export default {
}, },
methods: { methods: {
openMessage(type){
console.log(type);
//
switch(type){
case 'success':
this.$Message.success('成功,文案自定义')
break;
case 'error':
this.$Message.error('失败,文案自定义')
break;
case 'info':
this.$Message.info('提示,文案自定义')
break;
}
//
// this.$Message({
// type: 'success',
// title: '',
// message: '',
// duration: 5000,
// showClose: true,
// center: true
// })
},
showTooltip() { showTooltip() {
this.$refs.tooltip.show() this.$refs.tooltip.show()
}, },

Loading…
Cancel
Save