【问题标题】:how to build a svelte customElement using @smui/dialog?如何使用@smui/dialog 构建一个纤细的 customElement?
【发布时间】:2021-06-07 00:38:12
【问题描述】:

我想构建一个可以与 React 框架一起使用的 svelte 组件,在阅读了 svelte 文档之后,我决定将我的 Svelte 组件构建为 svelte customElement,一切都很顺利,直到我使用了@smui/dialog,我的代码:

<svelte:options tag="charity-legal-agreement-element" />

<script lang="ts">
import Dialog, {Title, Content, Actions} from '@smui/dialog';
...
<Dialog
  bind:this={dialog}
  aria-labelledby="dialog-title"
  aria-describedby="dialog-content"
  on:MDCDialog:closed={deleteItem}
>
...
</Dialog>

汇总配置:

svelte({
        preprocess: sveltePreprocess({ sourceMap: !production }),
        compilerOptions: {
            // enable run-time checks when not in production
            dev: !production,
            customElement: true
        },
        // customElement: true
    }),
    postcss({
        extract: true,
        minimize: true,
        use: [
          ['sass', {
            includePaths: [
              './src/theme',
              './node_modules',
              '../../node_modules',
            ]
          }]
        ]
      }),
     ...

来自调试控制台的错误:

index.mjs:1512 Uncaught TypeError: Illegal constructor
at new SvelteElement (index.mjs:1512)
at new Dialog (Dialog.svelte:56)
at create_fragment (index.svelte:53)
at init (index.mjs:1489)
at new Src (index.svelte:72)
at main.ts:13
at main.ts:18
SvelteElement   @   index.mjs:1512
Dialog  @   Dialog.svelte:56
create_fragment @   index.svelte:53
init    @   index.mjs:1489
Src @   index.svelte:72
(anonymous) @   main.ts:13
(anonymous) @   main.ts:18

如果我删除 @smui/dialog ,一切正常,但我需要对话框作为基础组件,任何想法都值得赞赏~

【问题讨论】:

标签: svelte custom-element svelte-component


【解决方案1】:

使用 Svelte 构建自定义元素时,应用中的每个组件都需要使用 &lt;svelte:options tag="custom-element-name-here" /&gt; 进行编译,这使得从另一个库导入组件变得很棘手。

您可以尝试使用 Material UI 的 web component implementation,尽管它还不是 1.0:

// main.js
import App from './App.svelte';
import '@material/mwc-dialog';

const app = new App({
    target: document.body,
    props: {
        name: 'world'
    }
});

export default app;
<!-- App.svelte -->
<svelte:options tag="custom-element"/>

<h1>Hello world</h1>
<mwc-dialog heading="Test dialog" open="true">
    <div>
        Text goes here
    </div>
</mwc-dialog>

另一种选择是不编译为自定义元素并使用svelte-adapter 在 React 应用程序中使用组件。

【讨论】:

  • 相关 Svelte 功能请求:github.com/sveltejs/svelte/issues/4228
  • 谢谢很多,顺便说一句,我复制了你的代码,它运行良好,但是当我尝试获取 mwc-dialog 元素时,它返回 null,我应该怎么做才能获得正确的结果(mwc -对话元素)? lang-js console.log('----------',document.querySelector('mwc-dialog')) // null
  • 我找到了获取元素的方法,但它相当复杂console.log(Array.from(document.querySelector('custom-element').shadowRoot.childNodes).map(i=&gt;{ if(i.tagName==='MWC-DIALOG'){ console.log('element found',i) } }))
  • document.querySelector 不起作用,因为 mwc-dialog 位于自定义元素的 shadow DOM 中。尝试在 mwc-dialog 元素上使用bind:this
  • 如果您不在 Svelte 组件范围内,也可以使用 document.querySelector('custom-element').shadowRoot.querySelector('mwc-dialog')
猜你喜欢
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 2020-03-03
  • 1970-01-01
  • 2021-03-13
相关资源
最近更新 更多