🔧 外部插件
ThinkAdmin 后台前端通过 RequireJS 加载 JavaScript 模块。当前 RequireJS 主配置写在 public/static/admin.js 中,后台模板会先加载 layui.js、require.js,再加载 admin.js 和 public/static/extra/script.js。
📚 加载顺序
后台主布局和插件中心布局的脚本加载顺序一致:
<script src="__ROOT__/static/plugs/jquery/pace.min.js"></script>
<script src="{:url('admin/api.plugs/script',[],false,false)}"></script>
...
<script src="__ROOT__/static/plugs/layui/layui.js"></script>
<script src="__ROOT__/static/plugs/require/require.js"></script>
<script src="__ROOT__/static/admin.js"></script>
<script src="__ROOT__/static/extra/script.js"></script>admin/api.plugs/script 只输出前端变量:
window.taDebug:当前应用是否为调试模式。window.taAdmin:后台入口地址,用于计算动态接口地址。window.taEditor:富文本编辑器类型,来自base.editor配置,默认ckeditor4。
RequireJS 的 paths、shim、baseUrl 等配置由 admin.js 完成,不是由 admin/api.plugs/script 返回。
🚀 基础变量
admin.js 会根据自身脚本地址计算以下变量:
window.appRoot:应用根路径。window.baseRoot:静态资源根路径,RequireJS 的baseUrl使用该值。window.tapiRoot:后台接口根路径,优先使用window.taAdmin,否则回退到appRoot + "admin"。
同时会挂载常用对象:
window.form = layui.formwindow.layer = layui.layerwindow.laytpl = layui.laytplwindow.laydate = layui.laydatewindow.jQuery = window.$ = layui.$
📋 内置模块
当前 admin.js 中配置的常用模块如下:
| 模块名 | 实际路径 | 说明 |
|---|---|---|
excel | plugs/admin/excel | Excel 导入导出工具 |
queue | plugs/admin/queue | 队列前端工具 |
upload | tapiRoot + '/api.upload/index?' | 上传接口脚本 |
validate | plugs/admin/validate | 前端验证工具 |
pcasunzips | plugs/jquery/pcasunzips | 省市区数据 |
vue | plugs/vue/vue.min | Vue |
md5 | plugs/jquery/md5.min | MD5 |
json | plugs/jquery/json.min | JSON 工具 |
xlsx | plugs/jquery/xlsx.min | XLSX 解析 |
jszip | plugs/jquery/jszip.min | ZIP 工具,依赖 filesaver |
marked | plugs/jquery/marked.min | Markdown 解析 |
base64 | plugs/jquery/base64.min | Base64 工具 |
notify | plugs/notify/notify.min | 通知组件 |
angular | plugs/angular/angular.min | Angular |
cropper | plugs/cropper/cropper.min | 图片裁剪 |
echarts | plugs/echarts/echarts.min | ECharts 图表 |
weditor | plugs/editor/create | WangEditor 创建脚本 |
ckeditor4 | plugs/ckeditor4/ckeditor | CKEditor 4 |
ckeditor5 | plugs/ckeditor5/ckeditor | CKEditor 5 |
artplayer | plugs/jquery/artplayer.min | 视频播放器 |
filesaver | plugs/jquery/filesaver.min | 文件保存 |
websocket | plugs/socket/websocket | WebSocket |
compressor | plugs/jquery/compressor.min | 图片压缩 |
sortablejs | plugs/sortable/sortable.min | SortableJS |
_weditor | plugs/editor/index | WangEditor 内部脚本 |
vue.sortable | plugs/sortable/vue.draggable.min | Vue 拖拽组件 |
jquery.ztree | plugs/ztree/ztree.all.min | zTree |
jquery.masonry | plugs/jquery/masonry.min | Masonry |
jquery.cropper | plugs/cropper/cropper.min | jQuery Cropper |
jquery.autocompleter | plugs/jquery/autocompleter.min | 自动补全 |
admin.js 还额外定义了两个别名模块:
define('jquery', [], function () {
return layui.$;
});
define('ckeditor', (function (type) {
if (type === 'wangEditor') return ['weditor'];
if (/^ckeditor[45]$/.test(type)) return [type];
return [Object.fromEntries ? 'ckeditor5' : 'ckeditor4'];
})(window.taEditor || 'ckeditor4'), function (ckeditor) {
return ckeditor;
});因此业务页面通常加载 ckeditor,不要直接假设它一定等于 CKEditor 4 或 CKEditor 5。
⚙️ Shim 依赖
当前内置 shim 规则包括:
jszip依赖filesaver。excel会额外加载plugs/layui_exts/excel.js。notify会加载plugs/notify/theme.css。cropper会加载plugs/cropper/cropper.min.css。_weditor会加载plugs/editor/css/style.css。websocket会加载plugs/socket/swfobject.js。ckeditor5依赖jquery、upload和plugs/ckeditor5/ckeditor.css。vue.sortable依赖vue和sortablejs。jquery.ztree依赖jquery和plugs/ztree/zTreeStyle/zTreeStyle.css。jquery.autocompleter依赖jquery和plugs/jquery/autocompleter.css。
CSS 通过 css! 插件加载,映射为 baseRoot + 'plugs/require/css.js'。
🔧 使用方法
加载内置模块
require(['md5', 'echarts'], function (md5, echarts) {
var value = md5.hash('test');
var chart = echarts.init(document.getElementById('chart'));
});加载编辑器别名
require(['ckeditor'], function (editor) {
// 实际返回值由 base.editor / window.taEditor 决定
console.log(editor);
});加载外部地址
require(['https://cdn.example.com/path/to/module.js'], function (module) {
console.log(module);
});外部地址需要自身兼容 AMD,或通过 shim 显式声明导出的全局对象和依赖。
🧩 扩展配置
自定义前端扩展推荐写在 public/static/extra/script.js。该文件在 admin.js 后加载,可以追加 RequireJS 配置;静态资源插件初始化后,正常 Composer 更新不会覆盖项目中的这个文件。
$(function () {
window.$body = $('body');
require.config({
paths: {
'my-chart': ['extra/my-chart']
},
shim: {
'my-chart': {
deps: ['echarts']
}
}
});
require(['my-chart'], function (chart) {
chart.init();
});
});追加配置时不要重复覆盖已有模块名,例如 vue、upload、ckeditor、notify 等;如果确实需要替换,应先确认现有页面是否依赖原模块。
⚠️ 注意事项
- 后台页面是局部刷新为主的单页式交互,插件对象需要在页面切换或重复初始化前自行销毁。
- 异步加载内容初始化后会触发
reInit,需要处理动态内容时可以监听$body.on('reInit', ...)。 - 二次初始化风险较高的组件,建议在 DOM 上保存实例并先判断旧实例是否存在。
- 非 AMD 脚本可以直接用
<script>引入,但更推荐通过require.config()配置路径与依赖,避免加载顺序失控。 upload模块实际来自后台接口api.upload/index?,不是 public 目录中的静态脚本文件。
