2

I have a new asp.net mvc project (not .net core) and I am trying to incorporate Vue js into the project. I have everything working in a sample project using Webpack+Vue+Asp.Net Mvc, which was created following this article https://medium.com/corebuild-software/vue-js-and-net-mvc-b5cede228626.

The app works great, except for the split second before Vue renders. There is noticable flashing/popping of the Vue templated code before its rendered to html. Below is a gif of me refreshing the page and users are able to see the template before Vue renders it into html.

enter image description here

I know why this is happening, but I do not know any ways around it. Would Server Side Rendering fix this? Can SSR be done in a non .net core project?

Unfortunately, switching to asp.net core is not an option. The project will be using Umbraco 7, which cannot run on asp.net core (https://our.umbraco.com/forum/using-umbraco-and-getting-started/93640-net-core).

Below are my files

Index.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 (gets compiled to Scripts/bundle/home.js by webpack)

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>
1
  • How did you get Vue to maintain ASP HTML? i can't find any solution to that Commented Oct 29, 2023 at 15:22

2 Answers 2

4

Make use of the v-cloak attribute.

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

The attribute is automatically removed by vue when the framework has finished mounting.

The v-cloack attribute does not show or hide your elements - it is basically a marker that indicates if mounting is finished. You write a css selector to target v-cloack to hide the elements or show a loading indicatior.

<style>
    [v-cloak] > * { display:none }
    [v-cloak]::before { content: "Please wait…" } 
</style>
Sign up to request clarification or add additional context in comments.

1 Comment

Based on my research this is the best answer, thank you :)
0

Switching to .net core or any other server side technology would not help.

The issue is because the html is rendered by the browser as it downloads & before all the script resources have downloaded/parsed/run & rendered the html from the Vue component.

When dealing with mixed rendering (partially server side & partially client side) your best option is to hide the template by default & "show" it once the vue component is setup & ready.

For example in your server side view, hide <div id="app"> either with an attribute, style or class.

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

Then in your vue component mounted method set isLoaded to true. This is just one of many ways to hide the component before it's ready.

3 Comments

I am a bit surprised SSR wouldn't help at all. As I understood it, the MVC and Vue components would both be rendered server side correct? Which would leave the user seeing the fully rendered MVC and Vue component that is served.
Sure, you CAN use Vue server-side-rendering embedded withing an MVC application but then why would you want to use Vue to begin with? You already have MVC Razor to render server-side. One of the main benefits of client side rendering is you shift processing to the client to free-up the server & ideally reduce bandwidth with less html being transferred.
We are trying to get away from jquery by using react instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.