[技巧]C#Razor框架与vue.js和ElementUI的融合

2021/3/24 21:11:26

本文主要是介绍[技巧]C#Razor框架与vue.js和ElementUI的融合,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

开发背景:

最近,领导找我去维护公司里面最古老的项目。由C# MVC框架搭建而成,前后端一起开发,前端由jQuery加一些表单和上传插件开发而成,因为前端写,后端也写,导致代码很乱,一般人不敢去动他。
但是!在这个前后端分离的时代,显然这套框架已经过时了。不说别的,现在一些年纪轻的前端估计都不会jQuery。讲真,我也不想写jQuery.......😥

那怎么办呢,得,想办法改造吧!


改造前:

  • 第一步:问同事,查资料。得知这个项目基于C# Razor框架开发🚩官方通道。
  • 哦吼,刀锋,和摩托罗拉某款手机型号同名。
  • 第二步:了解MVC工作原理(Model+View+Controller),现在大家喜欢吹的MVVM,早期就是由MVC演变而来,对于正经前端来说,MVC理解起来不难。
  • 第三步:看框架,Views+Controllers两个文件夹是核心。

页面渲染的形式,比如 xxx.com/My/Index 通过My找到相应Controller,然后再通过Index找到对应的方法及return View(Model),而这里的Model会传给ViewsViews就可以直接用Model,可能也可以操作Controller吧,这里就不多做介绍了,毕竟我只是前端。

  • 到此,弄明白了完整的M V C 模 型
// /Controllers/MyController.cs
namespace XXX.Web.Controllers{
  public class MyController : BaseController
  {
    #region 构造函数
    public MyController(){
      // todo something
    }

    public ActionResult Index(){
      // 从数据库获取用户
      var userid = LoginContext.Current.UserID;
      var model = _TB_UserService.Get(userid);
      // 这里把model传给view
      return View(model);
    }
  }
}
 // /Views/My/Index.cshtml
 @using xxx
 @model TB_User
 @{
  // 配置母板
  Layout = "~/Views/Master/_UCLayout.cshtml";
  ViewBag.Title = "用户中心";
  // 处理model
  var UserName = Model.UserName;
 }
 <style></style>
 <div class="UserName">
   用户名:@UserName
 </div>
  <script type="text/javascript">
    $(function(){
      console.log($('.UserName').text(),"@UserName");
      // todo ajax ....
    })
  </script>
// /Views/Master/_UCLayout.cshtml
@using xxx
@{
  var user = LoginContext.Current;
  // todo something 
}

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" href="xxx/global.css?v=@Utils.GetValue("version")" />
    <script src="xxxx/jQuery.js?v=@Utils.GetValue("version")"></script>
</head>
<body>
  @Html.Partial("_Header")
  <div class="Layout">
    <!-- 菜单权限 -->
    <div class="Menu">
      @if (user.IsCa){
        <div class="Item">
          <a href="/Order/CW">财务菜单</a>
        </div>
      }
      @if (user.UserType == "Person"){
        <div class="Item">
          <a href="/UserCenter/Person">工作台</a>
        </div>
      }
      @if (user.UserType == "Company"){
        <div class="Item">
          <a href="/UserCenter/Company">工作台</a>
        </div>
      }
    </div>
    <div class="Content">
      @RenderBody()
    </div>
  </div>
  @Html.Partial("_Footer")
</body>
</html>
  • 以上就是Razor框架的实现流程。

改造难点:

  1. jQuery要与vue共存,webpack脚手架肯定不可能,那就只能从cdn安装入手。
  2. 如果页面上要用el-containerel-asideel-menuel-submenuel-main,那么 _UCLayout.cshtml就必须要用Vue加载。
  3. 如果把子页面作为组件,通过Vue.component('xxx',{}) 载入,那新增的需要import到_UCLayout.cshtml中,太麻烦了。
  4. @在Razor框架中属于关键字,页面上用@click,会出现异常。
  5. ★★★ 不能影响现有的功能和页面!

改造思路:

方向肯定是:Vue写的母板内嵌Vue写的子页
翻遍了官网文档,脑子浮现一个词:Mixins
灵感往往来自一瞬间🤩
var subApp = {
  data(){
    return {}
  },
  methods:{

  }
}
var rootApp = new Vue({
  el:'#parent',
  mixins:[subApp]
})

改造实施:

  • 菜单用ElementUI,那就必须先改_UCLayout.cshtml
// /Views/Master/_UCLayoutVue.cshtml
@using xxx
@{
  var user = LoginContext.Current;
  // todo something 
}

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" href="xxx/global.css?v=@Utils.GetValue("version")" />
    + <link rel="stylesheet" href="xxx/ElementUI.css?v=@Utils.GetValue("version")" />
    <script src="xxxx/jQuery.js?v=@Utils.GetValue("version")"></script>

    + <script src="xxxx/Vue.js?v=@Utils.GetValue("version")"></script>
    + <script src="xxxx/ElementUI.js?v=@Utils.GetValue("version")"></script>
    + <style>
        [v-cloak]{ display: none; }
      </style>
    + <script type="text/javascript">
        // 核心代码,暂定数组,Header,Footer等都可以混入
        var mixinArray = [];
      </script>
</head>
<body>
  @Html.Partial("_Header")
  <el-container class="Layout" id="rootApp" v-cloak>
    <!-- 菜单权限 -->
    <el-aside width="200px">
        <el-menu class="Menu" :default-active="activeIndex">
          @if (user.IsCa){
              <a href="/Order/CW">
                  <el-menu-item class="Item">
                    财务菜单
                  </el-menu-item>
              </a>
          }
          @if (user.UserType == "Person"){
              <a href="/UserCenter/Person">
                  <el-menu-item class="Item" index="MYINDEX">
                    工作台
                  </el-menu-item>
              </a>
          }
          @if (user.UserType == "Company"){
              <a href="/UserCenter/Company">
                  <el-menu-item class="Item" index="MYINDEX">
                    工作台
                  </el-menu-item>
              </a>
          }
        </el-menu>
    </el-aside>
    <el-main class="Content">
      @RenderBody()
    </el-main>
  </el-container>
  @Html.Partial("_Footer")
  <script type="text/javascript">
    var rootApp = new Vue({
     el:'#rootApp',
     data(){
       return {
        activeIndex:'MYINDEX',
         // ...
       }
     },
     mixins:mixinArray
    })
  </script>
</body>
</html>
  • 子页如果要用vue,那必须不能 var subapp = new Vue();
// /Views/My/IndexVue.cshtml
 @using xxx
 @model TB_User
 @{
  // 配置母板
  Layout = "~/Views/Master/_UCLayoutVue.cshtml";
  ViewBag.Title = "用户中心";
  // 处理model
  var UserName = Model.UserName;
 }
 <style></style>
 <div class="UserName">
   后端用户名:@UserName
   前端用户名:{{ UserName }}
   <el-button type="primary" @@click="ChangeName">改名</el-button>
 </div>
  <script type="text/javascript">
    var subApp = {
      data(){
        return {
          UserName:'@UserName',  // 可设为后端返回的
          toggle:false,
        }
      },
      mounted(){
        // 打印rootApp,全局vue实例
        console.log(rootApp.activeIndex);  // 'MYINDEX'
        console.log($('.UserName').text()); // 正常打印
      },
      methods:{
        ChangeName(){
          if(!this.toggle){
            this.UserName = '***';
          }else{
            this.UserName = '@UserName';  // 前后端可互通了,完美 
          }
          this.toggle = !this.toggle;
        }
      }
    }
    mixinArray.push(subApp);
  </script>

改造完成:

优点:既对其他页面没影响,又可以愉快的使用vue开发(新的页面)。
缺点:只能使用cdn模式安装。
后期也可以把其他组件作为混入对象。
兼容IE的话,请加入Babel和Polyfill。
致敬经典,Razor框架很强!❤

如果对你有所帮助,请随手点个赞,Coding不易~❤



这篇关于[技巧]C#Razor框架与vue.js和ElementUI的融合的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程