vue-autoui自匹配webapi的UI控件
vue-autoui 是一款基于vue
和element
扩展的一个自动化UI控件,它主要提供两个控件封装分别是auto-form
和auto-grid
; 通过这两个控件可以完成大多数的信息输入和查询输出的需要.auto-form
和auto-grid
是通过json
来描述展示的结构,在处理上要比写html
标签来得方便简单, 但这控件的最大优势并不是在这里,它最重要的功能是可以结合webapi
的信息来自动输出界面,只需要调整webapi
的信息结构即可完成UI的调整。
基础使用
控件可以直接在vuejs功能中使用,但需要结合json
来设置具体UI展示,以下是一个简单的例子
<auto-form ref="form" v-model="data" size="mini" :info="info"> </auto-form>
<el-button @click="if($refs.form.success()){alert(JSON.stringify(data))}">确定</el-button>
功能很简单就是显示当前输入并验证通过的数据,下面用json描述信息输入源。
data(){
return {
info: { items: [] },
data: { },
};
},
mounted(){
var items = [];
items.push({
name: 'active', label: '活动名称', rules: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
]
});
items.push({
name: 'region', label: '活动区域', type: 'select',
data: [{ value: '广州' }, { value: '深圳' }, { value: '上海' }, { value: '北京' }],
rules: [{ required: true, message: '请选择活动区域', trigger: 'change' }],
eof: true
});
items.push({ name: 'starttime', label: '开启时间', type: 'date', rules: [{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }] });
items.push({ name: 'endtime', label: '-', type: 'date', eof: true, rules: [{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }] });
items.push({ name: 'instant', type: 'switch', label: '即时配送', eof: true });
items.push({
name: 'nature', type: 'checkbox', label: '活动性质',
rules: [{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }],
data: [{ value: '美食/餐厅线上活动' }, { value: '地推活动' }, { value: '线下主题活动' }, { value: '单纯品牌暴光' }], eof: true
});
items.push({
name: 'resource', label: '特殊资源', type: 'radio', rules: [{ required: true, message: '请选择活动资源', trigger: 'change' }],
data: [{ value: '线上品牌商赞助' }, { value: '线下场地免费' }], eof: true
});
items.push({ name: 'remark', label: '活动形式', type: 'remark', rules: [{ required: true, message: '请填写活动形式', trigger: 'blur' }] })
this.info = { items: items}
}
以上是使用json
来描述一个输出的界面,具体效果如下:
虽然用json
来描述界面会比html
描述会方便一些,但总体上来说工作量还是有些大的,在调整界面的时候也不方便。接下介绍一下如何结合BeetleX.FastHttpApi
来进一步简化这些繁琐的操作。
Webapi动态输出
其实在构建vue-autoui
的时候更多是考虑和BeetleX.FastHttpApi
进行一个整合,通过和后端融合可以把这些UI编写的工作量大大节省下来,让开发这些功能变得更简单方便,更重要的是api变化后界面就自动适应
。使用要求:在和BeetleX.FastHttpApi
整合还需要引用BeetleX.FastHttpApi.ApiDoc
插件,因为这个插件用于给接口输出对应UI的JSON
信息。接下来通过几个示例来介绍整合的方便性:
登陆
登陆功能是比较常见的,接下来看一下使用auto-form
如何结合webapi
来完成这个功能。
<div>
<auto-form ref="login" url="/login" v-model="login.data" size="mini"> </auto-form>
<el-button size="mini" @click="if($refs.login.success())login.post()">
登陆
</el-button>
</div>
以上是一个登陆功能UI的定义,是不是很简单呢?通过指定url
的webapi连接即可以自动适应UI;这时候只需要针对登陆接口进行一个定义即可:
[Input(Label = "用户名", Name = "name", Eof = true)]
[Required("用户名不能为空", Name = "name")]
[Input(Label = "密码", Name = "pwd", Type = "password", Eof = true)]
[Required("用户密码不能为空", Name = "pwd")]
[Input(Label = "保存状态", Value = true, Name = "saveStatus")]
public bool Login(string name, string pwd, bool saveStatus)
{
Console.WriteLine($"name:{name} pwd:{pwd} saveStatus:{saveStatus}");
return name == "admin";
}
注册
接下来定义一个信息多些的注册界面
<div>
<auto-form ref="login" url="/register" v-model="register.data" size="mini" @completed="onCompleted"> </auto-form>
<el-button size="mini" @click="if($refs.login.success())register.post()">
注册
</el-button>
</div>
在UI定义上基于没什么变化,只是调整一下对应的url
地址,在这里多了一下completed
事件,这个事件主要是通过接口加载UI信息才会触发的。对应功能的javascript
代码
data(){
return {
register: new beetlexAction('/register', {}),
checkConfirmPassword: (rule, value, callback) => {
var password = this.$refs.login.getField('Password');
var cpassword = this.$refs.login.getField('ConfirmPassword');
if (password.value != cpassword.value)
callback(new Error('确认密码不正确!'));
else
callback();
},
}
},
methods: {
onCompleted(){
this.$refs.login.getField('ConfirmPassword').rules.push({ validator: this.checkConfirmPassword, trigger: 'blur' });
},
},
mounted() { this.register.requested = (r) => {
alert(JSON.stringify(r));
};
}
代码主要是定密码和确认密码的对比验证,接下来看一下后台注册对应的接口
[Post]
public RegisterDto Register(RegisterDto register)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(register));
return register;
}
public class RegisterDto
{
[Input(Label = "用户名", Eof = true)]
[Required("用户名不能为空")]
[DataRange("用户名的必须大于3个字符", Min = )]
public string Name { get; set; } [Input(Label = "邮箱地址", Eof = true)]
[Required("邮件地址无效", Type = "email")]
public string Email { get; set; } [Input(Label = "密码", Eof = true, Type = "password")]
[Required("输入密码")]
public string Password { get; set; } [Input(Label = "确认密码", Eof = true, Type = "password")]
[Required("输入确认密码")]
public string ConfirmPassword { get; set; } [GenderInput(Label = "性别", Value = "男", Eof = true)]
public string Gender { get; set; } [Required("选择所在城市")]
[CityInput(Label = "城市", Eof = true)]
public string City { get; set; } [HobbyInput(Label = "爱好")]
[Required("选择爱好", Type = "array", Trigger = "change")]
public string[] Hobby { get; set; }
}
服务代码也没太多的变化,只是通过一些标签来标记一下相关属性的数据源和输入要求.具体运行效果如下:
数据列表
有应用中除了数据输出外更多的数据列表,auto-grid
即是专门用于处理列表的一个控件,这个控件提供分页,选择,编辑和删除的功能;接下来做一个简单的雇员列表示例:
<auto-grid url="/employees" @completed="employees.get()"
@itemchange="onItemChange"
@itemdelete="onItemDelete"
@command="onCommand"
:data="employees.result"
size="mini" height="100%"
edit="true" delete="true">
</auto-grid>
这个列表提供编辑和删除功能,相关脚本代码如下:
data(){
return {
employees: new beetlexAction('/employees', {}, [])
}
},
methods: {
onCommand(e){
this.$open('models-employee', e.data);
},
onItemChange(item){
if (confirm('是否要修改' + item.data.FirstName + '?')) {
item.success();
}
},
onItemDelete(item){
if (confirm('是否要删除' + item.data.FirstName + '?')) {
item.success();
}
},
},
mounted() { }
接下来的工作就是在服务端定义api
来输出结果
[Column("FirstName", Type = "link")]
[Column("LastName", Read = true)]
[Column("Title")]
[Column("HomePhone")]
[Column("City")]
[Column("Address")]
public object Employees()
{
return DataHelper.Defalut.Employees;
}
动态查询
实际应用中需要提供查询条件输入,这个时候就可以把auto-form
和auto-grid
整合起来,以下通过一个简单的订单查询来展示这两个控件结合使用
<auto-form url="/orders" v-model="orders.data" @completed="orders.get()" size="mini" @fieldchange="orders.get()"> </auto-form>
<auto-grid url="/orders" height="300" :data="orders.result.items" :pages="orders.result.pages" :currentpage="orders.result.index" @pagechange="onPageChange" size="mini"> </auto-grid>
可以在auto-form
的fieldchange
事件中自动执行查询,对应的脚本代码如下:
data(){
return {
orders: new beetlexAction("/orders", {}, { index: 0, pages: 0, items: [] })
};
},
methods: {
onPageChange(page){
this.orders.data.index = page;
this.orders.get();
},
},
mounted(){ }
接下来需要实现服务端代码,由于方法需要描述输入和列表所以对应的标签比较多
[Input(Name = "id", Type = "select", DataUrl = "/EmployeeSelecter", Label = "雇员",NullOption =true)]
[Input(Name = "customerid", Type = "select", DataUrl = "/CustomerSelecter", Label = "客户",NullOption =true, Eof = true)]
[SizeInput(Name = "size", Label = "分页记录数")]
[Input(Name = "index", Hide = true)] [Column("OrderID", Read = true)]
[Column("EmployeeID", Type = "select", DataUrl = "/EmployeeSelecter")]
[Column("CustomerID", Type = "select", DataUrl = "/CustomerSelecter")]
[Column("OrderDate", Type = "date")]
[Column("RequiredDate", Type = "date")]
[Column("ShippedDate", Type = "date")]
public object Orders(int id, string customerid, int index, int size, IHttpContext context)
{
Func<Order, bool> exp = o => (id == || o.EmployeeID == id)
&& (string.IsNullOrEmpty(customerid) || o.CustomerID == customerid);
int count = DataHelper.Defalut.Orders.Count(exp);
if (size == )
size = ;
int pages = count / size;
if (count % size > )
pages++;
var items = DataHelper.Defalut.Orders.Where(exp).Skip(index * size).Take(size);
return new { pages, index, items }; }
插件详细代码 https://github.com/IKende/BeetleX-Samples/tree/master/Web.AutoUI
https://github.com/IKende/vue-autoui
vue-autoui自匹配webapi的UI控件的更多相关文章
- 如何使用JavaScript UI控件(WijmoJS)构建Electron应用程序
概述 What is Electron? Electron是一个使用JavaScript.HTML和CSS构建跨平台桌面应用程序的框架. 您可以将Electron与纯JavaScript或您选择的Ja ...
- 实现Winform 跨线程安全访问UI控件
在多线程操作WinForm窗体上的控件时,出现“线程间操作无效:从不是创建控件XXXX的线程访问它”,那是因为默认情况下,在Windows应用程序中,.NET Framework不允许在一个线程中直接 ...
- 跨线程访问UI控件时的Lambda表达式
工作中经常会用到跨线程访问UI控件的情况,由于.net本身机制,是不允许在非UI线程访问UI控件的,实际上跨线程访问UI控件还是 将访问UI的操作交给UI线程来处理的, 利用Control.Invok ...
- ANDROID L——Material Design详解(UI控件)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...
- WinForm/Silverlight多线程编程中如何更新UI控件的值
单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么 ...
- 富客户端 wpf, Winform 多线程更新UI控件
前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...
- UI控件(复习一下)
如何修改控件状态• 可见,确实需要经常修改控件状态• 那如何去修改控件的状态呢?方法很简单➢ 每一个UI控件都是一个对象➢ 修改UI控件的状态,其实就是修改控件对象的属性➢ 比如修改UILabel显示 ...
- IOS学习资源收集--开发UI控件相关
收集的一些本人了解过的iOS开发UI控件相关的代码资源(本文持续补充更新) 内容大纲: 1.本人在github上也上传了我分装好的一些可重复利用的UI控件 2.计时相关的自定义UILabel控件 正文 ...
- 《深入理解Windows Phone 8.1 UI控件编程》基于最新的Runtime框架
<深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的 ...
随机推荐
- 关于unicode汉字范围正则表达式的写法
\u2E80-\u2EFF:CJK部首补充: \u2F00-\u2FDF:康熙部首: \u3000-\u303F:CJK标点符号: \u31C0-\u31EF:CJK笔划: \u3200-\u32FF ...
- Linux系统添加新用户
Linux系统中一般不直接使用root用户进行操作,需要添加新的用户. 首先,查看当前系统已有的用户 cat /etc/passwd 查看用户组 cat /etc/group 其次,添加想要的用户组和 ...
- DocumentFragment的相关用法
额,今天看了vue1.0关于模板渲染的知识,认识了DocumentFragment这个东西,它相当于一个节点容器,我们对他使用appendChild时,只有它的子节点会被插入进去,它本身不会插入进去, ...
- 吴裕雄--天生自然KITTEN编程:青蛙答题过河
- 一下午简单写个搭建Flutter开发环境,dome跑起来!
1.下载flutter包由于需要翻墙,国内下载会出现问题,所有需要先配置一下用户环境变量. export PUB_HOSTED_URL=https://pub.flutter-io.cn export ...
- 从VR泛滥到倒闭看热门投机的山寨创业心态
相对国外来说,国人的从众心理非常严重.无数的段子和"名人名言"都在反复向我们传递出一个信息:国人在做事的时候,总是随大流,趋向热点.而从行业角度来看,结果就会造成行业中良莠不齐.鱼 ...
- 想清楚再入!VR硬件创业能“要你命”
每一次跨时代新产品的出现,总会让科技行业疯狂一阵儿,十年前是智能手机,今天自然是VR.自2015年开始,VR火的越来越让人欣喜,让人兴奋,更让人越来越看不清,越来越害怕.数不清的大小品牌义无反顾的杀入 ...
- 【转载】checkbox实现全选/取消全选
比较简单.好理解的写法,做个备注.查看请前往原地址:http://blog.csdn.net/graceup/article/details/46650781 <html> <bod ...
- UVA - 10462 Is There A Second Way Left?
题意: 给你一张无向图,让你判断三种情况:1.不是连通图(无法形成生成树)2.只能生成唯一的生成树 3.能生成的生成树不唯一(有次小生成树),这种情况要求出次小生成树的边权值和. 思路: 比较常见的次 ...
- PostgreSQL与MySQL对比
都属于开放源码的一员,性能和功能都在高速地提高和增强.MySQL AB的人们和PostgreSQL的开发者们都在尽可能地把各自的数据库改得越来越好,所以对于任何商业数据库使用其中的任何一个都不能算是错 ...