简体   繁体   English

在 Vue.js 中,有没有办法让组件模板远离 JavaScript 字符串?

[英]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.我刚刚浏览了 Vue.js 网站上的指南,我对组件的模板有一种不好的感觉。 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.当然,也许这适用于非常短的模板,但是一旦您使用多行模板,您就需要开始转义您的新行,并且在开始时在 javascript 字符串中包含 html 感觉是错误的。 Not to mention that syntax highlighting or any other nice IDE features are useless with HTML in JS strings.更不用说语法高亮或任何其他不错的 IDE 功能对 JS 字符串中的 HTML 毫无用处。

Two alternatives that are detailed in the docs are using inline templates , or X-templates , but both of these options are discouraged.文档中详述的两个替代方案是使用 内联模板X-templates ,但不鼓励使用这两个选项。

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.唯一的其他选择似乎是Single File Components ,这似乎是一个不错的选择,但它们在Advanced部分和文档中,据说对于中小型应用程序,只需使用Vue.component就足够了。 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).此外,单文件组件看起来更难集成到项目中,需要利用项目的构建系统(文档谈论 Webpack 和 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>\
  ',
......

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.鉴于您正在开始一个新项目,您可以使用vue-hackernews-2.0作为样板,您可以在其中看到许多组件已经通过 webpack 集成为 dev 和 prod env 进行了编码。 This is also developed by core vue team and recommended in official docs .这也是由核心 vue 团队开发并在官方文档中推荐的。

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:您可以看到每个组件都有不同的文件,一个组件看起来像下面的 HTML、JS 和 CSS 部分清晰分离:

<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.这使用 webpack 进行构建并添加了我自己在生产中使用的工作 配置,没有任何问题。

You can use <template>...</template> or <script type="text/x-template">...</script> , and specify the selector in template attribute for that.您可以使用<template>...</template><script type="text/x-template">...</script> ,并为此在template属性中指定选择器。

<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这里的简单工作示例: 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.您可以查看webpack-simple vue-loaderhttps ://github.com/vuejs-templates/webpack-simple,vue-loader 将为您完成所有工作。

Once you feel comfortable with webpack, you can take a look at the full webpack template: https://github.com/vuejs-templates/webpack一旦您对 webpack 感到满意,您可以查看完整的 webpack 模板: https ://github.com/vuejs-templates/webpack

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.如果没有, x-template还允许您摆脱转义换行符。 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 `` :答案是 ES6 模板文字- 包裹在``中的字符串:

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.另一方面,我真的认为 vue-cli 是一个很棒的工具。 Webpack is something worth learning. Webpack 是值得学习的东西。

This is not really a direct answer (It's editor Specific) but i just thought i should share, but if you're using Visual Studio Code as your editor, Then you can keep your templates as part of your component and still get Syntax highlighting.这不是一个真正的直接答案(它是特定于编辑器的),但我只是认为我应该分享,但如果您使用 Visual Studio Code 作为您的编辑器,那么您可以将模板保留为组件的一部分,并且仍然可以突出显示语法。

Thanks to this awesome extension angular-2-inline感谢这个很棒的扩展angular-2-inline

It was Originally meant for Angular 2, but it works for all ES6 Template strings ( Provided the key of Template String is "template ").它最初是为 Angular 2 设计的,但它适用于所有 ES6 模板字符串(假设模板字符串的键是“模板”)。

Single File components are the Recommended way, but they can become a burden when you're not building a Full-fledged SPA and you're just using Vue to enhance some HTML templates Here and there, and you don't want to get Involved with Webpack.单个文件组件是推荐的方式,但是当你没有构建一个成熟的 SPA 并且你只是在到处使用 Vue 来增强一些 HTML 模板并且你不想参与时,它们可能会成为一种负担使用 Webpack。

Don't believe it?不相信? I'm currently using it.我目前正在使用它。

在此处输入图像描述

Thanks to @danidee answer I was able to track an Atom extension to properly do syntax highlighting for "backticked" HTML strings.感谢@danidee 的回答,我能够跟踪 Atom 扩展以正确地对“反引号”HTML 字符串进行语法突出显示。 However as he indicates it will only work when the template is declared inside the very component definition (and I want to separate template in another .js file).但是,正如他指出的那样,它仅在模板在组件定义中声明时才有效(并且我想在另一个 .js 文件中分隔模板)。 So I did this and it's a more ellegant solution, I think:所以我这样做了,我认为这是一个更优雅的解决方案:

COMPONENT DEFINITION组件定义

/* template definition */
import { csFooterView } from './csfooter-view.js?v6';

/* component definition */
const csfooter = {
  name: 'csfooter',
  props: ['projectName'],
  data: function() {
      return {
          copyrightCompany: 'CSDev'
      }
  },
  template: csFooterView.template
};

/* exports */
export { csfooter };

TEMPLATE DEFINITION模板定义

/**
 * VUE Footer Component
 * Template
 */

 /* template definition */
 const csFooterView = {
   template: `
    <footer class="footer bg-warning p-4 m-auto">
      <p>{{ copyrightCompany }} (c) 2020 - {{ projectName }}</p>
    </footer>
   `
 };


 export { csFooterView }

ATOM SCREENSHOT WITH HTML SYNTAX HIGHLIGHTING IN THE .JS FILE在 .JS 文件中突出显示 HTML 语法的 ATOM 屏幕截图带有反引号的 HTML 字符串和 HTML 语法的 Atom 屏幕截图

Link to Atom extension链接到 Atom 扩展

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM