933 lines
20 KiB
Markdown
933 lines
20 KiB
Markdown
# Ciyon PC前端开发指南
|
||
|
||
## 框架概述
|
||
|
||
Ciyon是一个轻量级、高性能的PC前端开发框架,采用原生JavaScript开发,不依赖第三方库(如Vue、React、jQuery),专注于企业级后台管理系统和SaaS应用的快速开发。
|
||
|
||
### 核心特点
|
||
|
||
- **零依赖**: 纯原生JavaScript,无第三方库依赖
|
||
- **组件化**: 提供丰富的表单组件和业务组件
|
||
- **高性能**: 优化的DOM操作和事件处理
|
||
- **响应式**: 支持多端适配(PC、平板、手机)
|
||
- **国际化**: 内置多语言支持
|
||
- **主题系统**: CSS变量实现主题切换
|
||
|
||
---
|
||
|
||
## 框架架构
|
||
|
||
### 核心库文件
|
||
|
||
```
|
||
web/jscss/
|
||
├── ciy.js # 基础工具库和DOM操作
|
||
├── ciycmp.js # 表单组件库
|
||
├── ciycmp2.js # 扩展组件库
|
||
├── ciytable.js # 表格和列表组件
|
||
├── ciybigscreen.js # 数据大屏组件
|
||
├── ciy_websocket.js # WebSocket通信
|
||
├── style.css # 核心样式
|
||
└── theme.js # 暗黑模式
|
||
```
|
||
|
||
### 设计模式
|
||
|
||
#### DOM封装模式
|
||
|
||
框架使用 `$5()` 函数替代jQuery,提供统一的DOM操作接口:
|
||
|
||
```javascript
|
||
// 选择元素
|
||
var dom = $5('.class-name');
|
||
|
||
// 链式调用
|
||
dom.css({color: 'red'}).addClass('active').show();
|
||
|
||
// 事件绑定
|
||
dom.on('click', function(e) {
|
||
console.log('clicked');
|
||
});
|
||
```
|
||
|
||
#### 组件化模式
|
||
|
||
使用自定义标签和 `ciycmp()` 函数初始化组件:
|
||
|
||
```html
|
||
<ciy-datetime com="starttime" value="2026-01-01"></ciy-datetime>
|
||
|
||
<script>
|
||
ciycmp({
|
||
dom: '[com=starttime]',
|
||
type: 'datetime',
|
||
onchange: function(e) {
|
||
console.log('selected:', e.value);
|
||
}
|
||
});
|
||
</script>
|
||
```
|
||
|
||
#### 面向对象模式
|
||
|
||
使用类封装复杂功能:
|
||
|
||
```javascript
|
||
var table = new ciyclass.table({
|
||
dom: '.table',
|
||
url: 'api/list',
|
||
pagecount: 20,
|
||
fn_done: function(json) {
|
||
console.log('data loaded');
|
||
}
|
||
});
|
||
table.callpage(1);
|
||
```
|
||
|
||
---
|
||
|
||
## 组件体系
|
||
|
||
### 表单组件
|
||
|
||
#### 日期时间选择器(ciy-datetime)
|
||
|
||
```html
|
||
<ciy-datetime com="date1" type="date" value="2026-01-01"></ciy-datetime>
|
||
<ciy-datetime com="datetime1" type="datetime" value="2026-01-01 12:00"></ciy-datetime>
|
||
<ciy-datetime com="month1" type="month" value="2026-01"></ciy-datetime>
|
||
```
|
||
|
||
**属性说明**:
|
||
- `com`: 组件名称(必填)
|
||
- `type`: 类型(date/datetime/month)
|
||
- `value`: 初始值(时间戳或日期字符串)
|
||
- `mindate`: 最小日期
|
||
- `maxdate`: 最大日期
|
||
- `placeholder`: 占位文本
|
||
|
||
#### 日期范围选择器(ciy-daterange)
|
||
|
||
```html
|
||
<ciy-daterange com="daterange1" type="date" value="2026-01-01~2026-12-31"></ciy-daterange>
|
||
```
|
||
|
||
**输出格式**:`开始日期~结束日期`
|
||
|
||
#### 下拉选择框(ciy-select)
|
||
|
||
```html
|
||
<ciy-select com="status1" range="auditstatus" all="全部"></ciy-select>
|
||
|
||
<script>
|
||
ciycmp({
|
||
dom: '[com=status1]',
|
||
range: 'auditstatus', // 字典key
|
||
all: '全部', // 第一项
|
||
filter: {field: 'upid', value: 0}, // 过滤条件
|
||
onchange: function(e) {
|
||
console.log('selected:', e.value);
|
||
}
|
||
});
|
||
</script>
|
||
```
|
||
|
||
#### 多选下拉框(ciy-selmulti)
|
||
|
||
```html
|
||
<ciy-selmulti com="tags1" range="tags"></ciy-selmulti>
|
||
```
|
||
|
||
**输出格式**:`,id1,id2,id3,`
|
||
|
||
#### 级联选择框(ciy-selcas)
|
||
|
||
```html
|
||
<ciy-selcas com="region1" range="region"></ciy-selcas>
|
||
```
|
||
|
||
用于省市区级联选择。
|
||
|
||
#### 开关(ciy-switch)
|
||
|
||
```html
|
||
<ciy-switch com="enable1" value="1"></ciy-switch>
|
||
```
|
||
|
||
**输出值**:`1`(开启)/ `2`(关闭)
|
||
|
||
#### 单位编辑器(ciy-inputunitedit)
|
||
|
||
```html
|
||
<ciy-inputunitedit com="unit1" value="瓶|24|盒|20|箱"></ciy-inputunitedit>
|
||
```
|
||
|
||
用于三级单位换算,如:1箱=20盒,1盒=24瓶。
|
||
|
||
#### 地图选择器(ciy-map)
|
||
|
||
```html
|
||
<ciy-map com="location1" value="116.404,39.915"></ciy-map>
|
||
```
|
||
|
||
输出经纬度:`lng,lat`
|
||
|
||
#### 文本编辑器(ciy-textarea)
|
||
|
||
```html
|
||
<ciy-textarea com="content1" max="1000"></ciy-textarea>
|
||
```
|
||
|
||
支持Tab键、字数统计、@用户提示。
|
||
|
||
#### 文件上传(ciy-upload)
|
||
|
||
```html
|
||
<ciy-upload com="file1" type="jpg,png" maxcount="1"></ciy-upload>
|
||
```
|
||
|
||
**属性说明**:
|
||
- `type`: 允许的文件类型
|
||
- `maxcount`: 最大上传数量
|
||
- `maxkb`: 文件大小限制(KB)
|
||
|
||
### 列表组件
|
||
|
||
#### 表格组件(ciyclass.table)
|
||
|
||
```html
|
||
<div class="table">
|
||
<div class="list">
|
||
<!-- 表格内容自动生成 -->
|
||
</div>
|
||
<div>
|
||
<div class="btmbtn"></div>
|
||
<div>
|
||
<div class="btmbtn"></div>
|
||
<div class="page"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
var table = new ciyclass.table({
|
||
dom: '.table',
|
||
url: 'list',
|
||
pagecount: 20,
|
||
fn_tdcontent: function(key, value, field, row, json) {
|
||
// 自定义单元格内容
|
||
if (key == 'status') {
|
||
return '<span class="tag">' + value + '</span>';
|
||
}
|
||
// 自定义操作按钮
|
||
if (key == '_btn') {
|
||
var html = '';
|
||
html += `<a class="btn def" onclick="menubtn(this, 'view')">查看</a>`;
|
||
// 根据需求添加或删除按钮
|
||
// html += `<a class="btn" onclick="menubtn(this, 'edit')">修改</a>`;
|
||
return html;
|
||
}
|
||
return value;
|
||
},
|
||
fn_done: function(json, post) {
|
||
// 数据加载完成回调
|
||
}
|
||
});
|
||
table.callpage(1);
|
||
</script>
|
||
```
|
||
|
||
**功能特性**:
|
||
- 动态列配置
|
||
- 列宽调整记忆
|
||
- 列排序
|
||
- 列隐藏
|
||
- 行选择
|
||
- 分页
|
||
- 搜索
|
||
- 顶部选项卡筛选
|
||
|
||
**顶部选项卡筛选**:使用 `fillsearch` 的 `lidata` 参数添加顶部选项卡,`liall` 设置"全部"选项的文本:
|
||
|
||
```javascript
|
||
table = new ciyclass.table({
|
||
dom: '.table',
|
||
url: 'list',
|
||
pagecount: 20,
|
||
fn_beforedata: function(json) {
|
||
ciyfn.fillsearch({
|
||
searchdom: '.search',
|
||
data: json,
|
||
liall: '全部',
|
||
lidata: [
|
||
{id: 1, name: '未使用'},
|
||
{id: 2, name: '已使用'}
|
||
],
|
||
//lidata: '【字典代码】', // 引用字典写法
|
||
//lidata: ':全部.1:未使用.2:已使用', //数组简写
|
||
liclick: function(dom) {
|
||
table.search(dom, 'li');
|
||
}
|
||
});
|
||
return json;
|
||
}
|
||
});
|
||
```
|
||
|
||
**liid编号**:自定义标识值应从1开始,不要使用0。
|
||
|
||
**后端处理**:在 `setwhere` 函数中根据 `liid` 参数进行筛选。
|
||
|
||
#### 卡片列表(ciyclass.cardtable)
|
||
|
||
```html
|
||
<div class="table">
|
||
<ul class="list row">
|
||
<!-- 卡片内容自动生成 -->
|
||
</ul>
|
||
<div>
|
||
<div class="btmbtn"></div>
|
||
<div class="page"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
var table = new ciyclass.cardtable({
|
||
dom: '.table',
|
||
url: 'api/list',
|
||
pagecount: 9,
|
||
fn_lihtml: function(ldat) {
|
||
return `<li data-id="${ldat.id}">
|
||
<div class="ciy-list">
|
||
<div class="l1">${ldat.name}</div>
|
||
<div class="l2">${ldat.memo}</div>
|
||
</div>
|
||
</li>`;
|
||
}
|
||
});
|
||
table.callpage(1);
|
||
</script>
|
||
```
|
||
|
||
### 功能组件
|
||
|
||
#### 弹窗(ciyfn.alert)
|
||
|
||
```javascript
|
||
ciyfn.alert({
|
||
title: '提示',
|
||
content: '操作成功',
|
||
btn: ['确定', '取消'],
|
||
cb: function(opn) {
|
||
if (opn.btn == '确定') {
|
||
// 确定操作
|
||
}
|
||
}
|
||
});
|
||
```
|
||
|
||
#### Toast提示(ciyfn.toast)
|
||
|
||
```javascript
|
||
ciyfn.toast('操作成功');
|
||
ciyfn.toast('操作失败', 'error');
|
||
```
|
||
|
||
#### 选项卡(ciyfn.tabcard)
|
||
|
||
```html
|
||
<div class="ciy-tabcard">
|
||
<div class="tabs">
|
||
<div class="tab active">标签1</div>
|
||
<div class="tab">标签2</div>
|
||
</div>
|
||
<div class="contents">
|
||
<div class="content active">内容1</div>
|
||
<div class="content">内容2</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## 开发规范
|
||
|
||
### HTML结构规范
|
||
|
||
#### 标准页面结构
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<link href="/jscss/style.css" rel="stylesheet">
|
||
<script src="/jscss/theme.js"></script>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<!-- 搜索表单 -->
|
||
<form class="search" onsubmit="table.search(this,'btn');return false;">
|
||
<div>
|
||
<div class="sinps">
|
||
<div class="ciy-form">
|
||
<label>状态</label>
|
||
<div><ciy-select com="status" range="status"></ciy-select></div>
|
||
</div>
|
||
</div>
|
||
<div class="sbtns">
|
||
<button class="btn" type="submit">查询</button>
|
||
<a class="btn" onclick="edit(0)">添加</a>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
|
||
<!-- 列表区域 -->
|
||
<div class="table">
|
||
<div class="list"></div>
|
||
<div>
|
||
<div class="btmbtn"></div>
|
||
<div class="page"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="/jscss/ciy.js"></script>
|
||
<script src="/jscss/ciycmp.js"></script>
|
||
<script src="/jscss/ciycmp2.js"></script>
|
||
<script src="/jscss/ciytable.js"></script>
|
||
<script src="./common.js"></script>
|
||
<script>
|
||
// 页面逻辑
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
#### 表单结构
|
||
|
||
```html
|
||
<div class="ciy-form">
|
||
<label>字段名称</label>
|
||
<div>
|
||
<ciy-select com="field" range="dict"></ciy-select>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### JavaScript编码规范
|
||
|
||
#### 页面初始化
|
||
|
||
```javascript
|
||
'use strict';
|
||
|
||
var table;
|
||
ciyfn.pageload(function() {
|
||
// 初始化组件
|
||
ciycmp({
|
||
dom: '[com=status]',
|
||
range: 'status',
|
||
all: '全部'
|
||
});
|
||
|
||
// 初始化表格
|
||
table = new ciyclass.table({
|
||
dom: '.table',
|
||
url: 'api/list',
|
||
pagecount: 20
|
||
});
|
||
table.callpage(1);
|
||
});
|
||
```
|
||
|
||
#### 组件初始化
|
||
|
||
```javascript
|
||
// 标准初始化
|
||
ciycmp({
|
||
dom: '[com=component]',
|
||
range: 'dictionary',
|
||
value: '1',
|
||
onchange: function(e) {
|
||
console.log('changed:', e.value);
|
||
}
|
||
});
|
||
```
|
||
|
||
#### 事件处理
|
||
|
||
```javascript
|
||
// 使用$5绑定事件
|
||
$5('.btn-save').on('click', function(e) {
|
||
e.preventDefault();
|
||
// 保存逻辑
|
||
});
|
||
|
||
// 使用原生addEventListener
|
||
document.querySelector('.btn-save').addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
// 保存逻辑
|
||
});
|
||
```
|
||
|
||
#### API调用
|
||
|
||
```javascript
|
||
ciyfn.callfunc('api/admin.update', {
|
||
id: 1,
|
||
name: 'test'
|
||
}, function(json) {
|
||
//返回code:1,成功回调
|
||
});
|
||
```
|
||
|
||
#### 表单获取
|
||
|
||
```javascript
|
||
var form = ciyfn.getform('.search');
|
||
console.log(form);
|
||
```
|
||
|
||
### 样式规范
|
||
|
||
#### CSS变量
|
||
|
||
```css
|
||
:root {
|
||
/* 主色 */
|
||
--man3: #d7eeff;
|
||
--man4: #80c1f3;
|
||
--man5: #1E9FFF;
|
||
--man6: #1e89db;
|
||
--man7: #8568f7;
|
||
--mant: #ffffff;
|
||
|
||
/* 成功色 */
|
||
--succ5: #03a547;
|
||
--succ6: #048238;
|
||
--succt: #ffffff;
|
||
|
||
/* 警示色 */
|
||
--warn5: #e39725;
|
||
--warn6: #b97a1c;
|
||
--warnt: #ffffff;
|
||
|
||
/* 失败色 */
|
||
--dag5: #e34242;
|
||
--dag6: #bd2525;
|
||
--dagt: #ffffff;
|
||
|
||
/* 文字色 */
|
||
--txt1: #8c9ba4;
|
||
--txt2: #818e97;
|
||
--txt3: #738088;
|
||
--txt4: #646e76;
|
||
--txt5: #576067;
|
||
--txt6: #454d52;
|
||
--txt7: #2c3236;
|
||
--txt8: #060708;
|
||
--txt9: #000000;
|
||
|
||
/* 背景色 */
|
||
--bg1: #ffffff;
|
||
--bg2: #fbfbfc;
|
||
--bg3: #f7f8f8;
|
||
--bg4: #f0f2f2;
|
||
--bg5: #e3e6e7;
|
||
--bg6: #cdd2d4;
|
||
--bg7: #afb6b9;
|
||
--bg8: #939da1;
|
||
--bg9: #7e8a8e;
|
||
|
||
|
||
/* 其他css变量 */
|
||
--e-scroll: rgba(0, 0, 0, 0.2);
|
||
--e-tabselect: #fffec5;
|
||
--e-dialog: 2px 2px 20px -10px #000000;
|
||
--e-inputbg: #f7f7f7;
|
||
--e-inputbr: #ffffff;
|
||
--e-switchtxt: #2c3236;
|
||
--e-inputshadow: 0 1px 3px 0 #00000042;
|
||
--e-menusec: 0.5s;
|
||
}
|
||
```
|
||
|
||
#### 响应式断点
|
||
|
||
```css
|
||
@media (max-width: 767px) { /* 手机 */ }
|
||
@media (max-width: 991px) { /* 平板 */ }
|
||
@media (min-width: 576px) { /* 平板及以上 */ }
|
||
@media (min-width: 992px) { /* PC */ }
|
||
```
|
||
|
||
---
|
||
|
||
## 后端交互
|
||
|
||
### API调用规范
|
||
|
||
#### 标准请求格式
|
||
|
||
```javascript
|
||
ciyfn.callfunc('/admin/user.update', {
|
||
param1: 'value1',
|
||
param2: 'value2'
|
||
}, function(json) {
|
||
// 处理响应
|
||
});
|
||
```
|
||
|
||
#### 标准响应格式
|
||
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "成功",
|
||
"data": {},
|
||
"list": [],
|
||
"count": 100,
|
||
"pageno": 1,
|
||
"once": {}
|
||
}
|
||
```
|
||
|
||
### 认证机制
|
||
|
||
框架使用JWT进行用户认证,Token存储在Cookie或LocalStorage中。
|
||
```
|
||
// 获取
|
||
var me = ciyfn.getstorage(ciy_vars.tokenfield);
|
||
```
|
||
|
||
### 权限控制
|
||
|
||
```
|
||
// 检查权限
|
||
if (ciyfn.nopower(me.power, 'p1v')) {
|
||
ciyfn.alert('未被授权');
|
||
}
|
||
```
|
||
|
||
权限格式:`.p1v.p2v.p3v.`(p=父权限,v=查看)
|
||
|
||
---
|
||
|
||
## 最佳实践
|
||
|
||
### 组件命名
|
||
|
||
- 使用 `com` 属性标识组件name
|
||
- 组件名采用下划线命名法
|
||
- 表单字段使用有意义的名称
|
||
|
||
```html
|
||
<ciy-select com="user_status" range="userstatus"></ciy-select>
|
||
<ciy-datetime com="start_time" type="datetime"></ciy-datetime>
|
||
```
|
||
|
||
### 数据字典
|
||
|
||
字典数据通过 `range` 属性引用:
|
||
|
||
```javascript
|
||
// 字典结构
|
||
[{
|
||
id: 1,
|
||
name: '状态1',
|
||
upid: 0
|
||
}]
|
||
|
||
// 使用
|
||
ciycmp({
|
||
dom: '[com=status]',
|
||
range: 'userstatus' // 从localstorage缓存读取
|
||
});
|
||
```
|
||
|
||
### 事件处理
|
||
|
||
- 使用 `onchange` 处理组件值变化
|
||
- 事件回调接收统一的参数对象
|
||
|
||
```javascript
|
||
ciycmp({
|
||
dom: '[com=status]',
|
||
onchange: function(e) {
|
||
console.log(e.name); // 组件名称
|
||
console.log(e.value); // 组件值
|
||
console.log(e.dom); // DOM元素
|
||
console.log(e.from); // 触发来源
|
||
}
|
||
});
|
||
```
|
||
|
||
### 国际化
|
||
|
||
使用 `ciyfn.lang()` 函数实现多语言:
|
||
|
||
```javascript
|
||
console.log(ciyfn.lang('保存'));
|
||
console.log(ciyfn.lang('删除'));
|
||
```
|
||
|
||
### 性能优化
|
||
|
||
- 使用 `ciyfn.throttle()` 防抖
|
||
- 使用 `ciyfn.lazyimg()` 懒加载图片
|
||
- 列表分页加载
|
||
- 图片URL转换:使用 `ciyfn.file_stor()` 将数据库存储路径转换为云存储绝对URL
|
||
- 图片查看:使用 `ciyfn.showimg(index, imagesString)` 查看多张图片,参数为起始索引和用`~`连接的图片路径字符串
|
||
|
||
```javascript
|
||
// 图片URL转换
|
||
var imgurl = ciyfn.file_stor('/2024/03/14/image.jpg');
|
||
|
||
// 查看多张图片,用~分隔(数据库中的原始存储)
|
||
ciyfn.showimg(1, '/img/1.jpg~/img/2.jpg~/img/3.jpg'); // 从第2张开始查看
|
||
```
|
||
|
||
```javascript
|
||
// 防抖示例
|
||
$5('.search-input').on('input', function() {
|
||
if (ciyfn.throttle(this)) return;
|
||
// 搜索逻辑
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 开发流程
|
||
|
||
### 新建页面
|
||
|
||
1. 在 `web/xxx/` 下创建同名HTML文件和后端文件
|
||
2. 引入必要的JS和CSS文件
|
||
3. 使用组件标签构建页面
|
||
4. 编写初始化逻辑
|
||
5. 实现交互功能
|
||
6. 测试和优化
|
||
|
||
### 示例代码
|
||
|
||
#### 列表页面示例
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<link href="/jscss/style.css" rel="stylesheet">
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<form class="search" onsubmit="table.search(this,'btn');return false;">
|
||
<div>
|
||
<div class="sinps">
|
||
<div class="ciy-form">
|
||
<label>状态</label>
|
||
<div><ciy-select com="status" range="status" all="全部"></ciy-select></div>
|
||
</div>
|
||
</div>
|
||
<div class="sbtns">
|
||
<button class="btn" type="submit">查询</button>
|
||
<a class="btn" onclick="edit(0)">添加</a>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
|
||
<div class="table">
|
||
<div class="list"></div>
|
||
<div>
|
||
<div class="btmbtn"></div>
|
||
<div class="page"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="/jscss/ciy.js"></script>
|
||
<script src="/jscss/ciycmp.js"></script>
|
||
<script src="/jscss/ciycmp2.js"></script>
|
||
<script src="/jscss/ciytable.js"></script>
|
||
<script src="./common.js"></script>
|
||
<script>
|
||
'use strict';
|
||
var table;
|
||
ciyfn.pageload(function() {
|
||
ciycmp({ dom: '[com=status]', range: 'status', all: '全部' });
|
||
|
||
table = new ciyclass.table({
|
||
dom: '.table',
|
||
url: 'list', //JS引擎将自动拼接为当前目录/文件名.list /admin/demopage.list
|
||
pagecount: 20,
|
||
fn_beforedata: function(json) {
|
||
ciyfn.fillsearch({ dom: '.search', data: json });
|
||
return json;
|
||
}
|
||
});
|
||
table.callpage(1);
|
||
});
|
||
|
||
function edit(id) {
|
||
ciyfn.alert({
|
||
title: id == 0 ? '添加' : '修改',
|
||
width: '600px',
|
||
frame: 'edit.html?id=' + id,
|
||
cb: function(opn) {
|
||
opn.close();
|
||
table.updateline(opn.inputs);
|
||
}
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
#### 表单页面示例
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<link href="/jscss/style.css" rel="stylesheet">
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<form onsubmit="save(event);">
|
||
<div class="ciy-form">
|
||
<label>名称</label>
|
||
<div><input type="text" name="name" required></div>
|
||
</div>
|
||
<div class="ciy-form">
|
||
<label>状态</label>
|
||
<div><ciy-switch com="status" value="1"></ciy-switch></div>
|
||
</div>
|
||
<div class="ciy-form">
|
||
<label>时间</label>
|
||
<div><ciy-datetime com="time" type="datetime"></ciy-datetime></div>
|
||
</div>
|
||
<button class="btn" type="submit">保存</button>
|
||
</form>
|
||
</div>
|
||
|
||
<script src="/jscss/ciy.js"></script>
|
||
<script src="/jscss/ciycmp.js"></script>
|
||
<script src="./common.js"></script>
|
||
<script>
|
||
'use strict';
|
||
ciyfn.pageload(function() {
|
||
ciycmp({ dom: '[com=status]' });
|
||
ciycmp({ dom: '[com=time]', type: 'datetime' });
|
||
});
|
||
|
||
function save(event) {
|
||
event.preventDefault();
|
||
var postparam = ciyfn.getform(event.target);
|
||
ciyfn.callfunc('save', postparam, function(json) {
|
||
ciyfn.toast('保存成功');
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
---
|
||
|
||
## 常用API
|
||
|
||
### 工具函数
|
||
|
||
```javascript
|
||
// 全局函数
|
||
tostr(val, defval) // 转字符串
|
||
toint(val, def) // 转整数
|
||
tofloat(val, def) // 转浮点数
|
||
tostamp(time) // 转时间戳
|
||
isarray(v) // 判断是否Array类型
|
||
isobj(v) // 判断是否Object类型
|
||
iselement(v) // 判断是否Element类型
|
||
|
||
// DOM操作
|
||
$5(selector) // 选择元素
|
||
dom.css('color') // 获取样式
|
||
dom.css()['color'] // 获取计算后样式
|
||
dom.css(name, val) // 设置样式
|
||
dom.css({color:#xxx}) // 批量设置样式
|
||
dom.show() / dom.hide() // 显示/隐藏
|
||
dom.on(event, handler) // 绑定事件
|
||
dom.val(value) // 获取/设置值
|
||
|
||
// 数据处理
|
||
ciyfn.tojson(str) // JSON解析
|
||
ciyfn.jsontostr(obj) // JSON序列化
|
||
ciyfn.tostamp(time) // 转时间戳
|
||
ciyfn.todatetime(stamp, fmt) // 格式化日期
|
||
|
||
// 存储
|
||
ciyfn.getstorage(key) // 读取存储
|
||
ciyfn.setstorage(key, val) // 写入存储
|
||
|
||
// 消息提示
|
||
ciyfn.toast(msg, type) // 提示
|
||
ciyfn.alert(opn) // 弹窗
|
||
|
||
// API调用
|
||
ciyfn.callfunc(url, data, callback, opn) // 调用接口
|
||
```
|
||
|
||
### 表格API
|
||
|
||
```javascript
|
||
// 分页
|
||
table.callpage(page); // 加载页面
|
||
table.updateline(json); // 更新行
|
||
table.delline(json); // 删除行
|
||
|
||
// 搜索
|
||
table.search(dom, act); // 执行搜索
|
||
```
|
||
|
||
---
|
||
|
||
## 八、注意事项
|
||
|
||
1. **原生开发**: 尽量使用原生开发,已封装$5(jQuery改进版)
|
||
1. **严格模式**: 所有JS代码使用 `'use strict'`
|
||
3. **引号使用**: 代码中使用单引号
|
||
4. **事件处理**: 使用 `$5().on()` 或原生 `addEventListener`
|
||
5. **异步处理**: 使用回调函数处理异步结果
|
||
6. **数据验证**: 后端必须验证数据
|
||
7. **错误处理**: 无需处理API错误,自动弹窗。特殊情况,在opn参数中定义fail函数
|
||
8. **性能优化**: 大数据列表使用分页加载
|
||
9. **兼容性**: 确保IE11+兼容
|
||
10. **安全性**: 防止XSS和CSRF攻击
|
||
11. **菜单结构设计**: PC端菜单应具备清晰的层级结构,二次菜单设计必须有一级菜单。
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### Q: 组件不显示?
|
||
|
||
A: 检查是否正确引入了组件库文件(ciycmp.js、ciycmp2.js)。
|
||
|
||
### Q: 表格数据不加载?
|
||
|
||
A: 检查API返回格式是否符合标准,确认 `url` 参数正确。
|
||
|
||
|
||
## 参考资料
|
||
|
||
- 组件示例:`web/admin/demo/front/`
|
||
- API文档:参考各组件的源码注释
|
||
- 设计思路:参考框架注释中的设计说明
|
||
|
||
---
|
||
|
||
**版本**: 1.0.0
|
||
**作者**: Ciyon Team |