为什么混合使用 Razor Pages 和 VueJs 是一件坏事?

新手上路,请多包涵

我正在尝试使用 Razor Pages 设置一个 .NET 核心项目,并在 Razor 页面中包含 vueJs 以用于我的所有逻辑。

是这样的:

 @{
    ViewData["Title"] = "VueJs With Razor";
}
<h2>@ViewData["Title"].</h2>

<div id="app">
   <span>{{ message }}</span>
</div>

<script>
     new Vue({
        el: '#app',
        data: {
          message : 'Hello vue.js'
        }
    })
</script>

我读到混合 Vue 和 Razor 页面是一种不好的做法,应该使用 Razor 或 Vue。

为什么是这样?

原文由 Joel Pinto Ribeiro 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

你可以这样做。有时你不得不这样做,如果像我们一样,你正在迁移一个现有的代码库并且你不能一次转换所有的东西。正如 Ron C 所说,它运作良好。

如果您要开始一个新项目,您可以自由选择。支持 SPA 而没有 Razor 的原因是……

  • 反应性。 SPA 应用程序通常感觉(更)更具反应性。初始渲染通常在数据到达之前从缓存中提供。在第一次加载时,所有资源都以一个请求-响应的形式捆绑在一起。没有或更少有请求链接。

  • 工作流程。 Webpack、捆绑和热重载都很棒。你得到生产构建,缩小,编译 Vue 渲染函数,消除 404 样式错误,捕获 js 语法错误。对于许多错误,从引入错误到发现错误的周期大大缩短。

  • 温泉宇宙。路由,Vuex,这真的是未来的方式。

  • 纯度。 Razor 和 Vue 在一天结束时做类似的事情。如果混合使用它们,您可能很难保持头脑清醒。

原文由 bbsimonbb 发布,翻译遵循 CC BY-SA 3.0 许可协议

混合 VueJs 和 Razor Pages 不一定是坏事,它可以很棒!

我将 Vue 与 razor 一起用于非 SPA 页面,两者可以很好地协同工作。我选择通过 CDN 的脚本标签加载 Vue 来使用它,并且我没有利用 WebPack 进行转译,我只是在 (gasp) ES5 中编写我的代码。我出于以下原因选择了这种方法。

  • 使用 Razor 页面而不是 SPA 有助于 SEO 和面向公众的页面的搜索引擎排名。
  • 直接从 CDN 加载 Vue 消除了学习曲线中的一整套以 Webpack 为中心的技术,这使得新开发人员更容易上手该系统。
  • 该方法仍然为 UI 开发提供了响应式优点,而 Vue 固有地为表格带来了这种优点。
  • 通过保持“页面模型”,提供站点功能的代码在逻辑上围绕提供该功能的后端页面进行分组。

由于 Vue 和 Razor 可以做很多相同的事情,我对面向公众的页面的目标是使用 Razor 生成尽可能接近最终的 html,并使用 Vue 向页面添加反应性。这为通过解析返回的 HTML 索引页面的爬虫提供了巨大的 SEO 好处。

我意识到我对 Vue 的使用与走 SPA 和 WebPack 的路线完全不同,这种方法通常意味着我不能在不稍微修改代码的情况下使用第 3 方 Vue 组件。但该方法简化了软件架构并提供了轻量级的反应式 UI。

通过使用这种方法,可以充分利用 Razor 来生成带有一些包含 vue 属性的标记的 HTML 的初始呈现。然后在浏览器中加载页面后,Vue 接管并可以以任何需要的方式重新配置该页面。

显然,这种方法不能满足所有开发人员或项目的需求,但对于某些用例来说,这是一个非常好的设置。

为感兴趣的人提供更多详细信息

由于我在全站范围内使用 vue,我的全局 _layout.aspx 文件负责实例化 vue。在 vue 中实现的任何站点范围的功能都是在这个级别实现的。许多页面都有页面特定的 vue 功能,这是作为该页面上的 mixin 或该页面加载的 js 文件中的 mixin 实现的。当 _layout.aspx 页面实例化 Vue 时,它会使用我已注册到全局 mixin 数组的所有 mixin。 (页面将它的 mixin 推送到那个全局 mixin 数组)

我不使用 .vue 文件。任何需要的组件都直接在页面上实现,或者如果它们需要被多个页面使用,那么它们将在如下所示的局部视图中实现:

dlogViewComponent.cshtml :

     @* dlog vue component template*@
    <script type="text/x-template" id="dlogTemplate">
        <div class="dlog" v-show="dlog.visible" v-on:click="dlog.closeBoxVisible ? close() : ''">
            <div class="dlogCell">
                <div class="dlogFrame" @@click.stop="" style="max-width:400px">
                    <i class="icon icon-close-thin-custom dlogCloseIcon" v-if="dlog.closeBoxVisible" @@click="close()"></i>
                    <div class="dlogCloseIconSpace" v-if="dlog.closeBoxVisible"></div>
                    <div class="dlogInner">
                        <div class="dlogTitle" style="float:left" v-text="title"></div>
                        <div class="clear"></div>
                        <div class="dlogContent">
                            <slot></slot>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </script>

    @* Vue dlog component *@
    <script type="text/javascript">
            Vue.component('dlog', {
                template: '#dlogTemplate',
                props: {    //don't mutate these!
                    closeBoxVisible: true,
                    title: 'One'
                },
                data: function () {
                    return {
                        dlog: { //nest the data props below dlog so I can use same names as cooresponding prop
                            closeBoxVisible: (typeof this.closeBoxVisible === 'undefined') ? true : (this.closeBoxVisible == 'true'),
                            title: (typeof this.title === 'undefined') ? '' : this.title,
                            visible: false
                        }
                    }
                },
                methods: {
                    //opens the dialog
                    open: function () {
                        app.hideBusy();        //just in case, no harm if not busy
                        this.dlog.visible = true;
                        var identifyingClass = this.getIdentifyingClass();
                        Vue.nextTick(function () {
                            $("." + identifyingClass).addClass("animateIn");
                            fx.manageDlogOnly();
                        });
                    },
                    //closes the dialog
                    close: function () {
                        fx.prepDlogClose();
                        var identifyingClass = this.getIdentifyingClass();
                        this.dlog.visible = false;
                        $("." + identifyingClass).removeClass("animateIn");
                    },
                    getIdentifyingClass: function () {
                        if (this.$el.classList.length > 1) {
                            //the last class is always our identifying css class.
                            return this.$el.classList[this.$el.classList.length - 1];
                        } else {
                            throw "A dialog must have an identifying class assigned to it.";
                        }
                    }

                }
            });
    </script>

在上面,它是 Vue.component(‘dlog’, … 安装组件并使其可用于页面的 js 部分。

_layout.cshtml 页面上的 vue 代码类似于下面的代码。通过在整个站点使用的 _layout.cshtml 上实例化 Vue,Vue 仅在站点范围内的一个地方实例化:

_layout.cshtml :

  <script type="text/javascript">
    var app = new Vue({
        el: '#appTemplate',
        mixins: mixinArray,                     //The page adds it's mixin to mixinArray before this part of the layout executes.
        data: {
            errorMsg: ''                        //used sitewide for error messages
            //other data used sitewide
        },
        methods: {
            //methods that need to be available in vue sitewide, examples below:
            showBusy: function (html) {
                //functionality to show the user that the site is busy with an ajax request.
            },
            hideBusy: function () {
                //functionality to hide the busy spinner and messaging
            }
        },
        created: function () {
             //this method is particularly useful for initializing data.
        }
    });

</script>

我在这里提供的内容非常清楚地描绘了这种非传统方法及其优势。不过,既然有几个人问过,我也写了一篇相关的博文: Using VueJs with ASP.NET Razor Can Be Great!

原文由 RonC 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题