如何將 Vue 與 ASP.NET Razor 一起使用
TLDR
- 在 ASP.NET Razor Pages 中整合 Vue 2,建議透過
_Layout.cshtml統一初始化 Vue 實例,並利用mixins擴充各頁面的邏輯。 - 為了避免「未編譯模板閃現」,務必使用
v-cloak指令並配合 CSS 設定。 - Vue 模板內禁止放置
<script>標籤,否則會觸發編譯錯誤。 - 在 Razor Pages 中使用 Vue 語法時,若遇到
@符號(如@click),需使用@@進行跳脫,且在 Tag Helper 屬性中應避免使用 Vue 的@簡寫。 - 處理 Ajax 請求時,需透過
axios的interceptors自動注入RequestVerificationToken以通過 Antiforgery 驗證。 - 若需保留 ASP.NET 的 Model Validation,可透過自定義
TagHelper將後端驗證屬性轉換為VeeValidate所需的 HTML 屬性。
Vue 與 Razor 的整合架構
在 ASP.NET Razor Pages 中整合 Vue,核心概念是將 Vue 的生命週期與 Razor 的頁面結構結合。建議將 Vue 實例的初始化放在 _Layout.cshtml,並利用 Vue 的 mixins 功能,讓各個頁面(.cshtml)能夠注入各自的資料與方法。
實作方式
- 在
_Layout.cshtml中定義一個全域的mixins陣列。 - 頁面透過
@section Scripts將該頁面專屬的pageMixin推入mixins陣列。 - 最後在
_Layout.cshtml底部統一執行new Vue({ el: '#vueApp', mixins: mixins })。
避免閃現問題
什麼情況下會遇到:頁面載入初期,瀏覽器尚未解析 Vue 模板,導致使用者看到原始的 語法。
- 解決方案:在根元素加上
v-cloak,並在 CSS 中設定[v-cloak] { display: none; }。
整合注意事項
模板限制
什麼情況下會遇到:在 Vue 渲染的 DOM 範圍內直接撰寫 <script> 標籤。
- 踩雷紀錄:Vue 模板僅負責 UI 映射,不允許包含具有副作用的標籤。
- 建議做法:將所有 JavaScript 邏輯移至
@section Scripts區塊中。
Razor 與 Vue 語法衝突
什麼情況下會遇到:在 Razor Pages 中使用 Vue 的 @ 簡寫(如 @click)。
- 原因分析:
@是 Razor 的保留字,且 Tag Helper 屬性對特殊字元有嚴格限制。 - 建議做法:
- 一般 HTML 屬性使用
@@click跳脫。 - 若該元素包含
asp-for等 Tag Helper,應避免使用@簡寫,改用v-on:click以確保編譯正確。
- 一般 HTML 屬性使用
取代 jQuery 的替代方案
Ajax 與安全性
什麼情況下會遇到:使用 axios 發送 POST 請求時,因缺少 RequestVerificationToken 導致 400 Bad Request。
- 建議做法:在
axios的interceptors中攔截請求,並從頁面隱藏欄位中讀取 Token 加入 Header:
javascript
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);
}
);前端驗證整合
什麼情況下會遇到:希望保留 ASP.NET 的 Validation Attributes(如 [Required]),同時在前端使用 VeeValidate 進行即時驗證。
- 建議做法:建立自定義
TagHelper,自動將後端 Model 的驗證規則轉換為v-validate屬性。
VeeValidationInputTagHelper 範例: 此 TagHelper 會自動讀取 asp-for 的 Metadata,並產生對應的 v-validate 規則。
csharp
// 簡化版邏輯,將後端 Attribute 轉為 VeeValidate 規則
if (For.Metadata.ValidatorMetadata.Any(x => x is RequiredAttribute)) {
output.Attributes.Add("v-validate", "'required'");
}VeeValidationMessageTagHelper 範例: 用於顯示錯誤訊息:
csharp
public override void Process(TagHelperContext context, TagHelperOutput output) {
output.Attributes.Add("v-show", $"errors.has('{For.Name}')");
output.Content.SetHtmlContent($"{{{{ errors.first('{For.Name}') }}}}");
}異動歷程
- 2022-10-24 初版文件建立。
