/**
* 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四、注意事项
路径匹配:确保
layui.config({ base: '...' })指向正确的自定义模块目录。错误处理:生产环境中建议在
mystorage.set()和mystorage.get()中添加try-catch。敏感数据:避免直接存储密码等敏感信息,必要时加密处理。
通过这种方式,你的自定义模块与 Layui 原生模块实现了 无缝集成,代码风格和调用方式完全一致,符合 Layui 的模块化设计哲学。
以下是基于 Layui 的完整使用示例,包含自定义模块的配置、初始化及与其他内置模块的协同操作:
评论区