单例模式实战:如何优雅地实现一个登录弹窗

97 阅读3分钟

今天我们来聊聊单例模式在前端开发中的妙用——实现一个高性能的登录弹窗。

为什么需要单例模式?

想象一下这个场景:你的网站有个登录功能,90%的用户可能根本不会点击登录按钮。如果一开始就加载登录弹窗的所有HTML、CSS和JS资源,是不是有点浪费?

这就是单例模式的用武之地!我们可以推迟创建这个弹窗,直到用户第一次需要它的时候,并且在整个应用中只创建一次,后续都复用这个实例。

单例模式初体验

先来看一个最简单的实现:

const Modal = (function(){
    let modal = null
    return function(){
        if(!modal){
            modal = document.createElement('div')
            modal.innerHTML = '我是弹窗内容'
            modal.id = 'modal'
            modal.style.display = 'none'
            document.body.appendChild(modal);
        }
        return modal
    }
})()

这里我们使用了立即执行函数(IIFE)闭包来保持modal实例的唯一性。当用户第一次调用时创建弹窗,后续调用都返回同一个实例。

完整代码实现

让我们看一个完整的例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Modal 登录弹窗单例</title>
    <style>
        #modal {
            height: 200px;
            width: 200px;
            line-height: 200px;
            position: fixed;
            left: 50%;
            top: 50%;
            transform: translate(-50%,-50%);
            border: 1px solid #000;
            text-align: center;
        }
    </style>
</head>
<body>
    <button id="open">打开弹窗</button>
    <button id="close">关闭弹窗</button>
    <script>
        // 单例
        const Modal = (function(){
            let modal = null
            return function(){
                if(!modal){
                    modal = document.createElement('div')
                    modal.innerHTML = 'fog'
                    modal.id = 'modal'
                    modal.style.display = 'none'
                    document.body.appendChild(modal);
                }
                return modal
            }
        })()
        document.getElementById('open').addEventListener('click',() => {
            const modal = new Modal();
            modal.style.display = 'block'
        })
        document.getElementById('close').addEventListener('click',() => {
            const modal = new Modal();
            modal.style.display = 'none'
        })
    </script>
</body>
</html>

为什么这样设计?

  1. 延迟加载:只有在第一次click时才会创建弹窗,节省初始加载资源
  2. 全局唯一:通过闭包保持modal变量,确保整个应用只有一个弹窗实例

实际项目中的应用

在实际项目中,我们可能会这样使用:

// 需要登录时
function checkLogin() {
    if (!isLogin) {
        const modal = LoginModal.getInstance();
        modal.open();
        return modal.login().then(() => {
            // 登录成功后操作
        });
    }
    return Promise.resolve();
}

// 点击购买按钮
buyButton.addEventListener('click', () => {
    checkLogin().then(() => {
        // 执行购买逻辑
    });
});

单例模式的优缺点

优点:

  1. 节省资源:延迟创建,减少初始加载负担
  2. 避免重复:确保全局唯一实例
  3. 统一管理:所有操作都通过单例接口

缺点:

  1. 难以测试:全局状态可能导致测试困难
  2. 违反单一职责:单例类既管理生命周期又处理业务逻辑

总结

单例模式在前端开发中非常实用,特别是对于弹窗、全局状态管理等场景。通过延迟创建和实例复用,我们可以显著提升应用性能。记住,好的设计模式应该像好的UI一样——用户(开发者)几乎感觉不到它的存在,但却能提供流畅的体验。

希望这篇笔记对你有所帮助!如果你有更好的实现方式,欢迎在评论区分享~

掘金金句
"代码如诗,模式如韵。单例虽小,却能让你的应用轻盈如燕。"
"前端优化不在于做多少,而在于不做多少。单例模式教会我们:有时候,少即是多。"