Vue: no se puede usar `: srcObject.prop` para establecer prop en nulo

Creado en 3 dic. 2018  ·  3Comentarios  ·  Fuente: vuejs/vue

Versión

2.5.17

Enlace de reproducción

https://codesandbox.io/s/ppyq71wrxj

pasos para reproducir

(Ver reproducción mínima)

  1. tiene un componente con un HTMLMediaElement que une :srcObject.prop a alguna propiedad de datos (que comienza como null ):
<audio :srcObject.prop="stream">
  1. configúrelo en algunos MediaStream válidos:
this.stream = new MediaStream();
  1. configúrelo de nuevo en null :
this.stream = null;

¿Lo que es esperado?

Espero que audio.srcObject sea nulo

¿Qué está pasando realmente?

permanece como MediaStream y hay un TypeError en el registro.


Me di cuenta de que realmente funcionó en mi primer intento de escribir el ejemplo de reproducción: https://jsfiddle.net/4tnkapxo/1/ (¿probablemente porque todo está en línea?)

No estoy seguro de cuán útil sea esto, pero según el seguimiento de la pila está relacionado con este código, que se encuentra en updateDOMProps :

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

isUndef(null) está evaluando verdadero, por lo que está tratando de establecer el accesorio en '' , pero srcObject específicamente necesita que sea null o MediaStream

improvement

Comentario más útil

tal vez no deberíamos aplicar la transformación para los enlaces .prop

Todos 3 comentarios

tal vez no deberíamos aplicar la transformación para los enlaces .prop

Ahora que he visto el código ( updateDOMProps en src / platform / web / runtime / modules / dom-props.js) en cuestión, creo que entiendo un poco mejor lo que está sucediendo. El caso de prueba asociado (en unit / modules / vdom / modules / dom-props.spec.js) hace que parezca que está protegiendo contra la eliminación:

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

... No hay una forma genérica de "borrar" una propiedad HTMLEmelent aparte de establecerla en cualquier valor arbitrario que defina el definidor. En ese sentido, convertir a una cadena vacía como elm[key] = ''; es básicamente lo más cercano que hay a una forma estándar. en el caso de una etiqueta <img> , establecer el prop .src en cualquier cosa al lado de una cadena vacía da como resultado un comportamiento bastante desagradable:

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"

(Estoy seguro de que hay una gran razón para ese comportamiento y tiene casos de uso legítimos por todas partes).

Entonces, en ese contexto, la cadena vacía parece un valor predeterminado tan razonable como cualquier otro para accesorios nulos / indefinidos. He experimentado cambiando el cheque isUndef(props[key]) a props.hasOwnProperty(key) , o incluso comparándolo directamente con undefined ... bastante simple de hacer, pero realmente no parece viable si los usuarios dependen de la capacidad de eliminar un accesorio configurándolo como nulo; no es compatible con versiones anteriores. Y las combinaciones de propiedad / elemento de carcasa especial en dom-props.js parecen demasiado obviamente terribles como para siquiera mencionarlas.

Dicho esto, ¿estoy haciendo demasiadas suposiciones allí? ¿Es ese código simplemente una protección contra los accesorios faltantes en el nuevo vnode? ¿El autor de la prueba solo consideró la propiedad src porque es lo que causó una falla? ¿Es razonable esperar que los usuarios proporcionen el valor correcto entre "" , null y undefined cuando "eliminan" una propiedad?

Por otro lado, supongo que realmente no tiene sentido hablar de eliminación cuando se trata de propiedades vinculadas ... como en el ejemplo de <audio :srcObject.prop="stream"> la propiedad calculada stream tendrá que devolver algo, así que supongo que hay algo con las partes internas de vnode que están más allá de mi comprensión que hace posible que {stream: {some: thing}} se reemplace con {} .

Si la sugerencia anterior suena bien, entonces asumiría que hasOwnProperty es la verificación correcta para hacer allí, y el resultado debería ser elm[key] = '' (como dije, es una eliminación "estándar" tan buena como cualquier otra , y probablemente el caso más comúnmente aplicable); Probablemente escribiré una solicitud de extracción esta semana. Pero no quiero perder el tiempo si no es un cambio seguro.

Creo que esto fue solucionado por f11449d916a468651d4fd5024c37e3eebbc9941f

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

wufeng87 picture wufeng87  ·  3Comentarios

hiendv picture hiendv  ·  3Comentarios

robertleeplummerjr picture robertleeplummerjr  ·  3Comentarios

franciscolourenco picture franciscolourenco  ·  3Comentarios

bdedardel picture bdedardel  ·  3Comentarios