Vue: não pode usar `: srcObject.prop` para definir prop como nulo

Criado em 3 dez. 2018  ·  3Comentários  ·  Fonte: vuejs/vue

Versão

2.5.17

Link de reprodução

https://codesandbox.io/s/ppyq71wrxj

Passos para reproduzir

(Veja reprodução mínima)

  1. tem um componente com HTMLMediaElement que liga :srcObject.prop a alguma propriedade de dados (que começa como null ):
<audio :srcObject.prop="stream">
  1. configure-o para algum MediaStream válido:
this.stream = new MediaStream();
  1. defina-o de volta para null :
this.stream = null;

O que é esperado?

Espero que audio.srcObject seja nulo

O que realmente está acontecendo?

ele permanece como o MediaStream e há um TypeError no log.


Percebi que realmente funcionou na minha primeira tentativa de escrever o exemplo de reprodução: https://jsfiddle.net/4tnkapxo/1/ (provavelmente porque a coisa toda está embutida?)

Não tenho certeza se isso é útil, mas com base no rastreamento de pilha está relacionado a este código, encontrado em updateDOMProps :

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

isUndef(null) está avaliando como verdadeiro e, portanto, está tentando definir a prop para '' , mas srcObject precisa especificamente que seja null ou MediaStream

improvement

Comentários muito úteis

talvez não devêssemos aplicar a transformação para ligações .prop

Todos 3 comentários

talvez não devêssemos aplicar a transformação para ligações .prop

Agora que olhei para o código ( updateDOMProps em src / platform / web / runtime / modules / dom-props.js) em questão, acho que entendo um pouco melhor o que está acontecendo. O caso de teste associado (em unit / modules / vdom / modules / dom-props.spec.js) faz parecer que está protegendo contra exclusão:

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

... Não há uma maneira genérica de "excluir" uma propriedade HTMLEmelent além de defini-la para qualquer valor arbitrário que o configurador definir. Nesse sentido, lançar em uma string vazia como elm[key] = ''; é basicamente o mais próximo que existe de uma forma padrão. no caso de uma tag <img> , definir o .src prop para qualquer coisa ao lado de uma string vazia resulta em um comportamento bastante desagradável:

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"

(Tenho certeza de que há um grande motivo para esse comportamento e há casos de uso legítimos por toda parte.)

Portanto, nesse contexto, string vazia parece um padrão tão razoável quanto qualquer outro para props null / undef. Eu experimentei mudar o cheque isUndef(props[key]) para props.hasOwnProperty(key) , ou mesmo apenas compará-lo diretamente a undefined ... muito simples de fazer, mas realmente não parece viável se os usuários dependerem da capacidade de excluir um objeto definindo-o como nulo; não é compatível com versões anteriores. E as combinações de propriedades / elementos com invólucros especiais em dom-props.js parecem obviamente terríveis demais para serem mencionados.

Dito isso, estou fazendo suposições demais aqui? esse código é puramente uma proteção contra adereços ausentes no novo vnode? o autor do teste considerou apenas a propriedade src porque foi ela que causou a falha? é razoável esperar que os usuários forneçam o valor correto entre "" , null e undefined ao "deletar" um prop?

Por outro lado, eu acho que realmente não faz sentido falar sobre exclusão quando se trata de propriedades associadas ... como no exemplo de <audio :srcObject.prop="stream"> a propriedade computada stream terá que retornar algo, então estou assumindo que há algo com os componentes internos do vnode que está além da minha compreensão que torna possível que {stream: {some: thing}} seja substituído por {} .

Se a sugestão acima parece correta, então presumo que hasOwnProperty é a verificação certa a ser feita e o resultado deve ser elm[key] = '' (como eu disse, é uma exclusão "padrão" tão boa quanto qualquer e provavelmente o caso mais comumente aplicável); Provavelmente escreverei um pull request esta semana. Mas não quero perder tempo se não for uma mudança segura.

Acho que isso foi corrigido por f11449d916a468651d4fd5024c37e3eebbc9941f

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

bfis picture bfis  ·  3Comentários

julianxhokaxhiu picture julianxhokaxhiu  ·  3Comentários

bdedardel picture bdedardel  ·  3Comentários

wufeng87 picture wufeng87  ·  3Comentários

loki0609 picture loki0609  ·  3Comentários