27

BeetleX.AdminUI介绍

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU5NzcwMjI2Mw%3D%3D&%3Bmid=2247484499&%3Bidx=1&%3Bsn=48e1e7352da19a46a07d226f35777a9d
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

BeetleX.AdminUI 是基于 Beetlexjs + Vuejs + Bootstrap 相结合的后台管理框架,主要介绍在不使用 Webpack 的情况下,如何用 VS 来开发一个单页面的Web后台管理应用。如果你喜欢用 Vuejs + Html ,那通过这个示例你可以更好的了解 Vuejs + Html 的使用。在介绍之前先看一下效果:

7vA7ram.jpg!web

可以通过访问 http://adminui.beetlex.io/ 查看在线演示.

在开发过程中虽然没有和Webpack,不过模式还是遵循组件化方式进行处理;通过这个示例让不想使用Webpack的开发人员可以使用另一种途径来进行开发 Vue 前端应用。

首页

这种模式没有app.js,取而代之的是一个 index.html ,这个页面主要是用于描述界面的主体布局,具体如下:

<div id="page">
        <main_menu @menu_resize="OnMenuResize($event)" @openwindow="OnOpenWindow($event)"></main_menu>
        <windows_bar :windows="windows" :full="full" :selectwindow="selectWindow.id" @openwindow="OnOpenWindow($event)" @close="OnCloseWindows($event)"></windows_bar>
        <div class="main-content" :style="{left:(full=='max'?'50px':'250px')}">
            <keep-alive>
                <component :is="selectModel" @openwindow="OnOpenWindow($event)" :token="selectWindow.data"></component>
            </keep-alive>
        </div>
        <page_footer></page_footer>
    </div>

布局很简单包括有主菜单,页脚,窗体栏和主内容显示.主页面的功能很简单,主要用来管理切换窗体,新建窗体和关闭窗体即可;详细代码如下:

Vue.prototype.$open = function (id, title, model, data) {
            this.$emit('openwindow', { id: id, title: title, model: model, data: data });
        };
        var model = {
            full: 'min',
            windows: [],
            selectWindow: {
            },
            selectModel: '',
        };
        var page = new Vue({
            el: '#page', data: model,
            methods: {
                OnMenuResize: function (event) {
                    this.full = event;
                },

                OnCloseWindows: function (e) {
                    var index = -1;
                    for (i = 0; i < this.windows.length; i++) {
                        if (this.windows[i].id == e.id) {
                            index = i;
                            break;
                        }
                    }
                    if (index >= 0) {
                        this.windows.splice(index, 1);
                        if (this.windows.length > 0)
                            this.OnOpenWindow(this.windows[0]);
                        else {
                            this.selectWindow = null;
                            this.selectModel = null;
                        }
                    }

                },

                OnOpenWindow: function (e) {
                    var items = [];
                    items.push(e);
                    for (i = 0; i < this.windows.length; i++) {
                        var item = this.windows[i];
                        if (item.id != e.id)
                            items.push(item);
                    }
                    this.windows = items;
                    this.selectWindow = e;
                    this.selectModel = e.model;
                },
            }
        });
        page.OnOpenWindow({ id: 'home', title: '主页', model: 'models_home' })

windows_bar

这个组件主要描述窗体的标签,解决窗体的切换功能;具体 Vue 模块如下:

<template id="__windowsbar">
    <div class="windows_bar" :style="{left:(fullStatus=='max'?'60px':'260px')}">
        <ul class="nav nav-tabs" style="display:flex">
            <li v-for="item in items" role="presentation" :class="[select==item.id?'active':'']">
                <a href="javascript:void(0)" @click="$open(item.id,item.title,item.model)">{{item.title}}</a>
                <img v-if="item.id!='home'" @click="OnClose(item)" src="/images/tabclose.png"/>
            </li>
        </ul>
    </div>
</template>

对应的展示如下:这个组件包括了一些简单的行为,选择窗体 $open(item.id,item.title,item.model) 和关闭窗体 OnClose(item) ;还有一个行为就是根据主菜单的样式来调整自己的占比宽度。详细的功能代码如下:

Vue.component('windows_bar', {
        props: ['windows', 'full', 'selectwindow'],
        data: function () {
            return {
                fullStatus: this.full,
                items: this.windows || [],
                select: this.selectwindow
            }
        },
        watch: {
            full(val) {
                this.fullStatus = val;
            },
            windows(val) {
                this.items = val;
            },
            selectwindow(val) {
                this.select = val;
            },
        },
        methods: {
            OnClose: function (e) {
                this.$emit('close', e);
            }
        },
        template: __windowsbar,
        mounted: function () {

        }
    });

主菜单

主菜单主要用于描述关键模块窗体,它有两种展示模式分别是:全显示和只显示功能图标

<template id="__menu">
    <div :class="[full=='min'?'menu_full':'menu_min']">
        <div>
            <h3 v-if="full=='min'" style="margin-top:10px;margin-right:-5px;padding-left:20px;">BeetleX.AdminUI</h3>
            <a v-if="full=='min'" href="javascript:void(0)" @click="OnResizeMenu('max')" style="float:right;margin-top:-35px;"><img style="width:24px;" src="/images/min.png" /></a>
            <hr v-if="full=='min'" style="padding:4px;margin:0px;" />
            <ul>
                <li v-if="full!='min'"><a href="javascript:void(0)" @click="OnResizeMenu('min')">
                    <img src="/images/full.png" style="height:32px;" /></a></li>
                <li>
                    <a href="javascript:void(0)" @click="OnOpenHome">
                        <img src="/images/home.png" style="height:32px;" />
                        <span v-if="full=='min'">主页</span>
                    </a>
                </li>
                <li>
                    <a href="javascript:void(0)" @click="OnOpenCustomer">
                        <img src="/images/customer.png" style="height:32px;" />
                        <span v-if="full=='min'">客户</span>
                    </a>
                </li>
                <li>
                    <a href="javascript:void(0)" @click="OnOpenOrders">
                        <img src="/images/order.png" style="height:32px;" />
                        <span v-if="full=='min'">订单</span>
                    </a>
                </li>
                <li>
                    <a href="javascript:void(0)" @click="OnOpenEmployees">
                        <img src="/images/employee.png" style="height:32px;" />
                        <span v-if="full=='min'">雇员</span>
                    </a>
                </li>
                <li>
                    <a href="javascript:void(0)" @click="OnOpenAbout">
                        <img src="/images/about.png" style="height:32px;" />
                        <span v-if="full=='min'">关于</span>
                    </a>
                </li>
            </ul>
        </div>
    </div>
</template>

主菜单的主要功能就是告诉页面需要打开那个模块,具体代码如下:

<script>
    Vue.component('main_menu', {
        data: function () {
            return {
                full: 'min',
            }
        },
        methods: {
            OnResizeMenu: function (value) {
                this.full = value;
                this.$emit('menu_resize', value)
            },
            OnOpenHome: function () {
                this.$open('home', '主页', 'models_home');
            },
            OnOpenCustomer: function () {
                this.$open('customers', '客户列表', 'models_customers');
            },
            OnOpenEmployees: function () {
                this.$open('employees', '雇员列表', 'models_employees');
            },
            OnOpenOrders: function () {
                this.$open('orders', '订单列表', 'models_orders');
            },
            OnOpenAbout: function () {
                this.$open('about', '关于', 'models_about');
            },
        },
        template: __menu,
        mounted: function () { }
    });
</script>

这样一个能支持多模块显示切换的主页就完成了,接下来的工作就是实现相关子模块,由于这个示例的子模块比较多就不一一介绍,只是抽取个别来介绍。

客户列表

接下来简单地 介绍 一下客户列表模块,并在模块中打开一个客户信息的窗体。   3yqIFfb.jpg!web  详细模板实现如下:

<template id="__models_customers">
    <div>
        <table class="table">
            <thead>
                <tr>
                    <th>CustomerID</th>
                    <th>CompanyName</th>
                    <th>ContactName</th>
                    <th>ContactTitle</th>
                    <th>Phone</th>
                    <th>Fax</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="item in items">
                    <td><a href="javascript:void(0)" @click="OnOpen(item)"> {{item.CustomerID}}</a></td>
                    <td>{{item.CompanyName}}</td>
                    <td>{{item.ContactName}}</td>
                    <td>{{item.ContactTitle}}</td>
                    <td>{{item.Phone}}</td>
                    <td>{{item.Fax}}</td>
                </tr>
                <tr v-if="GetCustomers.data.index<pages">
                    <td colspan="6" style="text-align:right;">
                        <a href="javascript:void(0)" @click="GetCustomers.get()">({{GetCustomers.data.index}}/{{pages}})更多...</a>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

对应的脚本代码

Vue.component('models_customers', {
        data: function () {
            return {
                GetCustomers: new beetlexAction("/Customers", { index: 0 }, { pages: 0, items: [] }),
                pages: 0,
                items: []
            }
        },
        methods: {
            OnOpen: function (item) {
                this.$open('cust' + item.CustomerID, '客户:' + item.CompanyName, 'models_customerdetail', { id: item.CustomerID });
            }
        },
        mounted: function () {
            var _this = this;
            this.GetCustomers.requested = function (r) {
                _this.pages = r.pages;
                this.data.index++;
                r.items.forEach(function (v) {
                    _this.items.push(v);
                });
            };
            this.GetCustomers.get();
        },
        template: __models_customers,
    })

以上是一个客户列表的功能模块,其他模块就不详细 介绍 ,可以查看项目

https://github.com/IKende/AdminUI

总结:为什么想到这种方式来使用vuejs的主要原因不想安装vscode和相关webpack套件,如果你也不喜欢这一套也可以搞个方式来写。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK