Vue.js将字符串文字中的<<和`>`解释为自定义元素

时间:2019-01-06 05:23:52

标签: vue.js

我有一个简单的Vue.js应用,带有以下模板:

<h1>{{ name || '<New Document>' }}</h1>

我的目标是,如果name虚假,则使用文本<New Document>。这不是自定义标记标签。我希望Vue.js将此插入文档:

<h1>&lt;New Document&gt;</h1>

相反,我在控制台上收到此警告:

  

[Vue警告]:未知的自定义元素:-您是否正确注册了组件?对于递归组件,请确保提供“名称”选项。

根据the documentation,使用一对大括号{{}}表示文本插值,并且该表达式的 text 值将为用过的。相反,Vue.js似乎希望将其视为HTML。

为什么会这样?该如何解决?

4 个答案:

答案 0 :(得分:4)

这是一个很好的问题。像您一样,我假设花括号之间的所有内容都将作为表达式求值并注入到模板中。这就是文档所隐含的含义,在所有情况下,我都遇到过这似乎是真的……除非在字符串文字中可以包含HTML标记。至少这就是为什么我的实验似乎表明了这一点。

采用以下示例:

<h1>{{ name || '<span>hello</span>' }}</h1>

解析器有两种读取方式:

  1. 包含花括号的h1标记-在其中,这是我们稍后需要评估的表达式。
  2. 一个h1标签,后跟字符串{{ name || ',然后是span,然后是另一个字符串' }}

在这种情况下,解析器被构建为选择(2),这解释了为什么您收到编译时错误。解析器表明您有一个以<New Document>开头的标签,但没有相应的结束标签。

如果这似乎是一个奇怪的设计选择,请考虑以下代码:

<h1>{{'<span>hello</span>'}}</h1>

用户在这里打算做什么?他/她是否打算用花括号和引号将span括起来?可能。

作为解决方案,您可以手动转义字符串:

{{ name || '&lt;New Document&gt;' }}

或者,您可以使用computed property解决此问题,这将完全避开模板解析器:

<template>
  <h1>{{ nameOrNew }}</h1>
</template>

<script>
export default {
  data() {
    return {
      name: false,
    };
  },
  computed: {
    nameOrNew() {
      return this.name || '<New Document>';
    },
  },
};
</script>

答案 1 :(得分:1)

您可以在此配置Vue.config.ignoredElements

中包括所有可能忽略的元素
Vue.config.ignoredElements = ['New Document'];

我希望对您有帮助

答案 2 :(得分:1)

Vue的模板解析器首先解析HTML(分为标签及其内容),然后再解析标签的属性和文本。

对于您的模板,它类似于:

parseInt

您应该首先将模板视为有效的HTML,然后再添加Vue的插值。

Documentation还指出:

  

所有Vue.js模板都是有效的HTML,可以通过符合规范的浏览器和HTML解析器进行解析。


参考:compiler/parser/html-parser.js

答案 3 :(得分:0)

这种行为的原因我尚不清楚,但是如果您只需要它起作用,这里有两种可能:

<h1 v-if="name">{{ name }}</h1>
<h1 v-else>&lt;New Document&gt;</h1>

或者,正如在另一个答案中已经指出的那样:

<h1>{{ name || '&lt;New Document&gt;' }}</h1>