## 基础介绍 本框架的前端部分(此处为后台界面)涉及到的JavaScript、jQuery、layui、CSS、TP模板语法 其中admin.js 文件主要用于整个后台界面的管理,以及一些常规的页面交互、文件上传、消息发送、CURD等操作 在使用后台进行扩展模块或者功能的时候,当前封装的大部分属性都已经足够使用,如果你需要扩展第三方,请熟悉layui前端框架的调用方式 ## 目录结构 ``` static ├─ css ├─ font ├─ images ├─ js │ ├─ common.js │ └─ QRCode.js ├─ system # 后端静态文件 │ ├─ css │ ├─ images │ ├─ js │ ├─ layui │ └─ module │ ├─ admin.js # 重要文件 后台全局依赖此文件进行常规操作 │ ├─ CircleProgress.js │ ├─ content.js │ ├─ mousewheel.js │ ├─ plugin.js │ └─ QRCode.js ``` `system` 文件夹是后台管理的一些静态文件,包括layui常用的一些第三方组件 在这个文件夹之上的,都是访客前端需要用到的静态文件,也就是Index应用的前端静态文件, 在开发插件应用的时候,如果前端需要用到一些固定的组件,可以按照目录的结构去调用,默认会复制在这里! ## 表单交互 得益于admin,js对大部分应用场景的封装以及swiftadmin独特的设计,使得在表单投递的编码中变得异常的简单, 首先在每个模板里面都包含当前的控制器,这点在基类控制器代码中可以体现、 **需要注意的是,我们的大部分表单交互操作, `添加和编辑都是采用的同一个模板` -> 请注意这句话** **需要注意的是,我们的大部分表单交互操作, `添加和编辑都是采用的同一个模板` -> 请注意这句话** **需要注意的是,我们的大部分表单交互操作, `添加和编辑都是采用的同一个模板` -> 请注意这句话** ``` // 分配前端变量 # 也就是将控制器接口分配给模板 View::assign([ 'app' => request()->root(), 'controller' => $this->controller, 'action' => $this->action, 'AdminLogin' => $this->admin ]); ``` 那么这样的话,每一个页面,例如当你访问/system/admin/edit控制器的时候,这时候展现的页面已经记录下来你要访问的是哪一个方法。 并且SwiftAdmin的设计是根据TP自身的模板特点,我们采用GET/POST访问同函数的方式,GET调用一般为展示界面,Ajax交互【注意本框架的Ajax操作全部采用POST传递】 POST我们当做是ADD EDIT的操作,那么这样的话,在调用iframe层面,比如添加某个数据的时候,是不需要填写任何额外的代码的,我们可以看下列的HTML模板代码; ### iframe方式 ``` <include file="/public/header" /> // 加载头部 也就是加载JS CSS <div class="layui-fluid" > <form class="layui-form layui-form-fixed" > <div class="layui-card-body" > <gt name="$data.id" value="0"><input type="text" name="id" value="{$data.id}" hidden=""></gt> <div class="layui-form-item"> <label class="layui-form-label">应用名称</label> <div class="layui-input-block"> <input type="text" name="title" autocomplete="off" value="{$data.title}" class="layui-input" lay-verify="required"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">应用LOGO</label> <div class="layui-input-inline" style="width: 306px"> <input name="logo" type="text" class="layui-input pic" value="{$data.logo}" lay-verify="required" /> </div> <button type="button" class="layui-btn layui-btn-normal" lay-upload="pic" >{:__('上传图片')}</button> </div> <div class="layui-form-item"> <label class="layui-form-label">应用ID</label> <div class="layui-input-block"> <input type="text" name="app_id" value="{$data.app_id}" class="layui-input layui-disabled" lay-verify="required" > </div> </div> <div class="layui-form-item"> <label class="layui-form-label">应用KEY</label> <div class="layui-input-block"> <input type="text" name="app_key" value="{$data.app_key}" class="layui-input layui-disabled" lay-verify="required" > </div> </div> <div class="layui-form-item"> <label class="layui-form-label">应用描述</label> <div class="layui-input-block"> <textarea name="content" id="content" cols="30" rows="10" style="min-height: 110px;" class="layui-textarea" lay-verify="required" >{$data.content}</textarea> </div> </div> </div> <div class="layui-footer" style="text-align: center;"> <button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog" >取消</button> <!-- 我们要重点看提交这里,表单交互只需要简单的增加 lay-filter="submitIframe" 属性即可一键提交 --> <button class="layui-btn layui-btn-normal" lay-filter="submitIframe" type="button" lay-submit>提交</button> </div> </form> </div> <include file="/public/footer" /> ``` ### 页面层方式 ``` <script type="text/html" id="editforms" > <div class="layui-fluid layui-bg-white" > <form class="layui-form layui-form-fixed" lay-filter="editforms" > <input type="text" name="id" hidden=""> <div class="layui-form-item"> <label class="layui-form-label"><font color="red">* </font>{:__('广告名称')}</label> <div class="layui-input-block"> <input name="title" placeholder="{:__('请输入广告名称')}" type="text" class="layui-input" lay-verify="required" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label"><font color="red">* </font>{:__('广告标识')}</label> <div class="layui-input-block"> <input name="alias" placeholder="{:__('请输入非中文广告标识')}" type="text" class="layui-input" lay-verify="required" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">{:__('广告封面')}</label> <div class="layui-input-inline" style="width: 322px"> <input name="pic" placeholder="{:__('广告封面')}" type="text" class="layui-input pic" /> </div> <button type="button" class="layui-btn layui-btn-normal" lay-upload="pic" >{:__('上传图片')}</button> </div> <div class="layui-form-item"> <label class="layui-form-label">{:__('到期时间')}</label> <div class="layui-input-block"> <input name="expirestime" placeholder="{:__('到期时间')}" type="text" class="layui-input" lay-datetime lay-verify="required" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">{:__('到期提醒')}</label> <div class="layui-input-inline"> <input name="remind" type="radio" value="1" title="{:__('开启')}" checked /> <input name="remind" type="radio" value="0" title="{:__('关闭')}" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label"><font color="red">* </font>{:__('广告代码')}</label> <div class="layui-input-block"> <textarea name="content" id="content" style="min-height: 110px;" placeholder="{:__('请输入广告代码')}" class="layui-textarea" lay-verify="required" ></textarea> </div> </div> <div class="layui-footer layui-form-item layui-center" > <button class="layui-btn layui-btn-primary" type="button" sa-event="closePageDialog" >{:__('取消')}</button> <!-- 请注意 lay-add lay-edit 的方式调用,并且HTML ELEMENT的过滤属性为 lay-filter="submitPage" --> <button class="layui-btn" lay-add="{:url('/system/adwords/add')}" lay-edit="{:url('/system/adwords/edit')}" lay-filter="submitPage" lay-submit>{:__('提交')}</button> </div> </form> </div> </script> ``` ## 表格交互 数据表格,在一般应用场景下,我们需要对表格进行增删改查、对数据进行搜索、排序等操作, 我们先来看一段调用layui table的代码 ``` <script> layui.use(['table','admin'], function () { var admin = layui.admin; var table = layui.table; /* * 初始化表格 */ var isTable = table.render({ elem: "#lay-tableList" ,url: "{:url('/system/adwords/index')}" ,cols: [[ {type: 'checkbox', width:45}, {field: 'id', align: 'center',sort: true,width: 80, title: 'ID'}, {field: 'title', align: 'left', title: '{:__("广告名称")}'}, {field: 'alias', align: 'left', width:180, title: '{:__("广告标识")}'}, {field: 'status', align: 'center',templet: '#columnStatus', width: 135, title: '{:__("状态")}'}, {field: 'expirestime', align: 'center',width:180, title: '{:__("到期时间")}'}, {field: 'createtime', align: 'center', width:180, title: '{:__("创建时间")}'}, {align: 'center', toolbar: '#tableBar', width:190, title: '{:__("操作")}'}, ]] }) }) </script> ``` 其实在软件工程当中,代码复用是一个很好的方式,你的数据表格,表单交互在任何时候处理的事务,其实就是当前用户跟服务器的交互, 进行数据的传递、返回而已,那么我们只需要把这部分的代码封装了,然后提供一些属性进行调用就可以了,在VUE之前,我们习惯性的在每一个页面里面去编写JS代码 其实这部分的JS代码会导致重复率很高,代码冗余不易维护。那么当前使用swiftadmin框架的时候,我们只需要这样调用就可以了,是不是很方便,当你使用表格搜索的时候 会自动触发下列代码。 ``` // 监听form表单搜索 form.on('submit(formSearch)', function (data) { var field = data.field; for (const key in field) { if (!field[key]) { delete field[key]; } } table.reload('lay-tableList', { page: {curr: 1}, where: field }); }) // 监听表格事件 table.on("tool(lay-tableList)", function (obj) { var data = obj.data , reqData = {} , selector = $(this).parents('table').find('tbody tr') , callback = { success: function (res) { obj.del(); // 删除tr元素 if ((selector.length - 1) == 0 || typeof selector.length === 'undefined') { table.reload("lay-tableList"); } layer.msg(res.msg); }, error: function (res) { layer.error(res.msg); } } , othis = $(this) , title = othis.data("title") || undefined // 拼接字段数据 , field = $(this).data('field'); if (typeof (field) === "undefined") { reqData = { id: data.id } } else { var array = field.split(","); for (let d in array) { reqData[d] = data[d]; } } // 表格编辑状态 if (obj.event === "edit") { admin.event.open(othis, obj); } else if (obj.event === "del") { var tips = i18n.prop('确定要删除吗'); if (typeof title !== "undefined") { tips += ' ' + title + ' '; } // tips += '?'; layer.confirm(tips, function (index) { admin.event.request(othis, reqData, callback); layer.close(index); }) } // 如果event为ajax,则发送请求 else if (obj.event === "ajax") { admin.event.request(othis, reqData, callback); } else { // 打开窗口 admin.event.open(othis, obj); } }) ``` ## 消息提示 我们封装了show.js插件,这个消息提示插件底层为iziToast。 由于他并没有比较建议的使用方法,所以我们在他之上又进行了一次封装, ``` // 在这里的notice就是iziToast组件 layui.define(['notice'], function (exports) { "use strict"; let MODULE_SHOW_NAME = {}; let notice = layui.notice, MOD_NAME = 'show'; // 正常消息通知 MODULE_SHOW_NAME.msg = function (msg) { notice.success({ message: msg, }); } // 错误消息通知 MODULE_SHOW_NAME.error = function (msg) { notice.error({ message: msg, }); } // 警告消息通知 MODULE_SHOW_NAME.warning = function (msg) { notice.warning({ message: msg, }); } // 信息消息通知 MODULE_SHOW_NAME.info = function (msg) { notice.info({ message: msg, }); } // 消息通知 MODULE_SHOW_NAME.notice = function (title, msg, options = {}) { notice.show({ title: title, message: msg, ...options }); } exports(MOD_NAME, MODULE_SHOW_NAME); }) ``` 你可以直接使用show.msg、show.error...等进行自定义消息的提示,具体可参考iziToast组件文档 ## 常规建议 至此,一个简单的前端表单以及数据表格的交互就阐述完毕了,是不是很简单!我们的建议是:当你的业务需求很小,表单的值不需要第三方组件去渲染的情况下, 我们强烈建议您使用页面层去进行交互,这样的好处就是用户的体验度会非常好,并且利用layui本身form表单自动填充的方法,可以省去编辑表单的额外工作; 并且、这样我们的一个功能的模板,仅仅只需要一个 `index.html` 就可以满足了,如果你的需求比较复杂,并且需要调用第三方组件,比如树形组件、动态渲染, 更新于 2026-08-09 14:48 阅读 8 ← 控制器 权限管理 → 相关问题 前言 安装 架构 多语言 数据库 控制器 权限管理 全局组件