【问题标题】:How can I use template tag inside slot in Vue.js?如何在 Vue.js 的插槽内使用模板标签?
【发布时间】:2019-07-08 10:03:40
【问题描述】:

我有一个包含一些 HTML 和一些 script 标记的模板。我想在我的 vue 组件中使用它作为模板,稍后我将把它放入 DOM 中,我希望它按原样放置,所以我的脚本标签也会被执行。

我想将模板保留在组件标签内并使用slot

例如

<amazing-component>
    <template>
        <p>This is the content</p>
        <script>
           console.log("I want to be executed as long as someone puts me in the DOM!");
        </script>
    </template>
</amazing-component>

<script type="text/x-template" id="component-template">
   <slot></slot>
</script>

但问题是Vue删除了templatescript标签,然后替换了slot标签。

到目前为止我拼命尝试但没有奏效:

  • 将模板放在另一个模板中 - 模板就消失了。
  • 用模板包裹slot - 模板就消失了。
  • 使用&lt;script type="text/x-template" &gt; - 这是一个史诗般的失败。
  • $slots 获取槽 - 这是一个没有模板/脚本标签的 VNode。

最大的问题是前端不知道template标签里面的html是什么样子的。它只是在服务器上呈现的一些 html,一些必须按原样插入页面才能工作的不可变遗留代码。

当然,我可以将模板标签放在组件外部并以另一种方式获取它,但我希望将它放在组件内部以使其更加整洁和优雅。

【问题讨论】:

  • 模板标签应该消失,这就是它们存在的全部原因。它们是你可以挂起 vue 规则的地方,而无需在 DOM 中插入额外的节点。
  • @DanielBeck 你肯定有一个观点,但模板标签不是 vue 特定的,所以完全删除它们感觉有点极端。
  • 这就是 Vue 的做法,大概是希望如果您使用 Vue,您不会同时尝试在其之上使用单独的模板系统。
  • @xpy 您可以强制 &lt;template&gt; 标签呈现为其他内容,而不是使用 &lt;template is="div"&gt; 消失。

标签: javascript vue.js vuejs2


【解决方案1】:

虽然 Vue 在自己的编译中使用模板标签,但您仍然可以使用 &lt;component is="template"&gt; 强制它发出 HTML 模板标签

var app = new Vue({
  el: '#app',
  template: `
      <div>
          <h1>No template:</h1>
          <template>
              test
          </template>
          <p>More code (check the page source)</p>
          <h1>Yes template: </h1>
          <component is="template">
              test
          </component>
          <p>More code(check the page source)</p>
          <h1>Yes script: </h1>
          <component is="script">
              console.log('Scrpt test');
          </component>
          <p>More code(check the console)</p>
      </div>
  `,
  data: {}
})
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

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

【讨论】:

  • 这与cmets中提到的@Archie几乎相同。可悲的是,script 标签也有条纹。 :(
  • @xpy 脚本标签的问题在于不清楚它们的含义,如果要执行1次,请将脚本放在正文中,但如果应该每次都执行组件已加载,使用 eval 加载它,当您包含脚本标记时,Vue 不会强制一种行为超越另一种行为,但您仍然可以使用相同的 is="script" 技巧来强制它
【解决方案2】:

这不是 Vue 的工作方式。 &lt;script&gt; 标签不属于 &lt;template&gt; 并且出于某种原因被省略。如果您想在页面加载时执行某些操作,请使用对应的 hook

要执行服务器生成的 JS 代码,请使用 eval()

父.vue

<template>
  <child script="console.log('something')"></child>
</template>

Child.vue

<template>

</template>

<script>
  props: ['script'],
  created() {
    eval(this.script)
  }
</script>

【讨论】:

  • 我的意图不是在某个时候执行某些脚本。说得更清楚一点,我希望有能力通过 vue 附加和执行在服务器上构建的任意脚本标签,而前端完全忽略了它的目的、功能和内容。
  • 使用eval() 来做到这一点。我在回答中添加了一个示例。
猜你喜欢
  • 1970-01-01
  • 2019-10-26
  • 2019-12-22
  • 2021-02-27
  • 2021-05-17
  • 1970-01-01
  • 2023-04-06
  • 2020-04-22
  • 2018-10-15
相关资源
最近更新 更多