2.5.17
https://codesandbox.io/s/ppyq71wrxj
(Siehe minimale Repro)
HTMLMediaElement
, die :srcObject.prop
an eine Dateneigenschaft bindet (die mit null
beginnt):<audio :srcObject.prop="stream">
MediaStream
:this.stream = new MediaStream();
null
:this.stream = null;
Ich erwarte, dass das audio.srcObject null ist
es bleibt als MediaStream und es gibt einen TypeError im Protokoll.
Mir ist aufgefallen, dass es bei meinem ersten Versuch, das Repro-Beispiel zu schreiben, tatsächlich funktioniert hat: https://jsfiddle.net/4tnkapxo/1/ (wahrscheinlich weil das Ganze inline ist?)
Ich bin mir nicht sicher, wie hilfreich das ist, aber basierend auf dem Stack-Trace hängt es mit diesem Code zusammen, der in updateDOMProps
:
for (key in oldProps) {
if (isUndef(props[key])) {
elm[key] = '';
}
}
isUndef(null)
wertet true aus und versucht daher, die Requisite auf ''
, aber srcObject
speziell null
oder MediaStream
Vielleicht sollten wir keine Transformation für .prop
Bindungen anwenden
Nachdem ich mir den fraglichen Code ( updateDOMProps
in src/platforms/web/runtime/modules/dom-props.js) angeschaut habe, denke ich, dass ich etwas besser verstehe, was passiert. Der zugehörige Testfall (in unit/modules/vdom/modules/dom-props.spec.js) lässt es so aussehen, als würde er vor dem Löschen schützen:
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('')
})
...Es gibt keinen generischen Weg, eine HTMLEmelent
Eigenschaft zu "löschen", außer sie auf einen beliebigen Wert zu setzen, den der Setter definiert. In diesem Sinne ist das Umwandeln in eine leere Zeichenfolge als elm[key] = '';
Grunde der Standardweg am nächsten. Im Fall eines <img>
Tags führt das Festlegen der .src
Requisite auf etwas anderes als eine leere Zeichenfolge zu einem ziemlich widerlichen Verhalten:
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"
(Ich bin sicher, es gibt einen guten Grund für dieses Verhalten und es gibt überall legitime Anwendungsfälle.)
In diesem Kontext scheint eine leere Zeichenfolge ein ebenso vernünftiger Standard zu sein wie jeder andere für null/undef-Requisiten. Ich habe damit experimentiert, den isUndef(props[key])
Check in props.hasOwnProperty(key)
zu ändern oder ihn sogar direkt mit undefined
... ziemlich einfach zu machen, aber es scheint nicht wirklich zu sein praktikabel, wenn Benutzer auf die Möglichkeit angewiesen sind, eine Requisite zu löschen, indem sie sie auf null setzen; es ist nicht abwärtskompatibel. Und Eigenschaft/Element-Kombinationen mit Sonderzeichen in dom-props.js
scheinen zu offensichtlich schrecklich, um sie überhaupt zu erwähnen.
Das heißt, mache ich da zu viele Annahmen? Ist dieser Code nur ein Schutz gegen fehlende Requisiten im neuen vnode? Hat der Autor des Tests nur die Eigenschaft src
Betracht gezogen, weil sie einen Fehler verursacht hat? Ist es vernünftig zu erwarten, dass Benutzer beim "Löschen" einer Requisite den richtigen Wert zwischen ""
, null
und undefined
angeben?
Andererseits denke ich, dass es nicht wirklich sinnvoll ist, über das Löschen zu sprechen, wenn es um gebundene Eigenschaften geht ... wie im Beispiel von <audio :srcObject.prop="stream">
die berechnete Eigenschaft stream
muss etwas zurückgeben, also gehe ich davon aus, dass es etwas mit den vnode-Interna gibt, das außerhalb meines Verständnisses liegt, das es ermöglicht, {stream: {some: thing}}
durch {}
zu ersetzen.
Wenn der obige Vorschlag in Ordnung klingt, dann würde ich davon ausgehen, dass hasOwnProperty
die richtige Prüfung ist, und das Ergebnis sollte elm[key] = ''
(wie gesagt, es ist so gut wie ein "Standard"-Löschvorgang , und wahrscheinlich der am häufigsten zutreffende Fall); Ich werde wahrscheinlich diese Woche einen Pull Request schreiben. Aber ich möchte die Zeit nicht aufwenden, wenn es keine sichere Änderung ist.
Ich denke, das wurde von f11449d916a468651d4fd5024c37e3eebbc9941f behoben
Hilfreichster Kommentar
Vielleicht sollten wir keine Transformation für
.prop
Bindungen anwenden