svelte 可以使用可组合函数吗?

Jor*_*dan 5 javascript svelte sveltekit

我来自 vue,习惯了可组合函数。我正在尝试找出以 svelte 方式做到这一点的方法

因此,我创建了一个 js 文件并导入存储,然后尝试创建一个可以在多个组件上调用并单独操作的函数

swipe.js 文件

import { writable, derived, get } from 'svelte/store';

function createSwipe() {

  const dyFromStart = writable(0)

  function moveEvent(eventType, val){
    console.log('moveEvent', eventType, val, get(dyFromStart))
    dyFromStart.update(n => n + 1);
  }

  const dxScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
  const dyScore = derived(dyFromStart, $dyFromStart => Math.round($dyFromStart + 100));
  return {
    moveEvent,
    dxScore,
    dyScore, 
  };
}

export const swipe = createSwipe();

Run Code Online (Sandbox Code Playgroud)

然后在 .svelte 组件中导入脚本中的函数并分解为子部分

import { writable, derived, get } from 'svelte/store';

function createSwipe() {

  const dyFromStart = writable(0)

  function moveEvent(eventType, val){
    console.log('moveEvent', eventType, val, get(dyFromStart))
    dyFromStart.update(n => n + 1);
  }

  const dxScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
  const dyScore = derived(dyFromStart, $dyFromStart => Math.round($dyFromStart + 100));
  return {
    moveEvent,
    dxScore,
    dyScore, 
  };
}

export const swipe = createSwipe();

Run Code Online (Sandbox Code Playgroud)

好吧,最终我想变成一个滑动组件,因此得名,但试图了解基本原理。因此,我希望能够为每个组件拥有唯一的存储,并且为此,如果我使用多个此 .svelte 组件,则状态将在所有组件之间共享。

不仅仅是像三个 idk modal.svelte 组件一样,我想对一堆 diff 组件使用滑动,也许 photoViewer.svelte 只是通用滑动功能,并对所有组件使用相同的代码。

或者我只需要保持每个 .svelte 组件中的状态const dyFromStart = writable(0)并将let dyFromStart = 0其传递到返回结果并更新本地 .svelte 变量的纯 js 函数中

将其添加为非存储更纯的 js 东西,我正在尝试,但无法做出反应,因此接受下面关于有效且听起来像的存储方法的答案是正确的方法

export function createSwipe() {
 let dyFromStart = 0

  function moveEvent(eventType, val){
    console.log('moveEvent', eventType, val, dyFromStart, dxScore(), dyScore())
    dyFromStart++
  }

  function dxScore(){ return dyFromStart + 3 }
  // const dzScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
  const dyScore = () => Math.round(dyFromStart + 100)
  
  return {
    moveEvent,
    dxScore,
    dyScore,
    dyFromStart
  };
Run Code Online (Sandbox Code Playgroud)
export function createSwipe() {
let dyFromStart = 0
  let dxScore = dyFromStart + 3
  let dyScore = Math.round(dyFromStart + 100)

  function moveEvent(eventType, val){
    console.log('moveEvent', eventType, val, dyFromStart, dxScore, dyScore)
    dyFromStart++
    dxScore = dyFromStart + 3
    dyScore = Math.round(dyFromStart + 100)
  }

  return {
    moveEvent,
    dxScore,
    dyScore,
    dyFromStart
  };
Run Code Online (Sandbox Code Playgroud)

我想这工作得很好,只是不与 $ 发生反应,并且需要调用来更新 diff 本地变量(如果这样做)

就可组合函数类型样式而不是存储类型而言,这对我来说似乎是最优雅的或类似的东西

export function createSwipe() {
 let dyFromStart = 0

  function moveEvent(eventType, val){
    console.log('moveEvent', eventType, val)
    dyFromStart++
  }

  $: dxScore = dyFromStart + 3
  $: dyScore = Math.round($dyFromStart + 100)
  return {
    moveEvent,
    dxScore,
    dyScore, 
  };
}
Run Code Online (Sandbox Code Playgroud)

dum*_*umm 3

我不完全理解这个问题,所以我尝试首先重申我认为你想要的内容:

  • 您想在多个地方使用滑动功能
  • 该滑动功能的每次使用都应该独立于所有其他功能

如果这是正确的,那么答案很简单:不要这样做export const swipe = createSwipe()。删除该部分并导出创建函数以直接在组件中使用。这样你每次都会创建一个新的独立实例:

<script>
  import { createSwipe } from "$lib/swipe";
  let { moveEvent, dxScore, dyScore } = createSwipe()
</script>
<p>{$dxScore}{$dyScore}</p>
<button on:click="() => moveEvent">button</button>
Run Code Online (Sandbox Code Playgroud)