【问题标题】:Vue.compile fails for HTML element nesting greater than twoVue.compile 因 HTML 元素嵌套大于两个而失败
【发布时间】:2018-05-18 09:55:50
【问题描述】:

将 Vue.compile 用于异步 HTML 似乎具有两个元素深度的最大复杂性。任何更高的值都会在渲染时抛出 Error in render: "TypeError: Cannot read property '0' of undefined"

所以<section><p>hello</p><section> 工作正常,但<section><p>hello <em>there</em></p><section> 失败。

下面的代码示例和a fiddle。 (由 setTimeout 模拟异步)

new Vue({
  el: '#app',
  data: {
    msg: 'simple template works',
    template: Vue.compile('<p>{{msg}}</p>').render
  },
  render(createElement) {
    return this.template();
  },
  mounted() {
    // below fails
    setTimeout(()=>{
      this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep <em>fails</em>?</p></div>').render;
    }, 1000);
    // below renders fine
    setTimeout(()=>{
      this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep fails?</p></div>').render;
    }, 2000);
  }
})

谁能告诉这里发生了什么?是否应该以不同方式编译/呈现“复杂”模板?

【问题讨论】:

    标签: javascript vue.js compilation runtime


    【解决方案1】:

    Vue.compile 返回一个具有 两个 属性的对象,这两个属性都是正确渲染组件所必需的。第一个属性是render,它是模板的根渲染函数,第二个是staticRenderFns,它是模板编译时创建的用于优化渲染过程的函数的集合。正如您可能从名称中推测的那样,它们呈现静态内容。

    如您所见,在某些情况下,编译过程不会生成任何静态渲染函数,您的代码可能会在不包含它的情况下工作。但是,通常,您需要这两个属性才能正确渲染。

    这是您的代码的更新版本。

    console.clear()
    
    new Vue({
      el: '#app',
      data: {
        msg: 'simple template works',
        template: Vue.compile('<p>{{msg}}</p>')
      },
      render(createElement) {
        let msg = this.msg
        let base = {
          data(){
            return {
              msg
            }
          }
        }
        let component = Object.assign({}, this.template, base)
        return createElement(component);
      },
      mounted() {
        setTimeout(()=>{
          this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep <em>fails</em>?</p></div>');
        }, 1000);
        
        setTimeout(()=>{
          this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep fails?</p></div>');
        }, 2000);
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
    <div id="app"></div>

    Vue.compile 是 documented here

    还有一小段documentation here

    Vue 核心团队之一的 Linus Borg 解释了一些关于 staticRenderFns here:

    好吧,静态渲染函数用于通过缓存 DOM 树的静态部分来优化渲染过程,这些部分是静态的,因此无法更改。当你调用与它们一起生成的渲染函数时,它会调用这些函数来获取那些静态部分。

    所以在运行时没有明智的方法来调用或更新它们,它们 必须作为具有该名称的道具出现在组件上,并且将 需要时由渲染函数调用。

    【讨论】:

    • 这是否记录在 vuejs.org 上的任何地方?我没找到。
    • @Sjeiti 我用一些文档指针更新了答案。
    猜你喜欢
    • 2017-11-12
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    相关资源
    最近更新 更多