Vue: не может использовать `: srcObject.prop`, чтобы установить для свойства значение null

Созданный на 3 дек. 2018  ·  3Комментарии  ·  Источник: vuejs/vue

Версия

2.5.17

Ссылка для воспроизведения

https://codesandbox.io/s/ppyq71wrxj

Действия по воспроизведению

(См. Минимальное воспроизведение)

  1. есть компонент с HTMLMediaElement который привязывает :srcObject.prop к некоторому свойству данных (которое начинается как null ):
<audio :srcObject.prop="stream">
  1. установите его на некоторый допустимый MediaStream :
this.stream = new MediaStream();
  1. верните его на null :
this.stream = null;

Что ожидается?

Я ожидаю, что audio.srcObject будет нулевым

Что на самом деле происходит?

он остается как MediaStream, а в журнале есть TypeError.


Я заметил, что это действительно сработало при моей первой попытке написать пример воспроизведения: https://jsfiddle.net/4tnkapxo/1/ (возможно, потому что все это встроено?)

Я не уверен, насколько это полезно, но, судя по трассировке стека, он связан с этим кодом, найденным в updateDOMProps :

  for (key in oldProps) {
    if (isUndef(props[key])) {
      elm[key] = '';
    }
  }

isUndef(null) оценивается как истина, и поэтому он пытается установить опору в '' , но srcObject специально требует, чтобы это было null или MediaStream

improvement

Самый полезный комментарий

возможно, нам не следует применять преобразование для привязок .prop

Все 3 Комментарий

возможно, нам не следует применять преобразование для привязок .prop

Теперь, когда я посмотрел на рассматриваемый код ( updateDOMProps в src / platform / web / runtime / modules / dom-props.js), я думаю, что я немного лучше понимаю, что происходит. Связанный тестовый пример (в unit / modules / vdom / modules / dom-props.spec.js) создает впечатление, что он защищает от удаления:

  it('should remove the elements domProps', () => {
    const vnode1 = new VNode('a', { domProps: { src: 'http://localhost/' }})
    const vnode2 = new VNode('a', { domProps: {}})
    patch(null, vnode1)
    const elm = patch(vnode1, vnode2)
    expect(elm.src).toBe('')
  })

... Не существует универсального способа «удалить» свойство HTMLEmelent кроме установки для него любого произвольного значения, определенного установщиком. В этом смысле приведение к пустой строке как elm[key] = ''; основном ближе всего к стандартному способу. в случае тега <img> установка .src prop на любое значение, кроме пустой строки, приводит к довольно неприятному поведению:

09:48:05.267 const img = document.createElement('img')
09:48:08.948 img.src
09:48:08.953 ""
09:48:14.469 img.src = null
09:48:17.213 img.src
09:48:17.222 "https://localhost:8080/null"

(Я уверен, что для такого поведения есть веская причина, и у него повсюду есть законные варианты использования.)

Таким образом, в этом контексте пустая строка кажется таким же разумным значением по умолчанию, как и любая другая для свойств null / undef. Я экспериментировал с изменением проверки isUndef(props[key]) на props.hasOwnProperty(key) , или даже просто сравнивая его напрямую с undefined ... довольно просто сделать, но на самом деле это не кажется жизнеспособно, если пользователи зависят от возможности удалить опору, установив для нее значение null; это не имеет обратной совместимости. И комбинации свойств / элементов со специальным регистром в dom-props.js кажутся слишком ужасными, чтобы их даже упоминать.

Тем не менее, я делаю здесь слишком много предположений? является ли этот код исключительно защитой от пропущенных реквизитов в новом vnode? был ли автор теста рассматривал свойство src потому, что оно вызвало сбой? разумно ли ожидать, что пользователи предоставят правильное значение из числа "" , null и undefined при "удалении" пропа?

С другой стороны, я думаю, что на самом деле нет смысла говорить об удалении, когда речь идет о связанных свойствах ... как в примере с <audio :srcObject.prop="stream"> stream вычисленное свойство {stream: {some: thing}} на {} .

Если вышеприведенное предложение звучит нормально, то я бы предположил, что hasOwnProperty - это правильная проверка, и результат должен быть elm[key] = '' (как я уже сказал, это такое же "стандартное" удаление, как и любое другое. , и, вероятно, наиболее часто применяемый случай); Я, наверное, напишу пул-реквест на этой неделе. Но я не хочу тратить время, если это небезопасно.

Думаю, это исправил f11449d916a468651d4fd5024c37e3eebbc9941f

Была ли эта страница полезной?
0 / 5 - 0 рейтинги