【问题标题】:Vue + Asp.net rendering issueVue + Asp.net 渲染问题
【发布时间】:2019-12-21 03:02:08
【问题描述】:

我有一个新的 asp.net mvc 项目(不是 .net 核心),我正在尝试将 Vue js 合并到项目中。我在使用 Webpack+Vue+Asp.Net Mvc 的示例项目中完成了所有工作,该项目是在这篇文章 https://medium.com/corebuild-software/vue-js-and-net-mvc-b5cede228626 之后创建的。

该应用程序运行良好,除了 Vue 渲染前的瞬间。 Vue 模板代码在呈现为 html 之前有明显的闪烁/弹出。下面是我刷新页面的 gif,用户可以在 Vue 将其渲染为 html 之前看到模板。

我知道为什么会发生这种情况,但我不知道任何解决方法。服务器端渲染会解决这个问题吗? SSR 可以在非 .net 核心项目中完成吗?

不幸的是,切换到 asp.net 核心不是一种选择。该项目将使用 Umbraco 7,它无法在 asp.net core (https://our.umbraco.com/forum/using-umbraco-and-getting-started/93640-net-core) 上运行。

以下是我的文件

索引.cshtml

@{
    ViewBag.Title = "Home Page";
}

<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
</div>

<div id="app" controller-data="{ name: 'James' }">
    <h3>Test</h3>
    {{ vueMessage }}
    {{ controllerData }}
    <first-component v-bind:time="new Date()" data="@Model"></first-component>
    <button v-on:click="test">Test</button>
</div>

<div class="row">
    <div class="col-md-4">
        <h2>Getting started</h2>
        <p>
            ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
            enables a clean separation of concerns and gives you full control over markup
            for enjoyable, agile development.
        </p>
        <p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p>
    </div>
    <div class="col-md-4">
        <h2>Get more libraries</h2>
        <p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
        <p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more &raquo;</a></p>
    </div>
    <div class="col-md-4">
        <h2>Web Hosting</h2>
        <p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
        <p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more &raquo;</a></p>
    </div>
</div>

@Scripts.Render("~/Scripts/bundle/home.js")

index.js(被 webpack 编译成 Scripts/bundle/home.js)

import Vue from 'vue';
import FirstComponent from './sub-components/first-component.vue'

new Vue({
    el: '#app',
    components: {
        FirstComponent
    },
    props: {
        controllerData: Object
    },
    methods: {
        test: function () {
            console.log(this);
        }
    },
    data: function () {
        return {
            vueMessage: 'Message from Vue'
        };
    }
})

first-component.vue

<template>
    <div class="time">
        {{ time }}
        {{ data }}
    </div>
</template>
<script>
    export default {
        props: {
            time: {
                type: Object,
                required: true,
            },
            data: Object
        }
    }
</script>
<style>
    .time {
        color: #F44336;
    }
</style>

【问题讨论】:

    标签: asp.net-mvc vue.js


    【解决方案1】:

    切换到 .net 核心或任何其他服务器端技术都无济于事。

    问题是因为 html 在浏览器下载时以及在所有脚本资源下载/解析/运行并从 Vue 组件渲染 html 之前由浏览器渲染。

    在处理混合渲染(​​部分服务器端和部分客户端)时,最好的选择是默认隐藏模板并在 vue 组件设置并准备好后“显示”它。

    例如,在您的服务器端视图中,使用属性、样式或类隐藏&lt;div id="app"&gt;

    <style>#app.loading {display:none;}</style>
    <div id="app" v-bind:class="{ loading: !isloaded }">
    

    然后在你的vue组件中mounted方法设置isLoaded为true。这只是在组件准备好之前隐藏组件的众多方法之一。

    【讨论】:

    • 我有点惊讶 SSR 根本没有帮助。据我了解,MVC 和 Vue 组件都将在服务器端正确呈现?这将使用户看到提供的完全呈现的 MVC 和 Vue 组件。
    • 当然,您可以使用嵌入到 MVC 应用程序中的 Vue 服务器端渲染,但是您为什么要开始使用 Vue?您已经拥有 MVC Razor 来呈现服务器端。客户端渲染的主要好处之一是您将处理转移到客户端以释放服务器并在理想情况下通过更少的 html 传输来减少带宽。
    • 我们正试图通过使用 react 来摆脱 jquery
    【解决方案2】:

    利用v-cloak 属性。

    <div id="app" v-cloak>
    ...
    </div>
    

    当框架完成挂载时,该属性会被 vue 自动删除。

    v-cloack 属性不会显示或隐藏您的元素 - 它基本上是一个指示安装是否完成的标记。您编写一个 css 选择器来定位 v-cloack 以隐藏元素或显示加载指示。

    <style>
        [v-cloak] > * { display:none }
        [v-cloak]::before { content: "Please wait…" } 
    </style>
    

    【讨论】:

    • 根据我的研究,这是最好的答案,谢谢:)
    猜你喜欢
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 2018-03-08
    相关资源
    最近更新 更多