静态前端

基础介绍

本框架的前端部分(此处为后台界面)涉及到的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就可以满足了,如果你的需求比较复杂,并且需要调用第三方组件,比如树形组件、动态渲染,

最后更新时间:2023-08-07 16:55:059110
https://doc.swiftadmin.net/help/8.html