6

I'm trying to implement an external template (creating an HTML page), but I can not succeed. This page is a ASP.NET MVC page that contains a Vue app.

I want to move the template section of this component to an external file, but whenever I do this it doesn't work.

The following (below) does work, but it's not easy to maintain or build upon due to loss of text editing features.

Vue.component('my-component', { template: '#my-component' }

This is the current code and it works perfectly:

var foo = Vue.component('foo', {
template:'
<table class="table">
 <template v-for="(foo, ColName, index) in foos">
    <template v-if="index % 3 == 0">
        <tr>
        </tr>
    </template>
    <th>{{ColName}}</th>
    <td v-if="foo">{{foo}}</td>
    <td v-else> -- </td>
 </template>
</table>',
data: function () { 
  return {
    foos: null,
    NumColuns: 3 
  }
}, 
mounted() { 
 axios
  .get('/api/account/foo/')
  .then(response => {
    this.foos = response.data                
   })
  .catch(error => {
    console.log(error1)
      this.errored = true
  })
  .finally(() => this.loading = false)
}
});
var foo = new Vue({ 
  el: '#foo-vue' 
});
3
  • #my-component means the template is inside the HTML on that page. From your explanation it isn’t clear if the Vue code is on that page or some other file or what exactly. Could you clarify exactly what file has what in them? Commented Jun 28, 2019 at 18:25
  • I think he has everything in one JS file, including the template and he's referencing that from a HTML page. he wants to have the template in a separate file. Commented Jul 2, 2019 at 21:16
  • All my code is on the JS page, and I would like to separate it to an HTML page (template). Commented Jul 3, 2019 at 21:19

3 Answers 3

3
+25

To fetch the HTML template from a file you need a async component.

Documentation: https://v2.vuejs.org/v2/guide/components-dynamic-async.html

In your example fetch the HTML and return the promise in the Vue.component factory.

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <script src="https://unpkg.com/vue"></script>
</head>

<body>

  <div id="app">
    <foo></foo>
  </div>

  <script>
    var foo = Vue.component('foo', () => {
      return fetch('/template.html')
        .then((response) => response.text())
        .then((html) => {
          return {
            template: html,
            data: function () {
              return { foos: null, NumColuns: 3 }
            },
            mounted() {
              this.foos = [{ foo: 1, ColName: "A" }];
              //  axios.get('/api/account/foo/').then(response => {
              //     this.foos = response.data
              //    })
              //   .finally(() => this.loading = false)
            }
          };
        });
    });
    var foo = new Vue({
      el: '#app'
    });
  </script>
</body>

</html>

template.html

<table class="table">
 <template v-for="(foo, ColName, index) in foos">
    <template v-if="index % 3 == 0">
        <tr>
        </tr>
    </template>
    <th>{{ColName}}</th>
    <td v-if="foo">{{foo}}</td>
    <td v-else> -- </td>
 </template>
</table>
Sign up to request clarification or add additional context in comments.

1 Comment

is there no way to import it the way Vue documentation has for .vue files?
2

The best thing you can do is configure an entire Vue project, so you can use .vue template files. I recently found an article that explains in detail how to achieve this, but it's specifically aimed at browser extensions. The steps you have to undertake to achieve it, in this case, are identical for the most part, so I'll just link the article here anyway: https://medium.com/javascript-in-plain-english/how-i-built-a-browser-extension-with-vue-part-2-2c4ab2dd752d.

Basically what's happening is, you'll configure the Vue project yourself with Webpack to compile the Vue files into one app.js file, which you'll then reference in your file (in the tutorial this file is his app.html). It will then inject its components into the #app element and handle all virtual DOM manipulations.

Comments

2

If your view is a razor .cshtml template then you can just extract your template to a html file and load that file to your ASP.NET MVC view as raw html code since Vue template is valid html:

<!-- in cshtml view -->
<script id="my-component" type="text/x-template">
    @Html.Raw(File.ReadAllText(Server.MapPath("~/Path/To/Template/my-component-template.html")))
</script>

And in your Vue component it should work with template: '#my-component' as you mentioned.

Docs: Vue: Edge Cases

P.S. You can prepare a partial view for your components or create some extension method to make code more readable and add some caching.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.