【问题标题】:Svelte - is there a way to use JS inside #each?Svelte - 有没有办法在#each 中使用 JS?
【发布时间】:2022-05-07 20:39:13
【问题描述】:

我正在迭代一个数据数组,我想在渲染它之前对其进行一些处理。

我知道我可以创建一个新组件并将数组条目传递给 i,并在该子组件内进行处理,或者我可以添加一个辅助函数 getClass(entry) 或者我可以内联一个三元运算符,

但我想知道是否有办法做这样的事情,将一些代码内联到每个块中。非功能示例:



<div class="Menu">
  {#each menuEntries as entry, i }
    {{ 
      let classes = entry.classes;
      
      if (entry.submenu) {
        classes += ' has-submenu';
      }
     }}
      
      <div class="menu-entry {classes}">...</div>
  {/each}
</div>


编辑:

这似乎是一种解决方法。唯一的问题是 classes 必须在循环之前定义。

<script>
let classes = '';
</script>
<div class="Menu">
  {#each menuEntries as entry, i }
    {(() => {
      classes = entry.classes;
      
      if (entry.submenu) {
        classes += ' has-submenu';
      }
      return ''; // return empty string so Svelte does not print it
     })()}
      
      <div class="menu-entry {classes}">...</div>
  {/each}
</div>


【问题讨论】:

  • ...

标签: javascript svelte svelte-3


【解决方案1】:

您可以使用 Array.map 函数进行一些额外的处理。

这样,您可以使用映射“this”添加可选参数,并使用映射函数返回的 [....] 使用其他循环变量。

例子:

{#each menuEntries.map(extraProcessing, thisArg) as [entry, arg2, arg3] , i }

  ... loop using entry, arg2, arg3, i

{/each} 

extraProcessing 函数示例:

function extraProcessing(entry, idx) {

   ... do something using: entry, idx and this (thisArg)

return [entry, arg2, arg3]

还有一个here a REPL 和你的例子。

【讨论】:

    【解决方案2】:

    如果您只想激活一个类,如果条目具有子菜单属性,您可以使用条件类 this

    <style>
        .has-submenu {/* your conditional css */}
    </style>
    
    <div class="Menu">
      {#each menuEntries as entry, i }      
          <div
              class={"menu-entry " + entry.classes}
              class:has-submenu={entry.submenu}
          >
              ...
          </div>
      {/each}
    </div>
    

    请注意,class:has-submenu={entry.submenu} 仅当 entry.submenu 本身为真(非 null、未定义、0 等)时才会评估为 true 并激活类,所以如果这是一个问题,您应该直接检查属性是否存在

    【讨论】:

      【解决方案3】:

      对于那些需要在#each 块内进行一些计算的人,您可以使用@const 语句。

      <script>
        const items = ['a', 'b', 'c'];
      </script>
      
      {#each items as item}
        {@const exclamationMark = item + '!'}
      
        <p>{exclamationMark}</p>
      {/each}
      

      【讨论】:

        【解决方案4】:

        另一种解决方案是使用 Svelte 组件处理数据并使用槽返回结果。

        您可以添加一个名为 Process.svelte 的组件,该组件接收参数和函数,调用函数的结果将在 slot prop 中提供。

        <script>
            export let args = {}
            export let process
        </script>
        
        <slot res={process(args)}/>
        

        导入 Process.svelte

        <script>
            import Process from './Process.svelte'
            let menuEntries = []
        </script>
        
        <div class="Menu">
          {#each menuEntries as entry, i }
              <Process process={() => {
              let a= entry.classes;
              if (entry.submenu) {
                a+= ' has-submenu';
              }
              return a; // the return value can be accessed by the children via let:res
             }} let:res>
                        <div class="menu-entry {res}">...</div>
               </Process>
          {/each}
        </div>
        

        【讨论】:

          猜你喜欢
          • 2020-08-20
          • 1970-01-01
          • 1970-01-01
          • 2021-03-26
          • 2016-03-03
          • 2020-09-30
          • 2021-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多