Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I just worked through the Guide on Vue.js's website, and I have a bad feeling about templates for components. It seems strange to me that they are specified in strings; sure, maybe this works for very short templates, but once you get to multiline templates, you need to start escaping your new lines and it just feels wrong to have html in javascript strings to begin with. Not to mention that syntax highlighting or any other nice IDE features are useless with HTML in JS strings.

Two alternatives that are detailed in the docs are using inline templates, or X-templates, but both of these options are discouraged.

The only other alternative seems to be Single File Components, which seems like a good option, but they are in the Advanced section and in the docs, it is said that for small and medium sized apps, simply using Vue.component should be enough. Furthermore, Single File Components look like they're more difficult to integrate into a project, requiring tapping into the project's build system (the docs talk about Webpack and Browserify).

So I'm confused. Do I just need to accept that my component code is going to look as messy as this example, pulled straight from the docs?

Vue.component('currency-input', {
  template: '\
    <span>\
      $\
      <input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)"\
      >\
    </span>\
  ',
......
share|improve this question
    
Do you want to use Vue with some existing project or are you creating a new project? – Saurabh yesterday
    
I'm doing a new project. Why do you ask? – Christopher Shroba yesterday
1  
You can use X-templates, they are discouraged only because, they separate templates from the rest of the component definition, but if that is what you want, then it is perfectly fine. – Mathew Jibin yesterday
    
It's not so much that that's what I want. Rather, I'm skeptical that the masses of people who use vue.js are all writing long templates in multiline JavaScript strings. Am I missing another alternative that most people are doing? – Christopher Shroba yesterday
1  
It depends on architecture and the toolchain we use. In some apps, architecture requires the template be separate and independent so that it can be swapped and modifiable without touching the code or by someone who does not code, where x-templates are fine. Some others have integrated toolchains which helps in using single page components. Depends on project size, ide and other tools, people that works with the components and such mostly. – Mathew Jibin yesterday
up vote 6 down vote accepted

Given that you are starting a new project, you can use vue-hackernews-2.0 as boilerplate, where you see lot of components already coded with webpack integration for both dev and prod env. This is also developed by core vue team and recommended in official docs.

You can see there are different files for each component and one component looks like following having clear separation of HTML, JS and CSS part:

<template>
  <li v-if="comment" class="comment">
    <div class="by">
      <router-link :to="'/user/' + comment.by">{{ comment.by }}</router-link>
      {{ comment.time | timeAgo }} ago
    </div>
    <div class="text" v-html="comment.text"></div>
    <div class="toggle" :class="{ open }" v-if="comment.kids && comment.kids.length">
      <a @click="open = !open">{{
        open
            ? '[-]'
            : '[+] ' + pluralize(comment.kids.length) + ' collapsed'
      }}</a>
    </div>
    <ul class="comment-children" v-show="open">
      <comment v-for="id in comment.kids" :id="id"></comment>
    </ul>
  </li>
</template>

<script>
export default {
  name: 'comment',
  props: ['id'],
  data () {
    return {
      open: true
    }
  },
  computed: {
    comment () {
      return this.$store.state.items[this.id]
    }
  },
  methods: {
    pluralize: n => n + (n === 1 ? ' reply' : ' replies')
  }
}
</script>

<style lang="stylus">
.comment-children
  .comment-children
    margin-left 1.5em
.comment
  border-top 1px solid #eee
  position relative
  .by, .text, .toggle
    font-size .9em
    margin 1em 0
  .by
    color #999
    a
      color #999
      text-decoration underline
  .text
    overflow-wrap break-word
    a:hover
      color #ff6600
    pre
      white-space pre-wrap
  .toggle
    background-color #fffbf2
    padding .3em .5em
    border-radius 4px
    a
      color #999
      cursor pointer
    &.open
      padding 0
      background-color transparent
      margin-bottom -0.5em
</style>

This uses webpack for build and adds working config as well which I myself am using in production without any issue.

share|improve this answer
    
Looks like the OP doesn't want to use SFC. Possibly because of Webpack or Browserify? Although I don't think it's a big problem. – Leo yesterday
    
@Leo That may be the case, but the vue-hackernews-2.0 provides all the config, which can help OP if setup is an issue, – Saurabh yesterday
    
Thanks so much for your response!! Looks like SFC isn't as complex as I thought. I appreciate the advice! – Christopher Shroba 17 hours ago
1  
@ChristopherShroba SFC is my personal favorite way of developing vue applications. But you need some knowledges of webpack (or browserify) too, because it relies on a pre-bundling process. As mentioned, vue-hackernews-2.0 and official vue-cli templates are very good learning examples. – Leo 7 hours ago

From my experiences, if the template is very short, use inline mode is OK. If not, x-template also allows you to get rid of escaping line breaks. I don't see why you think these approaches are discouraged. Can you provide more information?

However, if you insist to embed long template inline, you can still do that without escaping. The answer is ES6 template literals - string wrapped within ``:

template: `
  <span>
    $
    <input
      ref="input"
      v-bind:value="value"
      v-on:input="updateValue($event.target.value)"
    >
  </span>
`,

On the other hand, I really think vue-cli is a great tool. Webpack is something worth learning.

share|improve this answer
    
Thanks for your response! In the docs about X-templates and Inline templates, the last paragraph of each discourages their use. Regarding Inline templates: "However, inline-template makes the scope of your templates harder to reason about. As a best practice, prefer defining templates inside the component using the template option or in a template element in a .vue file.", and regarding X-templates: "These can be useful for demos with large templates or in extremely small applications, but should otherwise be avoided, because they separate templates from the rest of the component definition." – Christopher Shroba 17 hours ago
    
@ChristopherShroba I see them as suggestions to choose proper approach depending on your use case, rather than discouraging. So what is your use case? That's what matters. – Leo 7 hours ago

You can use <template>...</template> or <script type="text/x-template">...</script>, and specify the selector in template attribute for that.

<template id="myComponent">
  <div>
    <h1>Hello!</h1>
    <p><slot></slot></p>
  </div>
</template>


Vue.component('myComponent', {
  template: '#myComponent'
})

Simple working example here: http://codepen.io/anon/pen/dNWrZG?editors=1010

Also, the build process of single file components is not that difficult. You can check the webpack-simple template: https://github.com/vuejs-templates/webpack-simple, the vue-loader will do everything for you.

Once you feel comfortable with webpack, you can take a look at the full webpack template: https://github.com/vuejs-templates/webpack

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.