【问题标题】:Svelte.js component property is undefined within script tag with customElement: trueSvelte.js 组件属性在带有 customElement: true 的脚本标记中未定义
【发布时间】:2020-07-09 00:13:02
【问题描述】:

这可能是 Svelte.js 的工作方式,但我很好奇我是否做错了什么,或者是否有解决方法。

如果我设置编译器选项customElement: true,传递给组件的属性在该组件内的<script> 标记中不可用。我使用带有 svelte-loader 的 webpack。这是一个简单的例子:

// 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(...) 构造函数进行实例化,则 @​​987654326@ 将像 $: bar = foo.toUpperCase() 一样工作。

谁能解释为什么 Svelte 会这样工作?谢谢,干杯!

【问题讨论】:

    标签: javascript web-component svelte svelte-3 svelte-component


    【解决方案1】:

    对于自定义元素,props 不会从构造函数传递,它们只是稍后在组件实例上设置。

    我的意思是,使用自定义元素,在概念上就像使用标准组件一样:

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

    不是这样的:

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

    这就是为什么该值最初(您的console.log)未定义,但仍按预期显示在标记中。

    之所以会这样,是因为一个Svelte组件的init函数(也就是你的组件中&lt;script&gt;标签的内容)是从组件构造函数中同步调用的(也就是你做new App(...)的时候) .但是,此时元素的属性不可用(根据this answer)。

    要么给你的道具一个默认值,要么在使用前检查它......

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

    【讨论】:

    • 谢谢,现在完全说得通了,这就是String(foo).toUpperCase() 起作用的原因——通过在声明的(未定义的)变量上使用String 构造函数,它的值是'undefined',这是一个字符串,所以@ 987654331@ 不会触发错误,并且当组件被渲染时,它已经具有更新的值。所以最简单的解决方案基本上是设置一个空字符串作为默认值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 2017-11-15
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    相关资源
    最近更新 更多