Vue: ne peut pas utiliser `:srcObject.prop` pour définir prop sur null

Créé le 3 déc. 2018  ·  3Commentaires  ·  Source: vuejs/vue

Version

2.5.17

Lien de reproduction

https://codesandbox.io/s/ppyq71wrxj

Étapes à reproduire

(Voir la reproduction minimale)

  1. avoir un composant avec un HTMLMediaElement qui lie :srcObject.prop à une propriété de données (qui commence par null ):
<audio :srcObject.prop="stream">
  1. définissez-le sur des MediaStream valides :
this.stream = new MediaStream();
  1. remettez-le à null :
this.stream = null;

Qu'est-ce qui est attendu ?

Je m'attends à ce que l'audio.srcObject soit nul

Que se passe-t-il réellement ?

il reste en tant que MediaStream et il y a une TypeError dans le journal.


J'ai remarqué que cela fonctionnait réellement lors de ma première tentative d'écriture de l'exemple de repro : https://jsfiddle.net/4tnkapxo/1/ (probablement parce que tout est en ligne ?)

Je ne sais pas à quel point c'est utile, mais d'après la trace de la pile, il est lié à ce code, trouvé dans updateDOMProps :

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

isUndef(null) évalue true, et il essaie donc de définir la prop sur '' , mais srcObject spécifiquement besoin qu'elle soit null ou un MediaStream

improvement

Commentaire le plus utile

peut-être que nous ne devrions pas appliquer de transformation pour les liaisons .prop

Tous les 3 commentaires

peut-être que nous ne devrions pas appliquer de transformation pour les liaisons .prop

Maintenant que j'ai regardé le code ( updateDOMProps dans src/platforms/web/runtime/modules/dom-props.js) en question je pense comprendre un peu mieux ce qui se passe. Le cas de test associé (dans unit/modules/vdom/modules/dom-props.spec.js) donne l'impression qu'il se prémunit contre la suppression :

  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('')
  })

... Il n'y a pas de moyen générique de "supprimer" une propriété HTMLEmelent part la définir sur la valeur arbitraire définie par le setter. En ce sens, la conversion en chaîne vide en tant que elm[key] = ''; est fondamentalement la méthode la plus proche d'une méthode standard. dans le cas d'une balise <img> , définir la prop .src sur quelque chose à côté d'une chaîne vide entraîne un comportement assez odieux :

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"

(Je suis sûr qu'il y a une bonne raison à ce comportement et qu'il a des cas d'utilisation légitimes partout.)

Donc, dans ce contexte, une chaîne vide semble être une valeur par défaut aussi raisonnable que n'importe quelle autre pour les accessoires null/undef. J'ai expérimenté en changeant le isUndef(props[key]) en props.hasOwnProperty(key) , ou même en le comparant directement à undefined ... assez simple à faire, mais cela ne semble pas vraiment viable si les utilisateurs dépendent de la possibilité de supprimer un accessoire en le définissant sur null ; ce n'est pas rétrocompatible. Et les combinaisons de propriétés/éléments de boîtiers spéciaux dans dom-props.js semblent trop manifestement terribles pour même les mentionner.

Cela dit, est-ce que je fais trop d'hypothèses là-bas? ce code est-il purement une protection contre les accessoires manquants dans le nouveau vnode? l'auteur du test ne considérait-il que la propriété src parce que c'est ce qui a causé un échec ? est-il raisonnable de s'attendre à ce que les utilisateurs fournissent la valeur correcte parmi "" , null et undefined lors de la "suppression" d'un accessoire ?

D'un autre côté, je suppose que cela n'a pas vraiment de sens de parler de suppression en ce qui concerne les propriétés liées... comme dans l'exemple de <audio :srcObject.prop="stream"> la propriété calculée stream devra renvoyer quelque chose, donc je suppose qu'il y a quelque chose avec les composants internes de vnode qui dépassent ma compréhension qui permet à {stream: {some: thing}} d'être remplacé par {} .

Si la suggestion ci-dessus sonne bien, alors je suppose que hasOwnProperty est la bonne vérification à faire ici, et le résultat devrait être elm[key] = '' (comme je l'ai dit, c'est une suppression "standard" aussi bonne que n'importe quelle autre , et probablement le cas le plus couramment applicable); Je vais probablement écrire une pull request cette semaine. Mais je ne veux pas passer du temps si ce n'est pas un changement sûr à faire.

Je pense que cela a été corrigé par f11449d916a468651d4fd5024c37e3eebbc9941f

Cette page vous a été utile?
0 / 5 - 0 notes