Vue: `:srcObject.prop`を使用してpropをnullに設定することはできません

作成日 2018年12月03日  ·  3コメント  ·  ソース: vuejs/vue

バージョン

2.5.17

複製リンク

https://codesandbox.io/s/ppyq71wrxj

再現する手順

(最小限の再現を参照)

  1. :srcObject.propをいくつかのデータプロパティにバインドするHTMLMediaElementを持つコンポーネントがあります( nullで始まります):
<audio :srcObject.prop="stream">
  1. 有効なMediaStreamます:
this.stream = new MediaStream();
  1. 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

improvement

最も参考になるコメント

.propバインディングに変換を適用すべきではないかもしれません

全てのコメント3件

.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プロパティのみを考慮していましたか? 小道具を「削除」するときに、ユーザーが""nullundefined中から正しい値を提供することを期待するのは合理的ですか?

一方、バインドされたプロパティに関しては、削除について話すのはあまり意味がないと思います... <audio :srcObject.prop="stream">の例のように、 stream計算されたプロパティは何かを返すので、 {stream: {some: thing}}{}置き換えることができる、私の理解を超えたvnode内部の何かがあると思います。

上記の提案が問題ないように思える場合は、 hasOwnPropertyが適切なチェックであり、結果はelm[key] = ''なるはずです(「標準」の削除と同じくらい良いと言ったように) 、そしておそらく最も一般的に適用可能なケース); 今週はおそらくプルリクエストを作成します。 しかし、安全な変更ができない場合は、時間をかけたくありません。

これはf11449d916a468651d4fd5024c37e3eebbc9941fによって修正されたと思います

このページは役に立ちましたか?
0 / 5 - 0 評価