Свойство Svelte. js не определено в теге скрипта с помощью customElenent: true - PullRequest
1 голос
/ 28 марта 2020

Возможно, это то, как работает Svelte. js, но мне любопытно, если я делаю что-то не так, или если есть обходной путь.

Если я устанавливаю опцию компилятора customElement: true, свойства переданные компонентам недоступны в теге <script> внутри этого компонента. Я использую веб-пакет с svelte-загрузчиком. Вот простой пример:

// index.html

<my-app foo="testing svelte"></my-app>
<script src="bundle.js"></script>


// script.js (bundled into bundle.js)

import App from './App.svelte';
customElements.define('my-app', App);


// App.svelte

<script>
    export let foo;
    console.log(foo); // undefined

    $: bar = foo.toUpperCase(); // Cannot read property 'toUpperCase' of undefined

    $: qux = String(foo).toUpperCase(); // No error, works
</script>

{ foo } // testing svelte - works, as expected

{ qux } // TESTING SVELTE - works, as expected

Кроме того, если customElement: true не задано, а инфраструктура создается с помощью конструктора const app = new App(...), console.log(foo) будет работать так же, как $: bar = foo.toUpperCase().

Может кто-нибудь объяснить, почему Svelte работает таким образом? Спасибо, ура!

1 Ответ

1 голос
/ 30 марта 2020

С пользовательскими элементами реквизиты не передаются из конструктора, они устанавливаются только позже, на экземпляре компонента.

Я имею в виду, что с пользовательским элементом это концептуально похоже на стандартный компонент:

const app = new App({ target })
app.$set({ foo: 'bar' })

Не то чтобы:

const app = new App({ target, props: { foo: 'bar' } })

Именно поэтому значение изначально (ваше console.log) не определено, но все еще отображается в разметке, как и ожидалось.

Причина этого заключается в том, что функция init компонента Svelte (то есть содержимое тега <script> в вашем компоненте) вызывается синхронно из конструктора компонента (то есть, когда вы делаете new App(...)) , Однако на данный момент атрибуты элементов недоступны (в соответствии с этим ответом ).

Либо дайте вашему реквизиту значение по умолчанию, либо проверьте его перед использованием ...

<script>
  // default value
  export let name = ''

  // ... or sanity check
  export let other
  $: otherName = other != null ? other + name : null
<script>
...