VeiTool LAYUI 前端
单页模式
入口主页
入口主页模板文件位于后台应用视图文件夹下,具体位置:app/admin/view/index/index.php。文件的加载是经过后台主控制器模板解析过后再传递给浏览器端,并非纯静态形式的请求获得模板。这样设计有两个目的:1. 为了服务端能灵活处理模板;2. 为了防止静态模板可直接被下载。
主页结构
单页模式:入口主页第一次请求后,左栏菜单项里的链接(外链除外)点击后并不会再次刷新整体主页,而是会异步请求后通过 index.js、admin.js 两个主框组件中的路由、模板解析等一系列处理,再将处理结果呈现在layui-body容器中,这样一来所有主页引入的(也包括后面异步引入的)静态资源 css、js 文件以及定义的全局变量等,在后面异步加载的内容中也是可用的。
<!DOCTYPE html>
<html>
<head>
...
<link rel="stylesheet" href="{STATIC__PATH}layui/css/layui.css"/>
<link rel="stylesheet" href="{STATIC__PATH}admin/admin.css"/>
...
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header"> 面板页头部 </div>
<div class="layui-side"> 面板左栏主菜单【异步动态加载】</div>
<div class="layui-body"> 主体内容 【异步动态加载】</div>
<div class="layui-footer layui-text"></div>
</div>
<script type="text/javascript" src="{STATIC__PATH}layui/layui.js"></script>
<script>
// layui 相关配置,并引入 index.js、admin.js 主框组件
</script>
</body>
</html>温馨提示
由于单页模式的这类特性,启用多标签时,一定要注意各异步加载模板页内 id 的命名问题,不要重名。
内页结构
内页的引入是可以分为三种:
内部框架页引入 这种模式是采用iframe框架引入,需要重新全部加载所需静态资源的,页面也是需要整体独有布局的,一般是在某些,如不希望受到主框单页中的js、css影响的特殊页面。
外部链接页引入 这种模式也是采用iframe框架引入的。
普通页异步引入【常用】 系统大部分页面采用和推荐的模式,不需要再重新加载框架的资源文件,只需加载本页需要的静态资源文件:如js\css\图片资源等。一般的布局规范如下:
<style>
<!--这里可以写本页所需的css样式-->
</style>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
//头部
</div>
<div class="layui-card-body">
//主体
</div>
//v-show 中的权限路径用来控制该标签是否显示,当拥有该项权限路径时才显示【v2.0.0版新增】
<div v-show="system.log/index"> 带权限的内容控制 </div>
</div>
</div>
<!--JS部分 这里也可以引入单独的js文件:也就是本页所需的js业务逻辑写在独立的js文件种 -->
<script type="text/javascript">
//这种方式是视图和js业务逻辑集成在一个页面,方便维护开发
layui.use(['modelName'],function(){
//这里是js的业务逻辑($ 符在这里是直接可用的)
});
</script>主框组件
index.js 组件
构建左侧菜单
// res 菜单数据集
// murl 主体页路径 默认 '#/index/main'
index.buildLeftMenus(res,murl)清除tab记忆
index.clearTabCache()设置tab标题
// title 标题
// hash 路径
index.setTabTitle(title, hash)跳转到tab
// hash 路径
index.go(hash)admin.js 组件
转为blob
admin.util.toBlob()获取IP信息
// ip IP地址
admin.util.ip(ip)刷新当前标签
// url tab路径
admin.refresh(url)关闭当前 tab
// url tab路径
admin.closeThisTabs(url)关闭其他 tab
// url tab路径
admin.closeOtherTabs(url)获取 token
admin.getToken()清除 token
admin.removeToken()请求方法
// url 请求地址
// data 请求参数
// success 回调函数
// method 请求方法 get/post
// option 同ajax参数
admin.req(url, data, success, method, option)open方法
// option 同 layer.open(option) 中的参数
admin.open({option})vShow方法
admin.vShow()
// 对标签含 v-show="@index.log/index" 进行权限鉴别,无权限则被移除(含@则变灰色不移除)【v2.0.0+】vForm方法
// obj DOM对象
admin.vForm(obj)
// 弹窗页中存在搜索表单时,可采用该方法进行自由渲染,应添加在弹窗完成后执行渲染【v2.0.1+】vDict方法
// obj DOM对象
admin.vDict(obj)
// 渲染字典数据为下拉结构。弹窗页中存在下拉渲染时,可在弹窗完成后采用此方法【v2.0.1+】getDict方法
// key 字典编号
admin.getDict(key)
// 获取某字典编号下的字典数据集【v2.0.1+】构建组件
buildItems.js 组件
构建用法
// 普通用法
buildItems.build({
bid: 'id',
gid: 1,
data: [
{name:"note",title:"备注说明",type:"text",value:'',placeholder:"备注说明"},
]
});
// 结合 admin 组件
admin.open({
type: 1,
bid: 'form_items', //form_items@pane 标题和表单项竖排列
btn: ['确认', '取消'],
area: ['460px', '350px'],
title: '弹窗标题',
success: function(lay,index){
l.children('.layui-layer-content').css('overflow', 'visible');
layui.buildItems.build({
bid: 'form_items',
data: [
{name:"title",title:"标题",type:"text",value:id,verify:'required',must:true}
]
});
form.on('submit(form_items)',function(data){
var btn = $(this);
if (btn.attr('stop')){return false}else{btn.attr('stop',1)}
admin.req("add",data.field,function(res){
layer.msg(res.msg,{shade:[0.4,'#000'],time:1500},function(){
if(res.code==1){
layer.close(index);
}
btn.removeAttr('stop');
});
},'post');
return false;
});
}
});基础参数
Data参数
综合示例
admin.open({
type: 1,
bid: 'wenzhangSdw_items', // wenzhangSdw_items@pane 标题和内容竖排排版
btn: ['保存', '取消'],
title: '添加文章',
success: function(l,index){
layui.buildItems.build({
bid: 'wenzhangSdw_items',
space: 'layui-col-space10', //设置栅格间隙 layui-col-space(n)
data: [
{name:"itemid",type:"hidden"},
{type:'layui_tab',title:'选项卡一',showTab:true,data:[
{name:"title",title:"文章标题",type:"text",value:'',verify:'required',placeholder:"请输入文章标题",must:true},
{name:"author",title:"文章作者",type:"text",value:'',placeholder:"请输入文章作者,可不填"},
{name:"copyfrom",title:"文章来源",type:"text",value:'',placeholder:"请输入文章来源,可不填"},
{name:"sms_type",title:"发送方式",type:"radio",options:{qiniu:"七牛短信",smsbao:"短信宝"},value:'qiniu',relation:"sm"},
{name:"sms_user",title:"ID/KEY",type:"text",value:'',relation:"sm_qiniu"},
{name:"sms_pass",title:"短信秘钥",type:"text",value:'',relation:"sm_qiniu"},
{name:"smsbao_user",title:"ID/KEY",type:"text",value:'',relation:"sm_smsbao"},
{name:"smsbao_pass",title:"短信宝号",type:"text",value:'',relation:"sm_smsbao"}
]},
{type:'layui_tab',title:'选项卡二',data:[
{name:"fromurl",title:"来源网址",type:"text",value:'',placeholder:"请输入来源网址,可不填"},
{name:"hits",title:"阅读初数",type:"number",value:'0',verify:'required',placeholder:"请输入阅读初数",must:true},
{name:"listorder",title:"排序编号",type:"number",value:'100',verify:'required',placeholder:"请输入排序编号",must:true},
{name:"img",title:"文章图片",type:"images",value:''},
]},
]
});
form.on('submit(wenzhangSdw_items)',function(data){
//提交处理逻辑
return false;
});
},
//第1个按钮的回调
btn1: function(index, layero, that){ ... },
//第2个按钮的回调
btn2: function(index, layero, that){ ... },
});弹窗可以直接解析数据用法:
admin.open({
type: 1,
tpl: true, //开启模板解析,默认为 false
data: {val:'解析后显示的内容'}, //数据对象
title: '弹窗标题',
area: ['300px','300px'],
btn: ['按钮1', '按钮2'],
content:'<div>{{ d.val }}</div>', //模板中含解析标签
success: function(l,index){},
btn1: function(index, layero, that){},
btn2: function(index, layero, that){}
});新增特性
单页顶部常规搜索结构
v2.0.0版新增
// 表单域渲染 实现
// 加了样式类 render 则系统会对该表单域进行 layui.form.render 渲染
<form class="layui-form render">
<div class="layui-form-item">
<div class="layui-inline" style="width:150px;">
<input type="text" name="kw" placeholder="关键词" autocomplete="off" class="layui-input" lay-affix="clear"/>
</div>
<div class="layui-inline" style="width:200px;">
// 时间选择器渲染 实现
// input 中存在属性 date-render 则系统会对其进行日期渲染,渲染参数可以
// date-render="{type:'date',range:true,format:'yyyy/MM/dd'}" 以json字符串形式传入
<input type="text" name="sotime" date-render placeholder="创建时间" class="layui-input" lay-affix="clear"/>
</div>
<div class="layui-inline">
<div class="layui-btn-group">
// 【搜索】实现
// 存在 lay-submit 同时设置了 lay-filter 属性有“search-”前缀,随后为数据表 ID 标识名
<a class="layui-btn" lay-submit lay-filter="search-table">
<i class="layui-icon layui-icon-search"></i> 搜索
</a>
// 【全部】实现
// 存在 lay-submit 同时设置了 lay-filter 属性有“search-”前缀,随后为数据表 ID 标识名
// 第3个为 all 表示该按钮为触发搜索全部,如果搜索时需要追加该表单域中某个元素
// 为条件,那么可以:"search-table-all-key1|key2|key.." 则可以追加多个自定义条件
<a class="layui-btn" lay-submit lay-filter="search-table-all">
<i class="layui-icon layui-icon-light"></i> 全部
</a>
</div>
</div>
</div>
</form>数据字典
本项内容均为 v2.0.1 版本新增功能属性
数据结构
该功能主要是针对于快速实现下拉选项,以及方便选项数据的调用渲染和统一管理而增加。字典数据结构为多维数组,每个字典编码键对应一组字典数据,其结构为:
"KEY_TYPE": [
{
"id": 1,
"name": "字典项名",
"value": "字典项值",
"pid": "上级ID",
"pids": "所有上级ID串,逗号隔开。无则留空"
},
{
"id": 2,
"name": "字典项名2",
"value": "字典项值2",
"pid": "上级ID",
"pids": "所有上级ID串,逗号隔开。无则留空"
},
...
]调用渲染
字典数据在第一次访问框架主页时,和主菜单、用户数据一并加载缓存于本地页面中,在模板页的JS逻辑中可通过方法:admin.getDict('字典编码') 随时获取对应的字典数据。在模板中的调用渲染模式有两种:
SELECT标签形式
<select v-dict="字典编码/数据集" name="veitool"><option value="">请选择</option></select>DIV 标签形式
<div v-dict="字典编码/数据集" class="v-xmselect-tree" id="ID" options="{name:'www'}"></div>其中options属性请参照第三方扩展:xm-Select 该扩展可以轻松实现下拉树,以及单选、多选等功能
// SELECT标签形式
<select v-dict="PAY_TYPE" name="veitool2"><option value="">请选择</option></select>
// DIV 标签形式 必须设置带有 id 属性
<div class="v-xmselect-tree" id="id_name" v-dict="DICT_KEY" options="{name:'land',filterable:true,searchTips:'搜索词'}"></div>
// 数据集模式1初始数据 这类形式不能用于【DIV 标签形式】渲染
<div class="layui-inline" style="width:120px;">
<select v-dict="{key1:'val1',key2:'val2'}" name="veitool"><option value="">请选择</option></select>
</div>
// 数据集模式2初始数据
<div class="layui-inline" style="width:120px;">
<select v-dict="[{name:'val1',value:'id1'},{name:'val2',value:'id2'}]" name="veitool3"><option value="">请选择</option></select>
</div>弹窗渲染
弹窗中如果调用了字典,需要在弹窗业务完成后再单独执行一下字典渲染方法即可:
admin.open({
type: 1,
bid: 'test_items',
btn: ['保存', '取消'],
area: ['600px','600px'],
title: '页面',
shadeClose: false,
success: function(lay,index){
buildItems.build({
bid: 'test_items',
data: [
{name:"pay",title:"支付方式",type:"html",html:'<select v-dict="PAY_TYPE"></select>'},
]
});
admin.vDict(lay); //这里单独执行字典数据渲染
form.val('test_items_form',{pay:'ali'}); //这里的赋值须放在渲染的后面
}
});
评论区