如何在我的 .cshtml 页面中调用 Vue 组件?

Posted

技术标签:

【中文标题】如何在我的 .cshtml 页面中调用 Vue 组件?【英文标题】:How to call Vue components in my .cshtml pages? 【发布时间】:2019-10-11 04:33:54 【问题描述】:

我有一个与 Vue.js 结合使用的 ASP.NET Core MVC 项目。我只使用 Vue.js 使我的页面具有响应性。我的目标是基于 _layout.cshtml 文件中的 div 创建一个主 vue 实例,然后使用 X-Templates 创建 Vue 组件并在我的 Web 应用程序中使用它们。值得一提的是,我希望在自己的 .js 文件中包含 JS Vue.Component() 逻辑,因为其中一些组件将具有大量的 js 逻辑。

我遇到的问题是,当我从我想使用它们的 .cshtml 调用它们时,让 Vue 注册/识别我的组件。我发现这个 *** 帖子 link 显示了应该如何使这个工作的逻辑,但他的例子显示了 cshtml 中的 JS 逻辑,这是我试图避免的,并且没有关于如何调用 vue 组件的示例从另一个页面。

我得到的错误是...... [Vue warn] 无法挂载组件:模板或渲染函数未定义

技术栈:

ASP.NET Core MVC (2.2) Vue.js (2.6.10) Vue 模板编译器 (2.6.10) Vue-loader (15.7.0) Axios(0.18.0) Babel/Core (7.4.4) Babel/polyfill (7.0.0) WebPack (4.26.0)

这是我的主要 _layout.cshtml

    <div id="main-app">
     @RenderBody() 
    </div> 
@section Scripts 
    <script src="@Url.Content("~/js/mainVueApp.js")"></script>


这是我的 mainVueApp.js

 import Vue from 'vue';
    import myComponent from 'testComponent';

        new Vue(
         el: 'main-app',
         components: 
            myComponent 
            // I also tried, thisIsMyComponent: myComponent. No luck with that either.
          
       );

这是我的 _vueTestComponent.csthml

    @model TestViewModel 

        <script type="text/x-template" id="my-test-component-id">
                <div class="card">
                    <div class="card-header"> My Test Header </div>

                    <div class="card-body">
                           <table class="table"> 
                             <thead> 
                                  <tr> 
                                     <th class="pull-right">
                                       Test Header 
                                     </th>
                                  </tr>
                             </thead>

                             <tbody>
                                <tr v-if="isShowRow"> 
                                     <th class="pull-right">
                                       Test Header AGAIN 
                                     </th>

                                     <tr class="pull-right">
                                         @(Html.Kendo.CurrencyTextBoxFor(m => 
                 m.TestProperty).HtmlAttributes(new Dictionary<string, object>
                                 "id", "test-text-box",
                                 "class", "textbox-input",
                                 "v-model", "testTextBoxValue"
                                 ).Deferred()
                                 )
                                     </tr>
                                  </tr>
                             </tbody>
                           </table>
                     </div>
                </div>
            </script>
@section Scripts 
        <script src="@Url.Content("~/js/testComponent.js")"></script>

    

这是我的 testComponent.js

import Vue from 'vue';
import axios from 'axios';

let testComponent = Vue.Component('my-component', 
    template: 'my-test-component-id',
    data: function()           
       return 
      testTextBoxValue : 'Test Value',
      isShowRow: true
     

   ,
    methods: 
    // Nothing for now....
 
);

//I tried it without default, but it doesn't work either :(
export default 
testComponent 
;

这是我调用组件TestViewForVue.cshtml的视图

<div class="row"> 
  <div class="col-12">
      @* Call the Component *@
      @* Do I need to load the .cshtml where this component lives first, as a partial view or something? *@
       <my-component> </my-component>
  </div>
</div>

【问题讨论】:

这是一个长答案,但长话短说 cshtml 文件和 razor 与 vue.js 无关。您很可能需要创建一个 REST api,Vue 将从其中提取数据或将 json 对象公开给 vue 我已经在我的新 Vue() 实例中测试了 axios,我可以从我的 API 中取回数据并将其呈现在 _layout.cshtml 上。但是,我的目标是创建 vue 组件并在我的 UI(在其他 .cshtml 页面内)呈现这些组件。不完全确定,您的评论是什么意思。 【参考方案1】:

这会稍微改变你的结构(不使用脚本 x-template 语法),但它对我有用。如果可以,请尝试一下。

由于您想重用此组件,因此在您的情况下全局注册它可能是可以的。

此处使用模板文字,因此需要确保为 IE11 正确转译

// testComponent.js

Vue.component("my-component", 
  template: `
        <div class="card">
          <div class="card-header"> My Test Header </div>
        </div>
      `,
  data () 
    return 
  ,
  // ...
)

然后在您的 App_Start/BundleConfig.cs 中,为您的全局组件创建一个捆绑包,并在您的 _layout.cshtml 渲染脚本上渲染该捆绑包。

// BundleConfig.cs

public static void RegisterBundles(BundleCollection bundles)

  bundles.Add(new ScriptBundle("~/bundles/vuecomponents").Include(
    "~/Scripts/VueComponents/testComponent.js"
  ));

// _layout.cshtml

@Scripts.Render("~/bundles/vuecomponents")

现在您应该可以在应用中的任何 .cshtml 页面上包含 &lt;my-component /&gt;

【讨论】:

你认为可以在cshtml文件中而不是js文件中包含HTML吗?我希望将 HTML 放在 JS 文件之外。但是,我仍然会尝试这种可能的解决方案并报告我的发现。谢谢! @AdrianCruz 这可能是可能的,但我没有给出那个镜头,抱歉。告诉我^_^

以上是关于如何在我的 .cshtml 页面中调用 Vue 组件?的主要内容,如果未能解决你的问题,请参考以下文章

使用剃须刀页面调用服务器方法而无需重新加载页面

每个插入 cshtml 页面都会出现相同的错误

模型不会从剃刀页面中的 _Layout.cshtml 页面中的 _Footer.cshtml 部分视图绑定

我应该在我的 .NET 6 项目中混合 .cshtml 文件和 .razor 文件吗?

当期望值不在视图包中时重定向到登录页面

从数据库中提取 pdf 并将其显示在我的 cshtml 上