【问题标题】:Created a dynamic component, VUE works but prints an warning "template or render function not defined"创建了一个动态组件,VUE 工作但打印警告“模板或渲染功能未定义”
【发布时间】:2021-07-28 11:11:53
【问题描述】:

我正在创建一个像这样的动态降价组件

<div v-highlight :is="markdownComponent"></div>

在计算中:

computed: {
    markdownComponent() {
      return {
        template: this.html,
        data() {
          return {}
        },
        methods: { }
      }
    }
  }

this.html 是使用 markdown-it 动态创建的。我创建了一个 code_block/fence 规则来增强 pre &gt; code 块。 this.html 的一个例子是:

<div>
    <div class="code-header">
        <span class="code-language">
            Python
        </span>
        <a class="code-copy" @click="copyText('xxxx')">
        <i class="fa fa-copy"></i>
            Copy
        </a>
    </div>
  <pre>highlighted data</pre>
</div>

它可以工作,但 VUE 会打印一个警告

[Vue warn]: Failed to mount component: template or render function not defined.

found in

---> <Anonymous>
       <Notes2> at src/note.vue
         <App> at src/App.vue
           <Root>

如果我添加一个空的渲染函数,警告将会消失,但页面也会被清空:

computed: {
    markdownComponent() {
      return {
        render(h) {
           return h('div', {}, [])
        },
        template: this.html,
        data() {
          return {}
        },
        methods: { }
      }
    }
  }

}

如何添加“默认”渲染功能?我需要在停止 VUE 打印该警告的同时正确呈现页面。

编辑

我已经检查过Vue template or render function not defined yet I am using neither? 它没有提供解决此问题的方法

【问题讨论】:

  • geauser 可能是对的。什么是this.html - 它来自哪里以及它的外观如何?还为您正在使用的 Vue 版本添加适当的标签...
  • @MichalLevý 它是从 markdown-it 动态创建的。我只需要在“pre > code”元素中添加一个复制按钮。我在问题中附上了一个例子
  • 现在,检查哪个 Vue 包 you are using
  • 另外注意@daisy,您可以简单地修改现有元素的innerHTML,而不是为您的降价语料库创建新组件。我可能会让你的代码更清晰。

标签: javascript vue.js


【解决方案1】:

看起来可能不是这样,但Vue template or render function not defined yet I am using neither? 确实解决了您的问题...

Runtime + Compiler vs. Runtime-only

了解 Vue 模板总是编译成纯 JavaScrit 很重要(只需尝试将您的 this.html 示例粘贴到 vue-compiler-online 中。当您使用 vue 文件时,您是可能使用一些捆绑器(例如 Webpack - 直接或通过 VueCLI),它使用vue-loader 在构建时进行此编译。这就是为什么 Vue 项目通常使用不包含模板编译器的 Vue 构建。

但是如果你在某处使用template(即使在这样的项目中),你需要带有编译器的Vue包......

另一方面,如果 Markdown 的渲染输出中只有“Vue”功能——它是 @click 处理程序,你可以在没有 template 的情况下做到这一点(并且没有 Vue 编译由将其标记为 JS,然后再次将其呈现为静态 HTML)

  1. 删除你的code_block/fence修改
  2. 创建一个合适的markdownComponent.vue(见下文)
  3. 如果 markdown 来自不受信任的来源(用户)并且您将 html:true 传递给 markdown-it 构造函数,请执行 proper sanitization of the markdown-it output
  4. 使用 v-html 渲染由 markdown-it 生成的 HTML
<template>
  <div>
    <div class="code-header">
        <span class="code-language">
            Python
        </span>
        <a class="code-copy" @click="copyText(html)">
        <i class="fa fa-copy"></i>
            Copy
        </a>
    </div>
    <pre v-html="html"></pre>
  </div>
</template>
<script>
export default {
  props: ['html'],
  methods: {
    copyText() {
      .....
    }
  }
}
<script>

【讨论】:

    【解决方案2】:

    我已经解决了这个问题

    在markdownComponent中:

    markdownComponent() {
      let html = this.html
    
      return {
        render(h) {
          return h('div', {
            domProps: {
              innerHTML: html
            },
            on: {
              click: this.clickHandler
            },
          })
        },
        data() {
          return {}
        },
        methods: {
          clickHandler(event) {
            let b64data = event.target.getAttribute('data-src')
            let data = Base64.decode(b64data).trim()
            this.$copyText(data)
          },
        }
      }
    }
    

    在 code_block/fence 规则中,删除 @click 处理程序并添加一个 HTML 属性。

    VUE 不再抱怨了..

    【讨论】:

      猜你喜欢
      • 2019-02-27
      • 2018-06-14
      • 1970-01-01
      • 2018-03-01
      • 2018-12-20
      • 2018-10-16
      • 1970-01-01
      • 2019-09-21
      • 2017-06-01
      相关资源
      最近更新 更多