代码之家  ›  专栏  ›  技术社区  ›  Sjeiti

Vue.compile无法为大于2的HTML元素嵌套

  •  2
  • Sjeiti  · 技术社区  · 7 年前

    对于异步HTML使用vue.compile似乎具有两个元素的最大复杂性。有更高的投掷吗 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);
      }
    })
    

    有人能告诉我这是怎么回事吗?“复杂”模板的编译/呈现方式应该不同吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Bert Jeffrey Shen    7 年前

    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的核心团队之一LinusBorg对Staticrenderfs做了一些解释。 here :

    好吧,静态渲染函数用于优化渲染过程,方法是缓存DOM树中静态的部分,因此不能更改。当调用与它们一起生成的呈现函数时,它将调用这些函数以获取静态部分。

    因此,在运行时调用或更新它们没有合理的方法,它们 必须作为具有该名称的道具出现在组件上,并且将 在需要时由呈现函数调用。