Intro
Vue is rapidly becoming one of the most popular JavaScript frameworks for building user interfaces. Vue 3 can be used as the UI for a Sitecore MVC website (i.e., not headless). Still, a few configuration gotchas need to be addressed, and a general strategy for working with your markup needs to be implemented.
There are also some significant differences in implementing Vue 3 in a .NET application like Sitecore, as opposed to Vue 2. Let’s get started using Vue 3 with Sitecore MVC!
Getting Vue 3 Set Up
These steps assume you’re working with an existing Sitecore MVC implementation. If you don’t have a working instance, you can always try Vue out on one of the demo sites available in the Sitecore GitHub repositories (you will need a valid Sitecore license, of course).
The first step to using Let’s get started using Sitecore MVC with Vue 3 is installing the necessary packages for Vue, including the means to compile, load, and bundle all of your Vue components. There are a lot of options here, but at a minimum, you will want Vue (again, we’re focusing on Vue 3 here), a package to load Vue, load your SaSS/ CSS, and some way to compile and bundle your Vue components.
The goal here is to set up a working combination of Vue 3 within a Sitecore .NET application, so we’re going to keep it simple and only include the essentials. First, let’s add a bundler by running the following command in a terminal:
Prerequisites
The main assumption here is that you have an existing Sitecore instance. You also most likely have an existing front-end setup (and therefore already have npm/ yarn and a package.json file). If not, install the node and run npm init
. Alternatively, you can use yarn by running yarn init
.
Install packages for Vue 3
Get started by installing our bundler as a dev dependency. Here I am using the most recent release of Parcel (at the time of writing, version 2.7.0). Webpack is another good option but takes a bit more effort in the configuration department.
npm install parcel --save-dev
or
yarn add parcel --dev
Next, we want to install Vue and a few associated loaders to help us make use of JavaScript and CSS in our single file components (SFCs).
npm install vue
npm install vue-loader vue-template-compiler vue-style-loader css-loader --save-dev
or
yarn add vue
yarn add vue-loader vue-template-compiler vue-style-loader css-loader --dev
Create your component
You can begin by selecting any Sitecore rendering and extending the UI to use Vue. For this post, we’re choosing a simple example of a Sitecore rendering for a Heading with a headline and subheadline field.
Update Razor view markup
Whatever rendering you’re using to incorporate Vue and extend the UI, you will want to have an identifier (you can use a class or a tag name not already established). You will also want to use properties to pass data from the razor view to your view component.
@using Sitecore.Mvc @model HeadingRenderingModel <div @Html.Sxa().Component("heading-component", Model.Attributes)> @if (!String.IsNullOrWhiteSpace(Model.ErrorMessage)) { <div class="error-message"> @Model.ErrorMessage </div> } else { <!-- Vue template --> <heading-component headline="@Html.Sitecore().Field(Templates.Heading.FieldNames.Heading)" subhadline="@Html.Sitecore().Field(Templates.Heading.FieldNames.Subheadline)" </heading-component> } </div>
Create a simple SFC Vue component
Here we’re creating a Vue SFC called heading-component.vue. It contains a template that will display our Sitecore fields, some basic JavaScript to declare the properties for the Sitecore fields, and some simple CSS to style the component.
<template> <p class="heading-component__wrapper"> <div class="heading-component__headline">{{ headline }}</div> <div class="heading-component__subheadline">{{ subheadline }}</div> </p> </template> <script> import { ref, watch } from 'vue'; export default { name: 'HeadingComponent', props: { headline: { type: String, dault: '', required: true }, subheadline: { type: String, default: '', required: false } }, setup(props) { // TODO: do some stuff if you want } } </script> <style> .heading-component__wrapper { font-family: sans-serif; } .heading-component__headline { font-size: 2rem; font-weight: 600; } .heading-component__subheading { font-size: 1.125rem; } </style>
Wire up your Vue 3 component
Mount up
In Vue 2, when mounting an application with a template
the rendered content replaces the element we mount to. In Vue 3, the rendered application is appended as a child of such an element, replacing the innerHTML
.
To create a root and mount your component as a child to the root, you create an app.js file and add the following code.
import { createApp } from 'vue'; import Heading from './Components/scripts/heading-component.vue'; // Creates root Vue app and adds Heading Component createApp({ components: { HeadingComponent } }).mount('.heading-component');
Add an alias
The preceding setup would allow us to use Vue components in our application. Still, the data from Sitecore (via the razor view) would not be passed via the attributes we used (headline and subheadline) without specifying an alias. We need to take control of the import of Vue and force the use of the ES module. This is not well documented, but several blog posts on the web reference this required step in using Vue with a .NET MVC application.
Webpack has an alias property, but Parcel is “configuration-less,” so it will require updating the package.json file with our alias. Interestingly, the NPM docs don’t list alias
as an official property of the package.json file, but the Parcel official documentation does recommend configuring the alias this way, so it should be safe.
"alias": { "vue": "vue/dist/vue.runtime.esm-bundler.js" }
Conclusion
Adding Vue 3 has some gotchas, especially if you’re familiar with how to work with Vue 2 in the context of a Sitecore MVC website. If you’re having trouble or running into issues, make sure you are mounting your component as a child of the root app and that you have an alias configured that your bundler can recognize.