Asp.net+Vue+EmelentUI的实现(五)全局组件的注册 - Go语言中文社区

Asp.net+Vue+EmelentUI的实现(五)全局组件的注册


Vue注册全局组件,只要直接注册即可,代码如下

Vue.component('name', {
    props: [],
    template:' '
})

如果我们生成一个vue-comment.js的JS文件,并且通过PageBase的自动加载方式来加载,那么就可以实现自动载入了。在PageBase的载入默认JS的地方,加入载入vue-component.js的代码,新代码如下

 /// <summary>
        /// 添加默认的js
        /// </summary>
        private void AddDefaultJs()
        {
            //vue-js
            AddJs("vue.js", "/Scripts/vue.js", "/Scripts/vue.min.js");

            //vue-resource.js
            AddJs("vue-resource.js", "/Scripts/vue-resource.js", "/Scripts/vue-resource.min.js");

            //element-ui.js
            AddJs("element-ui.js", "/Scripts/ElementUI/element-ui.js", "/Scripts/ElementUI/element-ui.js");

            //vue-component.js
            AddJs("vue-component.js", "/Scripts/vue-component.js", "/Scripts/vue-component.js");

            //kit.js
            AddJs("kit.js", "/Scripts/kit.js", "/Scripts/kit.js");

            //global.js
            AddJs("/Scripts/global.js", "/Scripts/global.js", "/Scripts/global.js");

        }

有了vue-component.js,那么载入了该JS后,Vue组件就实现了全局注册,但这时又碰到了一个问题,就是这个JS的内容要如何生成?当然了,如果是直接编译vue-component.js文件是可行的,但是在写template的时候,由于是使用字符串的拼接,很容易出错,如果能像vue组件的编写方式一样,编写一个xxx.vue组件,然后通过编译生成到vue-component.js中,那就会方便很多。但我们采用的是Asp.Net模式来开发,没有使用nodejs、webpack来编译打包,所以不能按照常见的加载相关的模块来编译打包,为此,写了一个简易的VueEngine来编译。

VueEngine是一个控制台程序,代码如下

    class Program
    {
        static void Main(string[] args)
        {
            var dir = getParentDir(AppDomain.CurrentDomain.BaseDirectory);
            string componentsPath = dir + @"Components";
            if (!Directory.Exists(componentsPath))
            {
                Console.WriteLine("找不到路径 " + componentsPath);
                return;
            }
            string vue_component_js = dir + @"Scriptsvue-component.js";
            StreamWriter streamWriter = null;

            try
            {
                streamWriter = new StreamWriter(vue_component_js, false, Encoding.UTF8);
                var files = Directory.GetFiles(componentsPath, "*.vue");
                if (files == null || files.Length <= 0)
                {
                    Console.WriteLine("没有文件");
                }
                else
                {
                    var spaces = "    ";
                    foreach (var filePath in files)
                    {
                        StreamReader streamReader = new StreamReader(filePath, Encoding.UTF8);
                        bool isTemplateBegin = false;
                        bool isScriptBegin = false;
                        bool isScriptEnd = false;
                        List<string> templateLines = new List<string>();
                        List<string> scriptLines = new List<string>();
                        while (!streamReader.EndOfStream)
                        {
                            var line = streamReader.ReadLine();
                            if (string.IsNullOrWhiteSpace(line))
                            {
                                continue;
                            }

                            if (!isTemplateBegin && line.Trim().Equals("<template>"))
                            {
                                isTemplateBegin = true;
                            }
                            else if (line.Trim().Equals("<script>"))
                            {
                                isScriptBegin = true;
                            }
                            else if (line.Trim().Equals("</script>"))
                            {
                                isScriptEnd = true;
                            }

                            if (isTemplateBegin && !isScriptBegin)
                            {
                                templateLines.Add(line);
                            }

                            if (isScriptBegin)
                            {
                                scriptLines.Add(line);
                            }

                            if (isScriptEnd)
                            {
                                break;
                            }
                        }

                        if (templateLines.Count > 1)
                        {
                            templateLines.RemoveAt(0);//移除<template>
                            templateLines.RemoveAt(templateLines.Count - 1);//移除</template>
                        }

                        if (scriptLines.Count > 1)
                        {
                            scriptLines.RemoveAt(0);//移除<script>
                            scriptLines.RemoveAt(0);//移除 var exports =
                            scriptLines.RemoveAt(0);//移除 {
                            scriptLines.RemoveAt(scriptLines.Count - 1);//移除</script>
                            scriptLines.RemoveAt(scriptLines.Count - 1);//移除};
                        }
                        //输出组件名
                        streamWriter.WriteLine("//"+Path.GetFileName(filePath));
                        var nameLine = scriptLines[0];
                        var componentName = nameLine.Substring(scriptLines[0].IndexOf(":") + 1).Replace("'", "").Replace(",", "").Trim();
                        streamWriter.WriteLine($"Vue.component('{componentName}', {{");
                        scriptLines.RemoveAt(0);//移除name行
                        //输出data props methods等
                        for (int i = 0; i < scriptLines.Count; i++)
                        {
                            var suffix = (i == scriptLines.Count - 1 ? "," : "");
                            var scriptLine = scriptLines[0];
                            if (i == 0)
                            {
                                scriptLine = spaces + scriptLine.TrimStart();
                            }
                            streamWriter.WriteLine(scriptLine + suffix);
                        }
                        //输出template
                        for (int i = 0; i < templateLines.Count; i++)
                        {
                            var prefix = (i == 0 ? (spaces + "template:'") : "");
                            var suffix = (i == templateLines.Count - 1 ? "'" : @"");
                            streamWriter.WriteLine(prefix + templateLines[i] + suffix);
                        }
                        streamWriter.WriteLine("})");
                        streamWriter.WriteLine();//添加一行空行,便于与其他组件区分
                    }
                }
                streamWriter.Close();
            }
            catch (Exception ex)
            {
                if (streamWriter != null)
                {
                    streamWriter.Close();
                }
                Console.WriteLine("异常=>" + ex.Message);
            }
        }

        /// <summary>
        /// 获取上一级目录
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        private static string getParentDir(string dir)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(dir);
            return directoryInfo.Parent.FullName;
        }
    }

代码的主要逻辑是众Components文件夹下读取所有的.vue后缀的文件,然后对文件分析,提取出template作为Vue组件注册的template,然后将Script部分作为props等,生成vue-component.js文件到Scripts文件夹下。为了便于解析,我们对原有的vue组件的script定义方式略作了调整,其格式如下

<template>
    <div>
        //组件内容
    </div>
</template>

<script>
    var exports =
    {
        name: 'xxx',
        props: ['x1', 'x2']
    };
</script>

为了便于编译,template的开始和结束标记固定占一行,script的开始和结束标记固定占一行,script后的一行固定为var exports=,“{”和“};”固定占一行。

有了VueEngine后,我们将其输出到AspNetVueElementUI项目下的VueEngine文件夹,这个需要在VueEngine项目下作设定,对配置的Debug和Release都设置相同的输出路径。

这样设定之后,VueEngine项目编译的时候,会自动生成到AspNetVueElementUI项目下。

有了VueEngine.exe,那么我们只要在AspNetVueElementUI项目编译前先编译VueEngine,并且调用VueEngine.exe,就可在达成目的了。为了让VueEngine先编译,我们要将VueEngine项目设定为AspNetVueElementUI的依赖项。在解决方案上右键,选择属性来设置,如下图

经过这样的设定之后,AspNetVueElementUI编译的时候就会先编译VueEngine。那我们在AspNetVueElementUI项目上右键,选择属性来设定,在【生成事件】的生成前事件命令行输入 ..VueEngineVueEngine.exe,如下图

这时再编译AspNetVueElementUI项目就会将Components文件夹下的*.vue编译到vue-component.js下。比如我们在Components添加一个MenuTree.vue

<template>
    <div>
        <template v-for="m in menus">
            <el-submenu :index="m.id" :key="m.id" v-if="m.children&&m.children.length>0">
                <template slot="title">
                    <i :class="m.iconClass"></i>
                    <span slot="title">{{ m.name }}</span>
                </template>
                <menu-tree :menus="m.children" :click="click"></menu-tree>
            </el-submenu>
            <el-menu-item v-else :index="m.id" :key="m.id" @click="click(m.url)">
                <i :class="m.iconClass"></i>
                <span slot="title">{{ m.name }}</span>
            </el-menu-item>
        </template>
    </div>
</template>

<script>
    var exports =
    {
        name: 'menu-tree',
        props: ['menus', 'click']
    };
</script>

然后编译AspNetVueElementUI项目,MenuTree.vue已经生成到vue-component.js中,代码如下

//MenuTree.vue
Vue.component('menu-tree', {
    props: ['menus', 'click'],
    template:'    <div>
        <template v-for="m in menus">
            <el-submenu :index="m.id" :key="m.id" v-if="m.children&&m.children.length>0">
                <template slot="title">
                    <i :class="m.iconClass"></i>
                    <span slot="title">{{ m.name }}</span>
                </template>
                <menu-tree :menus="m.children" :click="click"></menu-tree>
            </el-submenu>
            <el-menu-item v-else :index="m.id" :key="m.id" @click="click(m.url)">
                <i :class="m.iconClass"></i>
                <span slot="title">{{ m.name }}</span>
            </el-menu-item>
        </template>
    </div>'
})

注意:每行后面的斜扛“”是换行转义符,如果不加有的浏览器会报错。

现在我们修改default.aspx生成菜单的部分,代码如下

 <el-container class="container">
                <el-aside class="left">
                    <el-menu>
                        <menu-tree :menus="menus" :click="open"></menu-tree>                  
                    </el-menu>
                </el-aside>
                <el-main class="right">
                    <iframe style="width:100%; height:100%; border: 0;" :src="iframeUrl"></iframe>
                </el-main>
            </el-container>

利用MenuTree.vue组件生成的菜单如下

源码下载

转载请注明出处。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xxdddail/article/details/90051250
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 11:14:34
  • 阅读 ( 1105 )
  • 分类:前端

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢