How to use Vue with ASP.NET Razor
TLDR
- For integrating Vue 2 into ASP.NET Razor Pages, it is recommended to initialize the Vue instance globally in
_Layout.cshtmland usemixinsto extend logic for individual pages. - To avoid "Flash of Uncompiled Content," always use the
v-cloakdirective combined with CSS settings. <script>tags are prohibited within Vue templates, as they will trigger compilation errors.- When using Vue syntax in Razor Pages, if you encounter the
@symbol (e.g.,@click), you must use@@to escape it. Additionally, avoid using Vue's@shorthand within Tag Helper attributes. - When handling Ajax requests, use
axiosinterceptorsto automatically inject theRequestVerificationTokento pass Antiforgery validation. - If you need to retain ASP.NET Model Validation, you can use a custom
TagHelperto convert backend validation attributes into the HTML attributes required byVeeValidate.
Integration Architecture for Vue and Razor
The core concept of integrating Vue into ASP.NET Razor Pages is to combine Vue's lifecycle with the Razor page structure. It is recommended to place the initialization of the Vue instance in _Layout.cshtml and utilize Vue's mixins feature, allowing individual pages (.cshtml) to inject their own data and methods.
Implementation
- Define a global
mixinsarray in_Layout.cshtml. - Pages push their specific
pageMixininto themixinsarray via@section Scripts. - Finally, execute
new Vue({ el: '#vueApp', mixins: mixins })at the bottom of_Layout.cshtml.
Avoiding Flash of Uncompiled Content
When does this occur: During the initial page load, before the browser has parsed the Vue template, causing the user to see raw syntax.
- Solution: Add
v-cloakto the root element and set[v-cloak] { display: none; }in your CSS.
Integration Notes
Template Limitations
When does this occur: Writing <script> tags directly within the DOM scope rendered by Vue.
- Pitfall: Vue templates are only responsible for UI mapping and do not allow tags with side effects.
- Recommended practice: Move all JavaScript logic to the
@section Scriptsblock.
Razor and Vue Syntax Conflicts
When does this occur: Using Vue's @ shorthand (e.g., @click) in Razor Pages.
- Analysis:
@is a reserved character in Razor, and Tag Helper attributes have strict limitations on special characters. - Recommended practice:
- Use
@@clickto escape for standard HTML attributes. - If the element contains Tag Helpers like
asp-for, avoid the@shorthand and usev-on:clickinstead to ensure correct compilation.
- Use
Alternatives to jQuery
Ajax and Security
When does this occur: Sending a POST request using axios results in a 400 Bad Request due to a missing RequestVerificationToken.
- Recommended practice: Intercept requests in
axiosinterceptorsand read the token from the hidden field on the page to add it to the header:
axios.interceptors.request.use(
config => {
let token = document.querySelector('input[name="__RequestVerificationToken"]');
if (token !== null) {
config.headers = {
RequestVerificationToken: token.value
}
}
return config;
},
error => {
return Promise.reject(error);
}
);Frontend Validation Integration
When does this occur: You want to retain ASP.NET Validation Attributes (e.g., [Required]) while using VeeValidate for real-time validation on the frontend.
- Recommended practice: Create a custom
TagHelperto automatically convert backend Model validation rules intov-validateattributes.
VeeValidationInputTagHelper Example: This TagHelper automatically reads the asp-for Metadata and generates the corresponding v-validate rules.
// Simplified logic to convert backend Attribute to VeeValidate rules
if (For.Metadata.ValidatorMetadata.Any(x => x is RequiredAttribute)) {
output.Attributes.Add("v-validate", "'required'");
}VeeValidationMessageTagHelper Example: Used to display error messages:
public override void Process(TagHelperContext context, TagHelperOutput output) {
output.Attributes.Add("v-show", $"errors.has('{For.Name}')");
output.Content.SetHtmlContent($"{{{{ errors.first('{For.Name}') }}}}");
}Change Log
- 2022-10-24 Initial documentation created.
