Является ли vm. $ El компонента Vue.js постоянным или его можно переназначить? - PullRequest
0 голосов
/ 22 февраля 2019

Экземпляры компонента Vue.js имеют свойство vm.$em , которое предоставляет доступ к корневому элементу DOM компонента.Меняется ли значение этого свойства в течение жизненного цикла компонента или оно постоянно после монтирования компонента?Другими словами, после создания корневого элемента DOM компонента его можно заменить на Vue при каких-то условиях?

Я знаю, что содержимое элемента DOM может, конечно, измениться.

Согласно приведенной ниже диаграмме жизненного цикла компонента, при изменении данных возникает «Повторная визуализация и исправление Virtual DOM».Я прочитал документ и попытался найти ответ в источнике Vue, но я до сих пор не нашел окончательного ответа.

Самое близкое, с чем я был связан с исходным кодом, это в src/core/instance/lifecycle.js:

Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
  const vm: Component = this
  const prevEl = vm.$el
  const prevVnode = vm._vnode
  const restoreActiveInstance = setActiveInstance(vm)
  vm._vnode = vnode
  // Vue.prototype.__patch__ is injected in entry points
  // based on the rendering backend used.
  if (!prevVnode) {
    // initial render
    vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)
  } else {
    // updates
    vm.$el = vm.__patch__(prevVnode, vnode)
  }
  restoreActiveInstance()
  // update __vue__ reference
  if (prevEl) {
    prevEl.__vue__ = null
  }
  if (vm.$el) {
    vm.$el.__vue__ = vm
  }
  // etc.
}

Это говорит о том, что vm.$el можно переназначать при каждом рендеринге компонента, но я не расшифровал, как работает __patch__(), чтобы быть уверенным, и когда _update() вызывается точно.

Зачем беспокоиться?

У меня есть какая-то задача установки, чтобы выполнить ее непосредственно с корневым элементом DOM (например, настроить плагин jQuery).Достаточно ли этого сделать только в хуке mounted (да, если vm.$el является постоянным) или я должен сделать это также в хуке updated при обнаружении изменения vm.$el?

Vue.js lifecycle diagram

1 Ответ

0 голосов
/ 22 февраля 2019

Если вы полностью контролируете содержимое компонента, тогда вы , вероятно, сохраните, предполагая, что vm.$el не изменится.Если вы делаете (например) миксин или директиву, то вы не можете - вполне возможно создать компонент, элемент верхнего уровня которого можно изменить, используя директиву is .

Например, это определяет компонент, который может изменить его тип элемента верхнего уровня:

Vue.component('comp',{
  props:{type:String},
  template:`
    <component :is="type">
       I am a {{type}}
    </component>
  `
})

Это скрипка, которая демонстрирует это: https://jsfiddle.net/tazfLqbh/1/

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

Анализ скрипки

Остается вопрос, является ли динамический компонент вСкрипка запускает создание нового компонента Vue при переключении его типа.В консоли разработчика:

// "Inspect" the span
> a = $0.__vue__
VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
// Toggle the type to div and "inspect" the div
> b = $0.__vue__
VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
> a === b
true

Таким образом, новый экземпляр компонента Vue не создается при переключении типа корневого элемента.

Как и ожидалось, эта скрипка показывает , чтодинамический тип компонента однако запускает создание нового экземпляра компонента Vue.Таким образом, в этом случае кажется, что крюка mounted достаточно.Примерно так:

<div id="app">
  <button @click="toggle">
    Toggle div or span element
  </button>
  <component :is="span?'comp-span':'comp-div'"></component>
</div>

Vue.component('comp-span',{
  template:`
    <span>
       I am a span
    </span>
  `
})

Vue.component('comp-div',{
  template:`
    <div>
       I am a div
    </div>
  `
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...