BeetleX.WebFamily针对Web SPA应用的改进

        BeetleX.WebFamily1.0在集成vue+element+axios的基础上添加应用页、窗体布局和登陆验证等功能。通过以上功能开发Web SPA应用时只需要编写vue控件和配置菜单即可实现应用开发。

使用

        创建一个.net控制台项目,然后通过Nuget引入BeetleX.WebFamily1.0组件,并在Main方法中编写以下代码:

static void Main(string[] args)
{
    WebHost host = new WebHost();
    //注册当前程序集
    host.RegisterController<Program>()
    .Setting(o =>
    {
        o.SetDebug();
        o.Port = 80;
        o.LogLevel = EventArgs.LogType.Error;
        o.LogToConsole = true;
    })
    .Initialize(s =>
    {
        s.Vue().Debug();
    }).Run();
}

然后运行这个程序即可在浏览器上访问,BeetleX.WebFamily在没有任何配置的情况下访问页面如下:

组件默认的开始页面,接下来的工作就可以通过编写VUE组件和配置菜单来实现自己的系统功能。

VUE扩展函数

        为了更好地应对SPA开发,组件针对Vue扩展了一系列的方法用于开发的需要;这些方法可以在所有自定义的Vue组件中使用。

//打开主页面窗体
$toHome()
//告诉应用登陆的用户,一般用于自定义登陆时,用于通讯应用登陆成功
$userLogin(name)
//重新加载Web信息,包括菜单和登陆信息等
$loadWebInfo()
//关闭指定id的窗体
$closeWindow(id)
//打开或激活窗体,参数分别是:唯一于标识,标题,对应VUE的组件名称和传入的数据。
$openWindow(id,title,model,data)
//获取当前打的所有窗体
$getWindows()
//激活对应菜单id的窗体
$openMenu(id)
//获取当前登陆的用户信息,包括有:用户名和角色
$getUser()
//注册窗体大小变化通知
$addResize(callback)
//广播窗体大小通知
$resizeWindow()
//ajax的post请求
$post(url,data)
//ajax的get请求
$get(url,data)
//ajax的put请求
$put(url,data)

通过以上方法组件可以简单地和应用进行一些布局交互操作。

添加首页/菜单

        组件默认情况下是一个没有内容的主页面,为了满足的需求需要配置对应的默认页面和菜单。可以在Initialize方法里面添加以下代码进行一个应用初始化。

//设置应用标题
WebHost.Title = "Northwind";
//调协头部显示的Vue组的名称
WebHost.HeaderModel = "myheader";
//是否需要登陆,默认为false,当设置true时应用获取不到登陆状态会自弹出登陆
WebHost.MustLogin = true;
//设置应用对应首页的vue控件
WebHost.HomeModel = "home";
//获取菜单,方法参数分别是:当前用户名,角色和http上下文
//菜单支持多层,根本需要添加对应的Child即可
WebHost.GetMenus = (user, role, context) =>
{
    List<Menu> menus = new List<Menu>();
    var item = new Menu();
    item.ID = "home";//菜单ID
    item.Name = "主页";//标题
    item.Img = "/images/home.png";//菜单图标,可缺省;
    item.Model = "home";//打开对应的vue组件。
    menus.Add(item);
    item = new Menu();
    item.ID = "product";
    item.Name = "产品";
    item.Img = "/images/product.png";
    item.Model = "products";
    menus.Add(item);


    item = new Menu();
    item.ID = "order";
    item.Name = "订单";
    item.Img = "/images/order.png";
    item.Model = "orders";
    menus.Add(item);


    item = new Menu();
    item.ID = "customer";
    item.Name = "客户";
    item.Img = "/images/customer.png";
    item.Model = "customers";
    menus.Add(item);


    item = new Menu();
    item.ID = "employee";
    item.Name = "雇员";
    item.Img = "/images/employee.png";
    item.Model = "employees";
    menus.Add(item);
    return Task.FromResult(menus);
};

通过以上配置重启程序就可以得到一个新的应用效果。

设置自定义头

        组件预留了一个头部位置,用来制定自己的应用头部信息,如:登陆用户,消息和快捷按钮等内容。

WebHost.HeaderModel = "myheader";

可以设置HeaderModel属性用于替换页面头部信息,然后通过Vue扩展函数进行页面相关操作,以下是示例头部的实现。

<div>
    <h4>BeetleX Webfamily Northwind示例</h4>
    <a style="float:right;position:absolute;margin-top:-40px;margin-left:350px;cursor:pointer;" 
    v-if="$getUser().name" @click="$userSignout()">退出</a>
</div>

登陆/JWT配置

        有很多应用需要访问需要验证登陆,组件默认也集成这一功能;当使用这些功能的时候需要开启JWT验证和设置必须登陆访问。

host.UseJWT()//访问webapi时必须进行验证控制
//开启登陆,当应用检测到没有用户信息时自动弹出登陆窗体
WebHost.MustLogin = true;

当开启以上配置后访问应用会弹出以下登陆框进行登陆验证。

组件默认所有用户名都可以有效登陆并不加以控制,可以通过添加以下委托来实现登陆验证的逻辑处理。

WebHost.LoginHandler = (user, pwd, context) =>
{
    //写入cookie
    context.SetJwtToken(user, "user", 60 * 60);
    return Task.CompletedTask;
};

可以通过以上方法进行验证,验证错误抛出异常即可,如果成则通过context写入当前登陆信息。

        只要开启了JWT那所有请求的webapi方法都需要验证才能有效请求,如果不希望某些方法不进行验证可以在控制器或方法中打上以下标签。

 [AuthMark(AuthMarkType.NoValidation)]
 public class Home
 {
 }

        如果登陆框功能不满足要求也是可以自定义登陆窗体,只要编写一个登陆组件如下:

<div>
    <el-form size="mini" :model="record" label-width="120px" ref="dataform">
        <el-row>
            <el-col :span="24">
                <el-form-item label="用户名" prop="Name" :rules="Name_rules"><el-input size="mini" v-model="record.Name"></el-input></el-form-item>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="24">
                <el-form-item label="密码" prop="Password" :rules="Password_rules"><el-input size="mini" v-model="record.Password" show-password></el-input></el-form-item>
            </el-col>
        </el-row>
        <el-row>
            <el-col span="24" style="text-align:right">
                <el-button size="mini" style="padding-left:10px; padding-right:10px;" @click="submitForm">登陆</el-button>
            </el-col>
        </el-row>
    </el-form>
</div>
<script>
    {
        props: [],
            data(){
            return {
                Name_rules: [{ required: true, message: '用户名不能为空!', trigger: 'blur' },],
                Password_rules: [{ required: true, message: '密码不能为空!', trigger: 'blur' },],
                record: {
                    Name: null,
                    Password: null,
                }
            };
        },
        methods: {
            submitForm() {
                this.$refs['dataform'].validate((valid) => {
                    if (valid) {
                        this.$post('/website/login', this.record).then(r => {
                            this.$userLogin(this.record.Name);
                        });
                    }
                });
            },
            resetForm() {
                this.$refs['dataform'].resetFields();
            }
        },
        mounted(){
        }
    }
</script>


在登陆成功的方法中调用this.$userLogin(this.record.Name);通知应用;最后把这个组件配置即可:

WebHost.LoginModel = "mylogin";

组件定义

        使用组件后只需要专注于功能组件编写,组件支持*.vue文件格式基本和Vue CLI一样,微小的差别就是在这里无须import引用组件。所有vue文件必须编写在项目的views目录,引用组件的名称默认使用文件名称.

以下是员工信息修改组件:

<div>
    <auto-form v-model="data" ref="editor" size="mini" style="width:600px;margin:auto;" @command="onSave">


    </auto-form>
</div>
<script>
    export default {
        props: ['token', 'winid'],
        data() {
            return {
                data: {}
            };
        },
        methods: {
            onSave() {
                this.$confirmMsg('是否要保存数据?', () => {
                    this.$closeWindow(this.winid);
                });
            },
        },
        mounted() {
            var edit = new autoData();
            edit.addText("LastName", "LastName", true).require('The value cannot be null');
            edit.addText("FirstName", "FirstName", true).require('The value cannot be null');
            edit.addText("Title", "Title", true).require('The value cannot be null');
            edit.addText("TitleOfCourtesy", "TitleOfCourtesy", true).require('The value cannot be null');
            edit.addDate("BirthDate", "BirthDate", true).require('The value cannot be null');;
            edit.addDate("HireDate", "HireDate", true).require('The value cannot be null');;
            edit.addText("Address", "Address", true);
            edit.addText("City", "City", true);
            edit.addText("PostalCode", "PostalCode", true);
            edit.addText("Country", "Country", true);
            var f = edit.addSelect("ReportsTo", "ReportsTo", true);
            f.dataurl = '/EmployeesSelectOptions';
            f.nulloption = true;
            edit.addButton("save", "保存");
            if (this.token) {
                edit.setValue(this.token);
            }
            edit.bindForm(this.$refs.editor);
        },
    }
</script>

可以在员工列表中打开它

this.$openWindow('雇员' + e.data.Name, '(雇员)' + e.data.Name,'employeeinfo',  e.data);

组件定义了两个属性,分别是token和winid;只要通过$openWindow打开的都能接收到这两个信息,前者是打开窗体传进来的数据,后者是对应窗体ID;可以通过this.$closeWindow(this.winid);关闭自己所在窗体。

数据请求

        组件集成了axios进行ajax访问,为了让调用更方便组件提供了以下简化方法调用。

//ajax的post请求
$post(url,data)
//ajax的get请求
$get(url,data)
//ajax的put请求
$put(url,data)

以下是一个简单的登陆调用过程

this.$post('/website/login', this.record).then(r => {
    this.$userLogin(this.record.Name);
});

总结

        通过引入组件可以快带地进行Web SPA应用开发,组件提供基础布局、安全控制和数据访问的基础功能,让你可以更专注于业务功能的实现。虽然集成功能并不丰富,但足以帮你解决主要的繁琐工作。再结合:

http://vueeditor.beetlex.io/ 数据界面在线生成工具更加让你事半功倍。

通过以下地址下载完整示例:

https://github.com/beetlex-io/BeetleX-Samples

有使用上的问题可以提交到:

https://github.com/beetlex-io/FastHttpApi/issues

BeetleX

开源跨平台通讯框架(支持TLS)
提供高性能服务和大数据处理解决方案

https://beetlex.io

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值