侧边栏壁纸
博主头像
云BLOG 博主等级

行动起来,活在当下

  • 累计撰写 318 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录
WEB

高级 localStorage 管理器

Administrator
2025-03-01 / 0 评论 / 0 点赞 / 1 阅读 / 0 字
/**
 * Layui 自定义模块:高级 localStorage 管理器
 */
layui.define(function(exports) {
  const storage = {
    // 默认配置
    _config: {
      maxInactiveTime: 3600, // 默认 1 小时未使用则清理
      excludeKeys: ['token', 'theme'] // 默认排除项
    },

    // 初始化方法(自动调用)
    _init: function() {
      // 合并全局配置(从 layui.config() 获取)
      const globalConfig = (layui.config().mystorage || {});
      this._config = { ...this._config, ...globalConfig };
      this._excludeKeys = [...this._config.excludeKeys, '_lastUpdated', '_lastCleaned'];
      this.cleanup();
      this._startAutoCleanup();
    },

    // 设置数据
    set: function(key, value, expire) {
      try {
        const data = { value, time: Date.now(), expire: expire ? Date.now() + expire * 1000 : null };
        localStorage.setItem(key, JSON.stringify(data));
        this._updateTimestamp();
      } catch (error) {
        console.error('localStorage 存储失败:', error);
      }
      return this;
    },

    get: function(key, defaultValue = null) {
      try {
        const data = localStorage.getItem(key);
        if (!data) return defaultValue;
        const parsedData = JSON.parse(data);
        if (parsedData.expire && Date.now() > parsedData.expire) {
          this.remove(key);
          return defaultValue;
        }
        this._updateTimestamp();
        return parsedData.value;
      } catch (error) {
        this.remove(key);
        return defaultValue;
      }
    },

    remove: function(key) {
      if (Array.isArray(key)) {
        key.forEach(k => this._safeRemove(k));
      } else {
        this._safeRemove(key);
      }
      this._updateTimestamp();
      return this;
    },

    clear: function() {
      Object.keys(localStorage).forEach(k => {
        if (!this._excludeKeys.includes(k)) localStorage.removeItem(k);
      });
      this._updateTimestamp();
      return this;
    },

    cleanup: function() {
      const now = Date.now();
      Object.keys(localStorage).forEach(k => {
        if (this._excludeKeys.includes(k)) return;
        const data = localStorage.getItem(k);
        if (!data) return;
        try {
          const parsedData = JSON.parse(data);
          const isExpired = parsedData.expire && now > parsedData.expire;
          const isInactive = now - parsedData.time > this.config.maxInactiveTime * 1000;
          if (isExpired || isInactive) this._safeRemove(k);
        } catch (error) {
          this._safeRemove(k);
        }
      });
      localStorage.setItem('_lastCleaned', now);
    },

    // 私有方法
    _safeRemove: function(key) {
      if (this._excludeKeys.includes(key)) return;
      localStorage.removeItem(key);
    },

    _updateTimestamp: function() {
      localStorage.setItem('_lastUpdated', Date.now());
    },

    _startAutoCleanup: function() {
      setInterval(() => this.cleanup(), this.config.maxInactiveTime * 1000);
    }
  };

  // 导出模块
  exports('mystorage', storage);
});

以下是基于 Layui 的完整使用示例,包含自定义模块 mystorage 的配置、初始化及与其他内置模块的协同操作:

一、完整代码示例

以下是基于 Layui 的完整使用示例,包含自定义模块 mystorage 的配置、初始化及与其他内置模块的协同操作:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Layui 自定义模块完整示例</title>
  <!-- 引入 Layui 样式 -->
  <link rel="stylesheet" href="layui/css/layui.css">
</head>
<body>
  <div class="layui-container">
    <!-- 表单示例 -->
    <form class="layui-form" style="margin-top: 20px;">
      <div class="layui-form-item">
        <label class="layui-form-label">用户名</label>
        <div class="layui-input-block">
          <input type="text" name="username" lay-verify="required" placeholder="请输入用户名" class="layui-input">
        </div>
      </div>
      <div class="layui-form-item">
        <div class="layui-input-block">
          <button class="layui-btn" lay-submit lay-filter="save">保存数据</button>
        </div>
      </div>
    </form>

    <!-- 表格示例 -->
    <table id="demoTable" lay-filter="demoTable"></table>
  </div>

  <!-- 引入 Layui 核心库 -->
  <script src="layui/layui.js"></script>
  
  <script>
    // 配置自定义模块路径(假设 mystorage.js 存放在 layui/lay/modules/ 目录下)
    layui.config({
      base: 'layui/lay/modules/' 
    }).use(['form', 'table', 'layer', 'laydate', 'element', 'mystorage'], function() {
      // 获取模块实例
      const form = layui.form;
      const table = layui.table;
      const layer = layui.layer;
      const mystorage = layui.mystorage; 

      // ------------------ 初始化 mystorage ------------------
      // 自定义配置(覆盖默认配置)
      mystorage.config({
        maxInactiveTime: 86400, // 24 小时未使用则清理
        excludeKeys: ['userSession'] // 永久保留的键名
      });

      // ------------------ 业务逻辑示例 ------------------
      // 1. 表单数据存储
      // 读取已保存的用户名
      const savedUsername = mystorage.get('username');
      if (savedUsername) {
        $('input[name="username"]').val(savedUsername);
        form.render(); // 更新表单样式
      }

      // 监听表单提交
      form.on('submit(save)', function(data) {
        const username = data.field.username;
        // 存储数据(设置 1 小时过期)
        mystorage.set('username', username, 3600); 
        layer.msg('数据已保存');
        return false;
      });


      // 读取已保存的主题
      const savedTheme = storage.get('theme');
      if (savedTheme) {
        document.querySelector('input[name="theme"]').value = savedTheme;
      }

      // 监听表单提交
      form.on('submit(save1)', function(data) {
        const theme = data.field.theme;
        storage.set('theme', theme); // 永久存储(在 excludeKeys 中)
        layer.msg('主题已保存');
        return false;
      });

      // 2. 表格数据缓存
      // 初始化表格
      table.render({
        elem: '#demoTable',
        url: '/api/data',
        page: mystorage.get('tablePage', true), // 读取缓存的分页状态
        cols: [[
          {field: 'id', title: 'ID'},
          {field: 'name', title: '名称'}
        ]],
        done: function() {
          // 缓存当前分页状态
          mystorage.set('tablePage', this.page);
        }
      });
    });
  </script>
</body>
</html>

二、关键代码解析

1. 模块加载与初始化

javascript

复制

layui.config({
  base: 'layui/lay/modules/' // 指定自定义模块存放目录
}).use(['form', 'table', 'layer', 'mystorage'], function() {
  // 模块加载完成后的回调
  const form = layui.form;
  const mystorage = layui.mystorage;
});
  • layui.config:配置自定义模块的存放路径。

  • layui.use:加载模块(内置模块 + 自定义模块),加载顺序无关。

2. 自定义模块配置

javascript

复制

mystorage.config({
  maxInactiveTime: 86400, // 覆盖默认配置
  excludeKeys: ['userSession'] // 追加保留项
});
  • 此配置会合并到模块默认配置中,优先级高于默认值。

3. 与表单模块协同

javascript

复制

// 读取缓存数据
const savedUsername = mystorage.get('username');
$('input[name="username"]').val(savedUsername);

// 监听提交事件
form.on('submit(save)', function(data) {
  mystorage.set('username', data.field.username, 3600);
});
  • 通过 mystorage.get() 实现表单数据的持久化。

  • 结合 form.on() 实现数据存储的触发逻辑。

4. 与表格模块协同

javascript

复制

table.render({
  page: mystorage.get('tablePage', true),
  done: function() {
    mystorage.set('tablePage', this.page);
  }
});
  • 读取缓存的表格分页状态。

  • 表格渲染完成后自动更新缓存。


三、目录结构建议

复制

项目根目录/
├── layui/
│   ├── css/
│   │   └── layui.css
│   ├── layui.js
│   └── lay/
│       └── modules/
│           └── mystorage.js  # 自定义模块文件
└── index.html

四、注意事项

  1. 路径匹配:确保 layui.config({ base: '...' }) 指向正确的自定义模块目录。

  2. 错误处理:生产环境中建议在 mystorage.set()mystorage.get() 中添加 try-catch

  3. 敏感数据:避免直接存储密码等敏感信息,必要时加密处理。

通过这种方式,你的自定义模块与 Layui 原生模块实现了 无缝集成,代码风格和调用方式完全一致,符合 Layui 的模块化设计哲学。

以下是基于 Layui 的完整使用示例,包含自定义模块的配置、初始化及与其他内置模块的协同操作:

0

评论区