vue.js.net-corerazorrazor-pagesunpkg

How to use a Vue component from an external library (for example Vue Cal) in a .NET Core Razor Page?


Hello dear people of Stack Overflow.

I am currently playing around with the combination of .NET Core Razor Pages and the VueJS JavaScript framework. I would like to use the Vue Cal library to display a calendar view on my Razor Page.

For simplicity I am pulling Vue from a CDN in the _Layout.cshtml file as most tutorials suggest, so I figured I could also pull in Vue Cal like this. The head tag of my _Layout.cshtml looks as follows:

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorVue</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorVue.styles.css" asp-append-version="true" />
    <link rel="manifest" href="/manifest.json" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
    <script src="https://unpkg.com/axios@0.2.1/dist/axios.min.js"></script>
    <script src="https://unpkg.com/vue-cal"></script>
    <link href="https://unpkg.com/vue-cal/dist/vuecal.css" rel="stylesheet">
</head>

My question now is, how do I go on to use the Vue Cal component in one of my Razor pages? I have tried it as follows, but the calendar won't show:

@page
@model RazorVue.Pages.CalendarModel
@{
}

<div id="calendar">
    <vue-cal style="height: 250px" />
</div>

 @section Scripts {
     <script src="https://unpkg.com/vue-cal"></script>

     <script type="text/javascript">
         Vue.createApp({
             components: { VueCal: vuecal }
         }).mount('#calendar')
     </script>
 }

My knowledge of both Razor Pages and Vue is still quite limited so I would appreciate it if you guys could help me out with this issue. It doesn't have to be Vue Cal specifically, I just want to learn how to use component libraries in this context. Thanks in advance :-)

EDIT: I changed the Razor Page code above and for clarity, I'll post my full _Layout.cshtml below:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorVue</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/RazorVue.styles.css" asp-append-version="true" />
    <link rel="manifest" href="/manifest.json" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
    <script src="https://unpkg.com/axios@0.2.1/dist/axios.min.js"></script>
    <script src="https://unpkg.com/vue-cal"></script>
    <link href="https://unpkg.com/vue-cal/dist/vuecal.css" rel="stylesheet">
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">RazorVue</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Counter">Counter</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/CatFacts">Cat facts</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Calendar">Calendar</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2023 - RazorVue - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

    <script>
    // Check that service workers are supported
    if ('serviceWorker' in navigator) {
        // Use the window load event to keep the page load performant
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('/sw.js');
        });
    }
</script>

Solution

  • Here is the simplest way.

    You will need to put your Vue App in the Script Section.

    In the _Layout.cshtml file there should be a Script Section defined:

     @RenderSection("Scripts", required: false)
    

    or async

    @await RenderSectionAsync("Scripts", required: false)
    

    And on your Razor Page

    You can also put the Vue Cal script tag directly to your Razor Page, if you don't want to load it on every page of your web application.

    @section Scripts {
      <script src="https://unpkg.com/vue-cal"></script>
    ....
    

    There are also other ways to achieve the same result. But at the end you will need to load some JavaScript file on your Razor Page where is your Vue App stored.