2.5.17
https://codesandbox.io/s/ppyq71wrxj
(最小限の再現を参照)
:srcObject.prop
をいくつかのデータプロパティにバインドするHTMLMediaElement
を持つコンポーネントがあります( null
で始まります):<audio :srcObject.prop="stream">
MediaStream
ます:this.stream = new MediaStream();
null
に戻します:this.stream = null;
audio.srcObjectがnullになると思います
MediaStreamのままで、ログにTypeErrorがあります。
再現例を書く最初の試みで実際に機能することに気づきました: https :
これがどれほど役立つかはわかりませんが、スタックトレースに基づくと、 updateDOMProps
にあるこのコードに関連しています。
for (key in oldProps) {
if (isUndef(props[key])) {
elm[key] = '';
}
}
isUndef(null)
はtrueと評価されているため、小道具を''
に設定しようとしていますが、 srcObject
特にnull
またはMediaStream
.prop
バインディングに変換を適用すべきではないかもしれません
問題のコード(src / platforms / web / runtime / modules / dom-props.jsのupdateDOMProps
)を確認したので、何が起こっているのかが少しよく理解できたと思います。 関連するテストケース(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
小道具を空の文字列以外に設定すると、かなり不快な動作が発生します。
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}}
を{}
置き換えることができる、私の理解を超えたvnode内部の何かがあると思います。
上記の提案が問題ないように思える場合は、 hasOwnProperty
が適切なチェックであり、結果はelm[key] = ''
なるはずです(「標準」の削除と同じくらい良いと言ったように) 、そしておそらく最も一般的に適用可能なケース); 今週はおそらくプルリクエストを作成します。 しかし、安全な変更ができない場合は、時間をかけたくありません。
これはf11449d916a468651d4fd5024c37e3eebbc9941fによって修正されたと思います
最も参考になるコメント
.prop
バインディングに変換を適用すべきではないかもしれません