将苗条组件添加到gridstack

Posted

技术标签:

【中文标题】将苗条组件添加到gridstack【英文标题】:Adding svelte component to 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 【参考方案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

    使用“w”而不是“宽度”

    您必须手动将 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

【讨论】:

以上是关于将苗条组件添加到gridstack的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用传递给组件的变量设置苗条样式的 css 属性值吗

苗条故事书的包装器元素

v显示苗条的替代品

苗条的组件不刷新

如何在苗条的故事书中使用“插槽”

如何继承带有苗条组件的插槽?