自定义组件 - Message 消息提示

news/2024/7/10 1:10:50 标签: 前端, javascript, vue

目录

  • 组成
  • 实现
    • Icon 组件
    • CSS Modules
    • 得到组件渲染的DOM
    • 最终实现
    • 使用

目标:使用 Vue2 的语法,简单实现一个类似 element-ui - Message 消息提示 的组件。

组成

点击上面的链接,可以看到展示效果,由以下几个部分组成:

  • 消息类型
  • icon 图标
  • 消息内容

另外还有2点

  • 消息提示是水平居中的,至于垂直方向的位置,自由度比较高,看具体情况。
  • 消息提示关闭后,设置可以执行一个传入回调函数。

实现

分为下面几个部分。

Icon 组件

这里只是简单实现,详细的实现可以参考这里TODU。

<template>
  <i class="iconfont" :class="'icon-' + name"></i>
</template>

<script>javascript">
export default {
  props: {
    name: String,
  },
};
</script>
<style scoped>
/* 包含了所有的 class */
@import "//at.alicdn.com/t/c/font_4268117_e989xit5r2k.css";
</style>

使用

<Icon name="success" />

CSS Modules

可以在 js 中导入 css 来使用。参考这篇文章

用于导入 Message 组件的 css。

得到组件渲染的DOM

用于获取 Icon 组件的 DOM 元素,和消息内容进行拼接。具体参考这篇文档

最终实现

showMessage.js

import Vue from "vue";
import Icon from "@/components/icon";
import styles from "./showMessage.module.less";

/**
 * 弹出消息
 * @param {String} content 内容
 * @param {String} type 主题  info  error  success  warn
 * @param {Number} duration 显示时间, 毫秒
 * @param {HTMLElement} container 容器,消息在该容器内垂直水平居中;不传则显示到页面正中
 */
export default function (options = {}) {
  const content = options.content || "";
  const type = options.type || "info";
  const duration = options.duration || 2000;
  const container = options.container || document.body;
  // 创建消息元素
  const div = document.createElement("div");
  const iconDom = getComponentRootDom(Icon, {
    name: type,
  });
  div.innerHTML = `<span class="${styles.icon}">${iconDom.outerHTML}</span><div>${content}</div>`;
  // 设置样式
  const typeClassName = styles[`message-${type}`]; //类型样式名
  div.className = `${styles.message} ${typeClassName}`;
  // 将div加入到容器中

  // 容器的 position 是否改动过
  if (options.container && getComputedStyle(container).position === "static") {
    container.style.position = "relative";
  }

  container.appendChild(div);
  // 浏览器强行渲染
  div.clientHeight; // 导致reflow

  // 回归到正常位置
  div.style.opacity = 1;
  div.style.transform = `translate(-50%, -50%)`;

  // 等一段时间,消失
  setTimeout(() => {
    div.style.opacity = 0;
    div.style.transform = `translate(-50%, -50%) translateY(-25px)`;
    div.addEventListener(
      "transitionend",
      function () {
        div.remove();
        // 运行回调函数
        options.callback && options.callback();
      },
      { once: true }
    );
  }, duration);
}

// 获取某个组件渲染的Dom根元素
function getComponentRootDom(comp, props) {
  const vm = new Vue({
    render: (h) => h(comp, { props }),
  });
  vm.$mount();
  return vm.$el;
}

showMessage.module.less

.message {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) translateY(25px);
  z-index: 999;
  border: 1px solid;
  border-radius: 5px;
  padding: 10px 30px;
  line-height: 2;
  display: flex;
  align-items: center;
  transition: 0.4s;
  opacity: 0;
  white-space: nowrap;
  &-info {
    background: #edf2fc;
    color: #909399;
  }
  &-success {
    background-color: #f0f9eb;
    border-color: #e1f3d8;
    color: #67c23a;
  }
  &-warn {
    background-color: #fdf6ec;
    border-color: #faecd8;
    color: #e6a23c;
  }
  &-error {
    background-color: #fef0f0;
    border-color: #fde2e2;
    color: #f56c6c;
  }
}

.icon {
  font-size: 20px;
  margin-right: 8px;
}

使用

可以挂在到 Vue 原型上方便全局使用

import Vue from "vue";
import App from "./App.vue";
import showMessage from "./utils/showMessage";
Vue.prototype.$showMessage = showMessage;

new Vue({
  render: (h) => h(App),
}).$mount("#app");
handleClick() {
  this.$showMessage({
    content: "错误消息",
    type: "error",
    duration: 1500,
  });
}

以上。


http://www.niftyadmin.cn/n/5050406.html

相关文章

Termius 8 for Mac(多协议服务器连接软件)

Termius是一款远程访问和管理工具&#xff0c;旨在帮助用户轻松地远程连接到各种服务器和设备。它适用于多种操作系统&#xff0c;包括Windows、macOS、Linux和移动设备。 该软件提供了一个直观的界面&#xff0c;使用户可以通过SSH、Telnet和Mosh等协议连接到远程设备。它还支…

【【萌新的SOC学习之绪论】】

萌新的SOC学习之绪论 Vitis 统一软件平台的前身为 Xilinx SDK&#xff0c;从 Vivado 2019.2 版本开始&#xff0c;Xilinx SDK 开发环境已统一整合 到全功能一体化的 Vitis 中。Vitis 开发平台除了启动方式、软件界面、使用方法与 SDK 开发平台略有区别&#xff0c; 其他操作几…

【React】函数式组件和类式组件的用法和逻辑

组件的使用 当应用是以多组件的方式实现&#xff0c;这个应用就是一个组件化的应用 注意&#xff1a; 组件名必须是首字母大写虚拟DOM元素只能有一个根元素虚拟DOM元素必须有结束标签 < /> 渲染类组件标签的基本流程React 内部会创建组件实例对象调用render()得到虚拟 …

导出conda某个环境配置,并再另一台机器安装

有网络环境 在源机器上导出conda环境配置&#xff1a; 打开终端或命令提示符。 使用以下命令导出要复制的conda环境的配置。将myenv替换为您要导出的环境的名称&#xff0c;并将environment.yml替换为您希望保存配置的文件名。 conda env export --name myenv > environ…

关于Java NIO的的思考

关于传统IO和NIO的概念和区别什么的就不在这里说明了&#xff0c;这片文章主要是关于通过Java nio来实现异步非阻塞模型&#xff0c;我们先来看一段代码&#xff1a; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import jav…

React 全栈体系(十四)

第七章 redux 六、react-redux 7. 代码 - react-redux 数据共享版 7.1 效果 7.2 App /* src/App.jsx */ import React, { Component } from "react"; import Count from "./containers/Count"; import Person from "./containers/Person";ex…

渲染路径RenderingPath

文章目录 前言一、什么是渲染路径二、渲染路径有哪些1、前向渲染路径2、延迟渲染路径3、顶点照明渲染路径(已过时)4、旧的渲染路径&#xff08;已过时&#xff09; 前言 渲染路径RenderingPath 一、什么是渲染路径 为进行光照计算而设计的渲染方式 二、渲染路径有哪些 1、前向…

【ES】笔记-数值扩展

数值扩展 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>数值扩展</title> </head> &l…