以单例模式实现登录弹窗

75 阅读2分钟

以单例模式实现登录弹窗

在现代 Web 应用和桌面应用中,登录弹窗(Login Modal) 是用户交互中非常常见的一部分。为了提高性能和用户体验,我们通常希望在整个应用中只创建一个登录弹窗的实例,并在需要时反复使用它。这种需求正好契合了 单例模式(Singleton Pattern) 的设计理念。

一、什么是单例模式?

单例模式 是一种创建型设计模式,它保证一个类在整个应用程序中只有一个实例,并提供一个全局访问点来访问该实例。

单例模式的典型应用场景包括:

  • 数据库连接池
  • 日志记录器
  • 全局配置对象
  • 登录弹窗、提示框等 UI 组件

二、为什么使用单例模式实现登录弹窗?

大部分网站用户是不会去登录的,而登录组件又比较复杂,所以首页加载时不会对改组件进行加载。登录组件的加载会被推迟到第一使用的时候,而又由于之后可能还会复用到这个组件,所以也不能在用完之后就卸载。所以需要实现的功能是能够在第一次使用时才加载,之后直接从缓存中获取。

使用单例模式可以实现这个功能,它可以确保:

  • 弹窗只被创建一次。
  • 所有组件访问的是同一个弹窗实例。
  • 弹窗状态统一管理,便于控制显示、隐藏、数据更新等操作。

三、使用 JavaScript 实现登录弹窗的单例模式

下面是一个使用 JavaScript 实现的登录弹窗单例示例:

// 将弹窗动态的添加到body中,只有当使用时候才加载
      const Model = (function () {
        let instance = null;
        return function () {
          if (!instance) {
            
            instance = document.createElement("div");
            // 添加id
            instance.id = 'model'
            // 
            instance.style = 'display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#fff;padding:20px;'

            instance.innerHTML = `
                        <form class="login-form">
                            <label for="username">用户名</label>
                            <input type="text" id="username" name="username" required>
                            <label for="password">密码</label>
                            <input type="password" id="password" name="password" required>
                            <button type="submit">登录</button>
                        </form>
                    `;
            document.body.appendChild(instance)
          }
          return instance;
        };
      })();
      
      const open = document.getElementById("open");
      const close = document.getElementById("close");
      open.addEventListener('click',(e)=>{
        const model = new Model()
        model.style.display = 'block'
      })
      close.addEventListener('click',(e)=>{
        const model = new Model()
        model.style.display = 'none'
      })

代码解析

  1. 闭包实现私有变量

    使用 JavaScript 的 IIFE(立即调用函数表达式)和闭包来模拟私有变量 instance,确保外部无法直接访问或修改实例。

  2. 延迟初始化(Lazy Initialization)

    只有在第一次调用 new Model() 时才创建实例,避免不必要的资源占用。

  3. 弹窗复用

    无论调用多少次 new Model(),返回的都是同一个对象,保证了弹窗的唯一性和可复用性。

HTML 部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录弹窗单例示例</title>
</head>
<body>

    <button id="open">打开弹窗</button>
    <button id="close">关闭弹窗</button>

<script src="login-modal.js"></script>

</body>
</html>

实现效果

tanc.gif