如何写一个全局的 Notice 组件?
下面将会实现这样的效果:
组件动态创建脚本:
import Vue from "vue";
import Notice from "@/components/Noticer/Notice.vue";
function create(Component, props) {
// 先建立实例
const vm = new Vue({
render(h) {
//h就是createElement,它返回VNode
return h(Component, { props });
},
}).$mount();
// 手动挂载
// 判断是否存在container,如果不存在则先创建
let container;
container = document.querySelector(".noticer-container");
if (container == null) {
container = document.createElement("div");
container.classList.add("noticer-container");
container.style.position = "fixed";
container.style.top = "50px";
container.style.right = "0px";
container.style.overflow = "hidden";
container.style.zIndex = 9999;
document.body.appendChild(container);
}
container.appendChild(vm.$el);
//销毁方法
const comp = vm.$children[0];
comp.remove = function () {
container.removeChild(comp["$el"]);
vm.$destroy();
};
comp.show();
return comp;
}
Vue.prototype.$notice = {
error: function (props) {
create(Notice, Object.assign(props, { type: "error" }));
},
info: function (props) {
create(Notice, Object.assign(props, { type: "info" }));
},
success: function (props) {
create(Notice, Object.assign(props, { type: "success" }));
},
warn: function (props) {
create(Notice, Object.assign(props, { type: "warn" }));
},
};
这里有一些值得注意的地方:
- container: 的作用是notice的容器,它可以用于定位notice在页面的哪里展示,注意notice不应该随页面卷动,因此其定位是
fixed
, 而之所以设定为overflow:hidden
的原因则是,notice 在出现和移除的时候,发生的动画偏移,会让页面出现横向滚动条。为了避免重复创建container, 这里做了一个判断逻辑。然后所有动态生成的notice实例dom都会通过appendChild
添加到这个容器。 - 在移除的时候, 移除的是
vm.$children[0]["$el"]
, 原因是,Notice 模板的实现中,外层套了一个 transition , 而这个transition是并不会渲染dom的。
创建Notice组件模板:
<template>
<transition
enter-active-class="animate__animated animate__slideInRight"
leave-active-class="animate__animated animate__slideOutRight"
@after-leave="afterLeave"
>
<div v-if="isShow" class="notice__root">
<div :class="`notice-type-${type}`" class="noticer">
{{
type === "error"
? "🍓"
: type === "success"
? "🍀"
: type === "warn"
? "🍋"
: "🐳"
}}
: {{ message }}
</div>
</div>
</transition>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "",
},
message: {
type: String,
default: "",
},
time: {
type: Number,
default: 1000,
},
type: {
type: String,
},
},
data() {
return {
isShow: false,
};
},
methods: {
show() {
this.isShow = true;
setTimeout(this.hide, this.time);
},
hide() {
this.isShow = false;
},
afterLeave() {
this.remove();
},
},
};
</script>
<style lang="less" scoped>
@error: rgb(255, 30, 30);
@warn: rgb(240, 192, 0);
@success: rgb(0, 144, 74);
@info: rgb(0, 80, 218);
@errorBg: rgb(255, 208, 208);
@warnBg: rgb(255, 245, 207);
@successBg: rgb(210, 255, 233);
@infoBg: rgb(203, 222, 255);
.notice__root {
user-select: none;
padding: 5px 50px 5px 5px;
}
.noticer {
padding: 5px 20px;
margin: 10px 0px;
// margin-right: 50px;
border-radius: 8px;
font-size: 16px;
width: auto;
min-width: 280px;
max-width: 300px;
word-break: break-all;
text-align: center;
box-sizing: border-box;
}
.notice-type-error {
color: @error !important;
border: 2px solid @error;
box-shadow: 1px 1px 5px 2px @errorBg;
background-color: @errorBg;
// border: 1px solid red;
}
.notice-type-warn {
color: @warn !important;
border: 2px solid @warn;
background-color: @warnBg;
box-shadow: 1px 1px 5px 2px @warnBg;
}
.notice-type-success {
color: @success !important;
border: 2px solid @success;
background-color: @successBg;
box-shadow: 1px 1px 5px 2px @successBg;
}
.notice-type-info {
color: @info !important;
border: 2px solid @info;
background-color: @infoBg;
box-shadow: 1px 1px 5px 2px @infoBg;
}
</style>
在 main.js 中引入执行该脚本即可
import Vue from "vue";
import App from "./App.vue";
import "animate.css";
import "@/components/Noticer/NotificationBanner.js";
new Vue({
render: (h) => h(App),
}).$mount("#app");
代码中使用实例:
if (!this.nickname) {
this.$notice.error({
message: "好汉!姓甚名谁?",
time: 3000,
});
} else {
this.showModal = false;
this.$notice.info({
message: this.nickname + "来了!!!",
time: 3000,
});
}
动态创建组件的执行逻辑:
当在使用的时候:
this.$notice.error({
message: "好汉!姓甚名谁?",
time: 3000,
});
上方代码触发,实际上会触发 NotificationBanner.js 中的 create
函数,该函数创建了一个notice 的组件实例,并在实力上添加了一个remove
方法,然后直接触发组件中的 show
方法。
notice 模板实例中:
methods: {
show() {
this.isShow = true;
setTimeout(this.hide, this.time);
},
hide() {
this.isShow = false;
},
afterLeave() {
this.remove();
},
},
show
方法执行,除了展示 notice,立即设定一个延时函数执行 hide
方法。
hide
方法执行, vue 提供的 transition 钩子 afterleave()
会在移除动画执行完毕后触发。 这时候,去触发 remove
方法,将该notice 组件实例移除。
如何写一个全局的 Notice 组件?的更多相关文章
- 手写一个简单的starter组件
spring-boot中有很多第三方包,都封装成starter组件,在maven中引用后,启动springBoot项目时会自动装配到spring ioc容器中. 思考: 为什么我们springBoot ...
- Tsx写一个通用的button组件
一年又要到年底了,vue3.0都已经出来了,我们也不能一直还停留在过去的js中,是时候学习并且在项目中使用一下Ts了. 如果说jsx是基于js的话,那么tsx就是基于typescript的 废话也不多 ...
- python安装及写一个简单的验证码组件(配合node)
1.安装Python 到官网下载响应系统的版本(这里以windows为例):https://www.python.org/downloads/windows/ 然后就是不断地"下一步&quo ...
- Vue学习—Vue写一个图片轮播组件
1.先看效果: 熟悉的图片轮播,只要是个网站,百分之90以上会有个图片轮播.我认为使用图片轮播. 第一可以给人以一种美观的感受,而不会显得网站那么呆板, 第二可以增加显示内容,同样的区域可以显示更多内 ...
- 用vue2.x注册一个全局的弹窗alert组件
一.在实际的开发当中,弹窗是少不了的,默认系统的弹窗样式太丑,难以满足项目的实际需求,所以需要自己定义弹窗组件,把弹窗组价定义为全局的,这样减少每次使用的时候引入麻烦,节省开发时间.本文将分享如何定义 ...
- 用vue2.x注册一个全局的弹窗alert组件、confirm组件
一.在实际的开发当中,弹窗是少不了的,默认系统的弹窗样式太丑,难以满足项目的实际需求,所以需要自己定义弹窗组件,把弹窗组价定义为全局的,这样减少每次使用的时候引入麻烦,节省开发时间.本文将分享如何定义 ...
- react全局的公共组件-------弹框 (Alert)
最近研究react,发现写一个组件很容易,但是要写一个全局的好像有点麻烦.不能像VUE一样,直接在原型上面扩展,注册全局组件 下面实现一个弹框,只需要引入之后,直接调用方法即可,不需要写入组件 给出我 ...
- 如何优雅的写一个Vue 的弹框
写Vue或者是react 都会遇见弹框的问题.也尝试了多种办法来写弹框,一直都不太满意,今天特地看了一下 Element UI 的源码,模仿着写了一个简易版. 大概有一下几个问题: 1.弹框的层级问题 ...
- 从零开始写一个npm包,一键生成react组件(偷懒==提高效率)
前言 最近写项目开发新模块的时候,每次写新模块的时候需要创建一个组件的时候(包含组件css,index.js,组件js),就只能会拷贝其他组件修改名称 ,但是写了1-2个后发现效率太低了,而且极容易出 ...
随机推荐
- EMS邮箱数据库常用命令(二)
1.查询邮箱数据库的使用空间 查询Exchange环境中所有邮箱数据库. 键入以下命令 Get-MailboxDatabase -Status | FL name,DatabaseSize 命令执行后 ...
- FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码
之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...
- QT-守护程序
功能:手动选择EXE文件 1.手动开启应用,关闭应用 2.选择是否自动开启应用程序 3.将应用程序名称,操作,时间记入TXT文档 涉及:文件写入操作,基本控件使用.Windows命令使用 Github ...
- 『忘了再学』Shell基础 — 9、Bash中的特殊符号(一)
目录 1.双单引号 2.双引号 3.$符号 4.反引号 5.$()符号 6.#符号 7.\符号 1.双单引号 '':单引号.在单引号中所有的特殊符号,如$和"`"(反引号)都没有特 ...
- 基础设施即代码(IAC),Zalando Postgres Operator UI 入门
Postgres Operator UI 提供了一个图形界面,方便用户体验数据库即服务.一旦 database 和/或 Kubernetes (K8s) 管理员设置了 operator,其他团队就很容 ...
- Angular项目构建指南 - 不再为angular构建而犹豫不决(转)
如果你不知道什么是Angular或者根本没听说过,那么我接下来所说的对你来说毫无益处,不过如果你打算以后会接触Angular或者干脆要涨涨姿势~读下去还是有点用的. Angular和它之前所出现的其余 ...
- 2021.08.06 P4392 Sound静音问题(ST表)
2021.08.06 P4392 Sound静音问题(ST表) [P4392 BOI2007]Sound 静音问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 序列a,求 ...
- Python多线程Threading爬取图片,保存本地,openpyxl批量插入图片到Excel表中
之前用过openpyxl库保存数据到Excel文件写入不了,换用xlsxwriter 批量插入图片到Excel表中 1 import os 2 import requests 3 import re ...
- 前台主页搭建、后台主页轮播图接口设计、跨域问题详解、前后端互通、后端自定义配置、git软件的初步介绍
今日内容概要 前台主页 后台主页轮播图接口 跨域问题详解 前后端打通 后端自定义配置 git介绍和安装 内容详细 1.前台主页 Homeviwe.vue <template> <di ...
- [笔记] Slope Trick:解决一类凸代价函数的DP优化问题
原理 当序列 DP 的转移代价函数满足 连续: 凸函数: 分段线性函数. 时,可以通过记录分段函数的最右一段 \(f_r(x)\) 以及其分段点 \(L\) 实现快速维护代价的效果. 如:$ f(x) ...