Как проксировать пользовательский элемент (веб-компонент)

class A extends HTMLElement {
  constructor() {
    super()
    return new Proxy(this, {})
  }
}

class B extends A {
  constructor() {
    super()
  }
}

window.customElements.define('b-element', B)
<b-element></b-element>

Как я могу Proxy пользовательский элемент?

Когда я пытаюсь это сделать: "Uncaught InvalidStateError: конструкторы пользовательских элементов должны сначала вызвать super() и не должны возвращать другой объект"

1 ответ

Решение

Вы можете либо проксифицировать класс, либо экземпляр пользовательского элемента.

Учитывая следующее определение пользовательского элемента:

class A extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    this.innerHTML = 'Hello'    
  }
}
customElements.define( 'a-element', A )

Прокси для экземпляра пользовательского элемента

Создайте прокси из ссылки на экземпляр (здесь: ae):

<a-element id="ae"></a-element>
<script>
  var b1 = new Proxy( ae, {
    get ( target, value ) { return target[value] }       
  } )
  console.log( b1.innerHTML ) // => "Hello"
</script>

Прокси для класса Custom Element

Определите construct ловушка, чтобы поймать new оператор:

<script>
  var B = new Proxy( A, {
    construct() { return new A }
  } )
  var b2 = new B
  document.body.appendChild( b2 )
  console.log( b2.innerHTML ) // => "Hello"
</script>

Получить экземпляр Proxy экземпляра пользовательского элемента из класса Proxy

Если вы хотите создать пользовательский элемент и получить один объект Proxy напрямую, вы можете объединить оба решения выше.

В следующем примере показано, как получить Proxy для элемента <a-element> это будет входить в консоль каждый доступ к свойству. construct() ловушка, определенная в классе Proxy, возвращает себя Proxy для созданного пользовательского элемента.

class A extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    this.innerHTML = 'Hello'    
  }
}
customElements.define( 'a-element', A )  

var P = new Proxy( A, {
  construct () { 
    return new Proxy ( new A, {
      get ( target, value ) { 
        if ( value == 'element' ) 
          return target
        console.info( `proxy: property ${value} for <${target.localName}> is "${target[value]}"` )
        return target[value]
      }       
    } )
  }
} )
var p = new P
document.body.appendChild( p.element )
console.log( p.innerHTML )

Другие вопросы по тегам