Сбой Vue.compile для вложенности элементов HTML больше двух - PullRequest
0 голосов
/ 18 мая 2018

Использование 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> не работает.

Пример кода ниже и скрипка .(асинхронное моделирование с помощью 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 Ответ

0 голосов
/ 18 мая 2018

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 задокументирован здесь .

Здесь также есть небольшая часть документации здесь .

Линус Борг (Linus Borg), один из основных разработчиков команды Vue, объясняет немного о staticRenderFns здесь :

Хорошо, используются статические функции рендерингаоптимизировать процесс рендеринга, по существу кэшируя части дерева DOM, которые являются статическими и поэтому не могут изменяться.Когда вы вызываете функцию рендеринга, которая была сгенерирована вместе с ними, она будет вызывать эти функции для получения этих статических частей.

Так что нет разумного способа вызвать или обновить их во время выполнения, они должны присутствовать накомпонент как опора с этим именем и будет вызываться функцией рендеринга при необходимости.

...