Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建

Mvc是近年比较流行的一种web开发模式  个人觉得MVC是一种简单易懂、高效的开发模式;关于开发模式还有MVVM, vue.js就是这种模式,这里就不讲什么是MVC、 MVVM了, 有兴趣可以百度了解一下。

主要用到的技术:

Asp.net MVC 5

IView + Vue.js(这两者是完美搭档, IView:基于Vue.js的UI)

require.js (按需加载js模块, 详解更多JS模块化工具requirejs教程,或进入require.js官网)

sql server 2017

Visual Studio 2017

 

下面我们将以一个(SecurityDemo)通用权限系统demo为例:

目录

第1章. 创建SecurityDemo项目

第2章 第一个实例

第3章: HtmlHelper类封装UI



1. 新建项目

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第1张图片

点确定 -->

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第2张图片

 

2. 添加RequireJs , IView + Vue.js到项目

  菜单选择工具 --》 NuGet包管理器 --》 管理解决方案Nuget程序包:

a.安装requirejs:(也要安装require.css程序包,因为IView.css将作为IView的依赖引入)

找到Requirejs的程序包, 右边列表项目里勾选指定的项目,点击“安装“按钮

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第3张图片

安装成功后,会看到多了下面几个文件

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第4张图片

b.安装IView + Vue.js

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第5张图片

这里版本并不是最新的, 安装成功后, 可以去官网拿最新的替换现在的,我们这里也是这样。(IView官网)

安装成功后, 多了下面这些文件:

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第6张图片

这些文件我们也是要替换的,资源URL, 找到我们要替换的文件,下载后替换掉 ,官网好像不能打包下载,我们可以用迅雷批量下载:

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第7张图片

右键菜单点击迅雷下载全部链接,取消下载html类型的文件

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第8张图片

vue.js官网最新下载vue.js, vue.min.js

第2章 第一个实例

文件结构:

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第9张图片

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第10张图片

主要文件:

//index.cshtml 


@{
    ViewBag.Title = "Index";
    Layout = null;
}



    
    Index
    
    
    


    
Click me! Welcome to iView {{visible}} Forward

//main.js

//配置模块
require.config({
    waitSeconds: 15,
    baseUrl: './',
    paths: {
        'jquery': '/Scripts/jquery-1.10.2.min.js',
        'jqueryvalidate': '/Scripts/jquery.validate.min',
        'modernizr': '/Scripts/modernizr-2.6.2',
        'respond': '/Scripts/respond',
        'iview': '/Scripts/IView/iview.min',
        'vue': '/Scripts/vue.min',
        'BaseApp': '/Scripts/Base/BaseApp',
        'VueResource': '/Scripts/vue-resource.min',
        'less': '/Scripts/less-1.5.1.min'
    },
    shim: {
        'jqueryforval': {
            exports: 'jquery'
        },
        'jqueryvalidate': {
            exports: '$',
            deps: ['/Scripts/jquery-1.10.2', '/Scripts/jquery.validate.unobtrusive']
        },
        'vue':{
            exports: 'Vue'
        },
        'iview': {
            exports: 'iview',
            deps: ['css!/Content/Iview/iview.css','css!/Content/Iview/iviewplus.css', 'vue']
        },
        VueResource: {
            exports: 'VueResource',
            deps: ['vue']
        }
       
    },
    map: {
        '*': {
            css: '/scripts/css.min.js'
        }
    }

    ////加上时间戳
    //,urlArgs: "bust=" + (new Date()).getTime()

});



// 注册事件
require(['vue', 'iview'], function (Vue, iview) {
    Vue.use(iview);
});




//BaseApp.js

define(['vue', 'less', 'iview'], function (Vue, less, iview) {
        // 使用严格模式
    'use strict';
        var BaseApp = function () {
            return {
                Config: {},
                Instance: {},
                Run: function (appId) {
                    var self = this;
                    if (appId) {
                        self.Config.el = appId;
                    }
                    $(document).ready(function () {
                         Vue.use(iview);// 注册IView
                        self.Instance = new Vue(self.Config);
                    });
                },
                IsEmptyStr: function (str) {
                    if (!str) { str = ""; }
                    if (str.length <= 0) { return true; } else { return false; }
                },
                isEmpty: function (o) {
                    if (typeof (o) == "undefined") { return true; }
                    if (!o) { return true; }
                    if (typeof (o) == "object") {
                        for (var n in o) { return false; }
                        return true;
                    }
                    if (o instanceof Array) {
                        if (!o.length) { return true; }
                    }

                    return false;
                }
            }

        }();
        return BaseApp;
    }
    );

//index.js

define(['BaseApp'], function (BaseApp) {
    // 使用严格模式
    'use strict';
    $(function () {
        BaseApp.Config = {
            el: '#app',
            data: {
                visible: false,
                buttonSize: 'large',
                myname:'LoveLearning',
                columns1: [
                    {
                        title: 'Name',
                        key: 'name'
                    },
                    {
                        title: 'Age',
                        key: 'age'
                    },
                    {
                        title: 'Address',
                        key: 'address'
                    }
                ],
                data1: [
                    {
                        name: 'John Brown',
                        age: 18,
                        address: 'New York No. 1 Lake Park',
                        date: '2016-10-03'
                    },
                    {
                        name: 'Jim Green',
                        age: 24,
                        address: 'London No. 1 Lake Park',
                        date: '2016-10-01'
                    },
                    {
                        name: 'Joe Black',
                        age: 30,
                        address: 'Sydney No. 1 Lake Park',
                        date: '2016-10-02'
                    },
                    {
                        name: 'Jon Snow',
                        age: 26,
                        address: 'Ottawa No. 2 Lake Park',
                        date: '2016-10-04'
                    }
                ]
            },
            methods: {
                show: function () {
                    this.visible = !this.visible;
                },
                clicked: function () {
                    alert("Clicked!");
                }
            }
        };
        return BaseApp.Run();
    });


});

运行后的效果如下:

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第11张图片

这里我们已经初步完成了一个简单的IView的Demo,下一章将会将如何封装到.Net htmlhelper中。

第3章: HtmlHelper类封装UI

先说一下上次的问题,main.js引入iview会有异常,requirejs异步加载文件,执行baseapp的时候,iview可能还没引入,会出错,

所以应该搬到baseapp.js里引入。

main.js之前已经引入了iview和vue对象了, 所以只需main.js里注释这段:

 // 注册事件
require(['vue', 'iview'], function (Vue, iview) {
    Vue.use(iview);
});

1. HtmlHelper封装

     为什么要封装:主要目的还是为了高效编写代码,可以增加拓展属性或方法,使用更友好,特别对于后端开发人员来说,用代码实现更好理解。

现在,让我们正是开始实践吧

首先,在你的解决方案里, 

Asp.net web MVC5 + IVIEW + Vue.js + Require.js框架搭建_第12张图片

解决方案里是之前已经写好的,所以我就不再新建了。

首先我们创建基类及其接口:

IBase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace MvcIViewUI.BaseUI
{
    public interface IBase : IHtmlString
    {
        string GetHtml();
        T Id(string id);
        T SetRef(string _ref);
        T AddInnerUI(TInnerUI control) where TInnerUI : IBase;
       // T SetUIName(string uiName);
    }
}

Base.cs

using MvcIViewUI.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace MvcIViewUI.BaseUI
{
    public abstract class Base : IBase
    {
        protected T self;
        protected string UIName;
        protected string innerContent = "";
        protected List bindModelProps = new List();
        protected List slots = new List(); //分发到此控件的内容
        protected string htmlAttribute = "";
        protected Dictionary DefValueList = new Dictionary();
        protected string style = "";
        protected string slot = "";  //如果是嵌入的内容, 注意要设置
        protected string text = "";
        public bool isNoEndEle = false;//是否是原生无结束标志的元素
        public bool isProp = false;
        public string id { get; protected set; }
        /// 
        /// 起到定位的作用, 相当于id,注意不能重复
        /// 
        public string Ref { get; protected set; }
        public string v_model { get; protected set; }
        public string v_if { get; protected set; }
        /// 
        /// 标签文本
        /// 
        public virtual string label { get; protected set; }
        public virtual string v_for { get; protected set; }
        public virtual string key { get;protected set; }
        /// 
        /// 控件css类
        /// 
        public string cls { get; protected set; }
        public Base() {
            if (string.IsNullOrEmpty(UIName)) {
                UIName = "base";
            }
            self = (T)Convert.ChangeType(this, typeof(T));
            this.innerContent = "";
        }
        /// 
        /// 构造此对象
        /// 
        /// 分发类型
        public  Base(string slot)
        {
            this.slot = slot;
            if (string.IsNullOrEmpty(UIName))
            {
                UIName = "base";
            }
            self = (T)Convert.ChangeType(this, typeof(T));
            this.innerContent = "";
        }
        /// 
        /// 生成html内容
        /// 
        public virtual string GetHtml()
        {
            string ls_html = "", ls_propsEvnts = "";

            #region 外层部分
            //非属性
            if (!isProp)
            {
                ls_html = "<" + UIName;
            }
            if (!string.IsNullOrEmpty(id))
            {
                ls_html += " id=\"" + this.id + "\"";
            }
            if (!string.IsNullOrEmpty(this.cls)) {
                if (this.cls.StartsWith(":")) {
                    ls_html += " :class=\"" + this.cls.Substring(1, this.cls.Length-1) + "\"";
                }
                else {
                    ls_html += " class=\"" + this.cls + "\"";
                }
            }
            if (!string.IsNullOrEmpty(this.Ref))
            {
                ls_html += " ref=\"" + this.Ref + "\"";
            }
            if (!string.IsNullOrEmpty(this.slot))
            {
                ls_html += " slot=\"" + this.slot + "\"";
            }
        

            if (!string.IsNullOrEmpty(this.htmlAttribute))
            {
                ls_html += " " + this.htmlAttribute.Trim();
            }
            //:style="{
            if (!string.IsNullOrEmpty(this.style))
            {
                ls_html += " :style=\"{" + this.style.Trim() + "}\"";
            }

            ls_propsEvnts = GenPropsEvent();
            if (!string.IsNullOrEmpty(ls_propsEvnts))
            {
                ls_html += " " + ls_propsEvnts;
            }
            //作为容器使用
            if (isProp) {
                return ls_html;
            }
            if (isNoEndEle) {
                ls_html = ls_html + "/>";
            }
            else {
                ls_html = ls_html + ">";
                if (!string.IsNullOrEmpty(this.text))
                {
                    ls_html += text;
                }
            }

            #endregion

            #region The end
            if (!isNoEndEle)
            {
                if (UIName == "Upload" && string.IsNullOrEmpty(this.innerContent)) {
                    if (!string.IsNullOrEmpty(this.text)) {
                        this.innerContent = "" + this.text + "";
                    }
                    else {
                        this.innerContent = "Upload files";
                    }
                }
                if (!string.IsNullOrEmpty(this.innerContent))
                {
                    ls_html += this.innerContent;
                }
                return ls_html + "";
            }
            else {
                return ls_html;
            }
            #endregion


            
        }

        public T Id(string id)
        {
            this.id = id;return self;
        }
        public T SetRef(string _ref)
        {
            this.Ref = _ref; return self;
        }
        /// 
        /// 设置分发类型
        /// 
        /// 分发类型
        public virtual T Slot(string slot) {
            this.slot = slot;
            return self;
        }
        /// 
        /// 即设置v-if属性
        /// 
        public T If(string v_if, bool isBindModel = false) {
            if (isBindModel) { bindModelProps.Add("v_if"); }
            this.v_if = v_if;
            return self;
        }
        /// 
        /// 设置控件css样式类
        /// 
        public T Cls(string cls) {
            this.cls = cls;
            return self;
        }
        /// 
        /// 设置控件html属性,可以多个
        /// 
        public T HtmlAttribute(string htmlAttribute) {
            this.htmlAttribute = htmlAttribute;
            return self;
        }
        public string ToHtmlString()
        {
            return GetHtml();
        }

        /// 
        /// 嵌入新的控件到此控件里
        /// 
        /// 将要嵌入的控件
        public T AddInnerUI(TInnerUI control) where TInnerUI : IBase
        {
            if (";area;base;br;col;command;embed;img;hr;keygen;link;meta;param;source;track;input;wbr;".IndexOf(";" + UIName.ToLower() + ";") < 0 && control!= null)
            {
                this.innerContent += control.GetHtml();
            }
            return self;
        }
        /// 
        /// 设置嵌入的内容(html/text)
        /// 
        public T AddContent(string content) {
            if (string.IsNullOrEmpty(this.innerContent)) { this.innerContent = ""; }
            this.innerContent += content;
            return self;
        }
        /// 
        /// 设置html属性, 可以多个,例子: 'value="value1" format="yyyy年MM月dd日" type="date"'
        /// 
        /// 
        /// 
        public T HtmlAttr(string htmlAttribute)
        {
            this.htmlAttribute = htmlAttribute;
            return self;
        }
        public T BackColor(string color)
        {
            AddStyleItem("background", color);
            return self;
        }
        /// 
        /// 设置宽度
        /// 
        public T Width(int width)
        {
            AddStyleItem("width", width.ToString() + "px");
            return self;
        }
        /// 
        /// 设置宽度
        /// 
        public T Width(string width)
        {
            AddStyleItem("width", width);
            return self;
        }
        /// 
        /// 设置高度
        /// 
        public T Height(string height)
        {
            AddStyleItem("height", height);
            return self;
        }
        public T Height(int height)
        {
            AddStyleItem("height", height.ToString() + "px");
            return self;
        }
        public T Left(string left)
        {
            AddStyleItem("left", left);
            return self;
        }
        public T Left(int left)
        {
            AddStyleItem("left", left.ToString() + "px");
            return self;
        }
        public T Right(string right)
        {
            AddStyleItem("right", right);
            return self;
        }
        public T Right(int right)
        {
            AddStyleItem("right", right.ToString()+"px");
            return self;
        }
        public T Style(string styles)
        {
            if (string.IsNullOrEmpty(styles)) { return self; }
            if (styles.StartsWith(",")) { this.style = this.style + styles; }
            else
            {
                if (!string.IsNullOrEmpty(this.style))
                {
                    this.style = this.style + "," + styles;
                }
                else
                {
                    this.style = styles;
                }

            }

            return self;
        }
        /// 
        /// 使用 v-model 双向绑定数据
        /// 
        public T Model(string vModel) {
            this.v_model = vModel;return self;
        }

        #region 受保护的方法
        protected virtual void InitDefValue() {


        }
        protected virtual string GenPropsEvent()
        {
            string ls_return = "", ls_prefix = "";
            var types = self.GetType();
            var props = types.GetProperties(); //当前类的所有属性

            InitDefValue();
            foreach (var p in props)
            {
                var sList = p.CustomAttributes.ToList();
                var propName = p.Name;
                var propValue = p.GetValue(self); //p.GetValue(this);
                var propType = p.PropertyType.FullName;
                var orgPropName = propName;

                if (string.IsNullOrEmpty(propName)) { continue; }
                if (propName.Substring(0, 1) == "_") { propName = propName.Substring(1, propName.Length - 1).Trim(); }
                propName = propName.Replace("_", "-").ToLower();



                bool isEvent = false;
                foreach (var cstAttr in sList)
                {
                    //Event
                    if (cstAttr.AttributeType.FullName == "MvcIViewUI.BaseUI.EventAttribute")
                    {
                        isEvent = true;
                        break;
                    }

                }

                if (!isEvent)
                { //Prop
                    ls_prefix = "";
                    if (bindModelProps.FindIndex(m => m == orgPropName) > -1) { ls_prefix = ":"; }
                    if (propType == "System.String") {
                        propValue = propValue == null ? "" : ((string)propValue).Trim();
                        if (!string.IsNullOrEmpty((string)propValue)) {
                            if (((string)propValue).StartsWith(":")) {
                                ls_prefix = ":";
                                propValue = ((string)propValue).Substring(1, ((string)propValue).Length - 1).Trim();
                            }
                        }
                    }
                    if (!string.IsNullOrEmpty(ls_prefix))//绑定了模型
                    {
                        ls_return += " " + ls_prefix + propName + "=\"" + (string)propValue + "\"";
                    }
                    else if (propType == "System.Boolean")
                    {
                        if (DefValueList.ContainsKey(orgPropName))
                        {
                            if ((bool)DefValueList[orgPropName] == (bool)propValue)
                            {
                                continue;
                            }
                        }
                        if ((bool)propValue)
                        {
                            ls_return += " " + propName;
                        }
                        else
                        {
                            ls_return += " " + ls_prefix + propName + "=\"false\"";
                        }
                    }
                    else if (propType == "System.DateTime")
                    {
                        if (DefValueList.ContainsKey(orgPropName))
                        {
                            if (Convert.ToDateTime(DefValueList[orgPropName]) == Convert.ToDateTime(propValue))
                            {
                                continue;
                            }
                        }
                        if (Convert.ToDateTime(propValue) != null)
                        {
                            ls_return += " :" + propName + "=\"new Date('" + Convert.ToDateTime(propValue).ToString("yyyy-MM-dd hh:mm:ss") + "')\"";
                        }
                    }
                    else if (propType == "System.Int32")
                    {
                        if (DefValueList.ContainsKey(orgPropName))
                        {
                            if ((int)DefValueList[orgPropName] == (int)propValue)
                            {
                                continue;
                            }
                        }
                        if ((int)propValue > 0)
                        {
                            ls_return += " " + ls_prefix + propName + "=\"" + propValue.ToString() + "\"";
                        }
                    }
                    else if (propType == "System.String")
                    {
                        if (DefValueList.ContainsKey(orgPropName))
                        {
                            if ((string)DefValueList[orgPropName] == (string)propValue)
                            {
                                continue;
                            }
                        }
                        if (!string.IsNullOrEmpty((string)propValue))
                        {
                            ls_return += " " + ls_prefix + propName + "=\"" + (string)propValue + "\"";
                        }
                    }
                    else
                    {
                        if (DefValueList.ContainsKey(orgPropName))
                        {
                            if (DefValueList[orgPropName] == propValue)
                            {
                                continue;
                            }
                        }
                        if (propValue != null)
                        {
                            ls_return += " " + ls_prefix + propName + "=\"" + (string)propValue + "\"";
                        }
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty((string)propValue))
                    {
                        ls_return += " @" + propName + "=\"" + (string)propValue + "\"";
                    }
                }




            }


            return ls_return;
        }

        protected void AddStyleItem(string styleItem, string value)
        {
            if (string.IsNullOrEmpty(styleItem) || string.IsNullOrEmpty(value)) { return; }
            if (!string.IsNullOrEmpty(this.style))
            {
                this.style += ", " + styleItem + ": '" + value + "'";
            }
            else
            {
                this.style = styleItem + ": '" + value + "'";
            }
        }
        protected T SetUIName(string uiName)
        {
            this.UIName = uiName;
            return self;

        }

        #endregion

    }
}

2.创建第一个Asp.net Mvc UI, 以Button为例:

先在项目中新建"UI"文件夹, 这里要用来存放我们要封装的UI,然后创建

Button.cs

using MvcIViewUI.BaseUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace MvcIViewUI.UI
{
    public class Button : Base

 

3.创建UI存储库类MvcIViewUIRsp,所有的UI都通过仓库输出,可以加个接口约束:

using MvcIViewUI.BaseUI;
using MvcIViewUI.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;


namespace MvcIViewUI.UIRsp
{
    public interface IMvcIViewUIRsp
    {
        MvcHtmlString BaseAppUrl(string url);
        T ParseUI(T uiControl) where T : IBase;
        Button UIButton();

    }
}

MvcIViewUIRsp.cs

using MvcIViewUI.BaseUI;
using MvcIViewUI.Chart;
using MvcIViewUI.ContainerUI;
using MvcIViewUI.ExtendUI;
using MvcIViewUI.NavUI;
using MvcIViewUI.UI;
using MvcIViewUI.ViewUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;


namespace MvcIViewUI.UIRsp
{
    public class MvcIViewUIRsp : IMvcIViewUIRsp
    {
        /// 
        /// 加载应用程序核心js文件
        /// 
        /// js文件路径
        public MvcHtmlString BaseAppUrl(string url)
        {
            string sScript = "";
            if (string.IsNullOrEmpty(url)) { url = ""; }
            sScript = "";
            return new MvcHtmlString(sScript);
        }

      

        /// 
        /// 手动解析UI
        /// 
        /// 
        public T ParseUI(T uiControl) where T : IBase
        {
            return uiControl;
        }

        public Button UIButton() {
            return new Button();
        }
        public Button UIButton(string text, string icon = "", string slot = "")
        {
            return new Button(text, icon, slot);
        }
       
    }
}

4.将UI库挂载到HtmlHelper静态类中

在项目中创建静态类:UIHelper,

using MvcIViewUI.UIRsp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace MvcIViewUI
{
    public static class UIHelper
    {
        public static MvcIViewUIRsp IView(this HtmlHelper helper)
        {
            return new MvcIViewUIRsp();
        }

    }
}

5.编写cshtml页面

@using MvcIViewUI
@{
    ViewBag.Title = "firstapp";
}

@Html.IView().BaseAppUrl("../../Scripts/App/Home/firstapp")


Scripts/App/Home/firstapp.js

define(['BaseApp'], function (BaseApp) {
    // 使用严格模式
    'use strict';

    $(function () {
        BaseApp.Config = {
            el: '#testapp',
            data: {
            },
            methods: {
                ue_test: function () {
                  alert("Tested!");
                }
            }
        };

        return BaseApp.Run();
    });


});

运行后,就可以看到效果了。

你可能感兴趣的:(Web开发)