Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Vue.js, is there a way to keep component templates out of JavaScript strings?

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>\
  ',
......
like image 829
Christopher Shroba Avatar asked Jan 23 '17 05:01

Christopher Shroba


People also ask

What is interpolation in VUE JS?

The most basic form of Vue interpolation is text interpolation. It's simply the process of displaying a string that's defined within your component logic.

How do I use a Vue template in JavaScript?

We need to prefix the src with v-bind:src = ”imgsrc” and the name of the variable with src. Following is the output in the browser. Let us inspect and check how the src looks like with v-bind. As seen in the above screenshot, the src is assigned without any vuejs properties to it.

How do I use Vue component template?

To create a SFC you first create a . vue file, e.g. Checkbox. vue, then define your template in a template tag and define the component in a script tag. This file then gets imported into your main Vue app.

How do I add external js scripts to Vuejs components?

Add a script tag inside your Vue component template. This is the easy fix I have found. Just add the script into the component template. But don't forget to add, type="application/javascript" to the script tag otherwise it will show an error during the build. However, if you have added document.


2 Answers

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.

like image 68
Saurabh Avatar answered Oct 07 '22 11:10

Saurabh


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

like image 45
CodinCat Avatar answered Oct 07 '22 11:10

CodinCat