【问题标题】:Adding svelte component to gridstack将苗条组件添加到gridstack
【发布时间】:2021-03-07 11:45:49
【问题描述】:

我正在尝试将 Svelte 与 gridstack 一起使用。但是当我在 js 中添加我的 Svelte 组件时,它并没有正确显示。这会添加一个按钮,但样式不起作用,并且输出不会打印到日志中。

<script>
  import { onMount } from "svelte";
  import Button from "./Button.svelte";
  import GridStack from "gridstack/dist/gridstack.all.js";
  import "gridstack/dist/gridstack.min.css";

  onMount(() => {
    var grid = GridStack.init();
    grid.addWidget({ width: 2, content: "<p>Hello</p>" });
    grid.addWidget({ width: 2, content: "<Button />" });
  });
</script>

<style>
</style>

<div class='grid-stack'></div>

完整示例:https://codesandbox.io/s/gallant-roentgen-jmnis?file=/App.svelte

【问题讨论】:

  • 您没有传递&lt;Button&gt; 组件,而是传递了"&lt;Button/&gt;" 字符串,该字符串被解析为HTML。

标签: svelte gridstack


【解决方案1】:

正如 Rich 在他的评论中提到的,您不能在运行时被 gridstack.js 解释为 HTML 的字符串中使用 Svelte 组件。为了让 Svelte 编译器发挥它的魔力,组件必须是标记的一部分,而不是在字符串中。

例如,这将是如何在 gridstack 容器下方添加按钮组件:

<div class='grid-stack'></div>
<Button />

现在我们有了交互式&lt;Button /&gt;,我们只需要弄清楚如何在网格堆栈中移动它。

幸运的是,gridstack addWidget function 也可以接受 DOM 节点而不是 HTML 字符串,所以我们可以这样做:

let elementWhichContainsButton; // TODO get a reference to the parent of <Button />
const widget = grid.addWidget(elementWhichContainsButton.firstChild, { width: 2 });

实现此目的的一种方法是使用Svelte action

有一些额外的逻辑(在 Promise 中包装网格并使用 {#await ...})来确保在网格初始化之前不添加小部件:

<script>
  /* ... imports go here ... */

  const gridPromise = new Promise(resolve => {
    onMount(() => {
      const grid = GridStack.init();
      grid.addWidget({ width: 2, content: "<p>Hello</p>" });
      resolve(grid);
    });
  });

  function addToGrid(element, grid) {
    grid.addWidget(element.firstChild, { width: 2 });
  }
</script>

<div class='grid-stack'></div>

{#await gridPromise then grid}
  <div use:addToGrid={grid}>
    <div><Button /></div>
  </div>
{/await}

当从 DOM 中删除元素时,一个适当的解决方案可能还应该从网格中删除该元素。根据Svelte action documentation,这可以通过返回一个destroy()方法来实现:

function addToGrid(element, grid) {
  const widget = grid.addWidget(element.firstChild, { width: 2 });

  return {
    destroy() {
      grid.removeWidget(widget);
    }
  };
}

解决方案的完整演示可在此处获得:https://codesandbox.io/s/mystifying-field-x2mkr?file=/App.svelte

【讨论】:

    【解决方案2】:

    在 GridStack 3+ 版本中,根据ValarDohaeriss 的回答,我做了一些 GridStack 3+ 所需的重要修改。

    进口变化:

        import "gridstack/dist/gridstack.min.css";
        import GridStack from "gridstack/dist/gridstack-h5";
        import "gridstack/dist/h5/gridstack-dd-native"; //  HTML5 drag&drop
    
    1. 使用“w”而不是“宽度”

    2. 您必须手动将 HTML 元素(= 即 svelte 组件)添加到 GridStack 元素。然后 - 通知 GridStack 添加了新元素。这是带有变化的新功能:

    
            function addToGrid(element, grid) {
                // In GridStack 3 we use "w" instead of "width"
                const widget = grid.addWidget(element.firstChild, { w: 1, h: 2, y: 3, x: 4 });
                // We set an id for this widget
                widget.id = "abc";
                // Then we append it manually to GridStack html element
                grid.el.appendChild(widget);
                // And then - we inform GridStack, that a new element is added.
                grid.makeWidget("#abc");
        
                return {
                  destroy() {
                     grid.removeWidget(widget);
                 }
        
              };
        
            }
    

    GridStack 3.2.0 的完整示例可在此处获得:https://codesandbox.io/s/great-worker-yq2e9?file=/App.svelte:786-1292

    【讨论】:

      猜你喜欢
      • 2021-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      相关资源
      最近更新 更多