Can svelte use composable functions?

Viewed 473

I am coming from vue and used to composable functions. I am trying to figure out the way to do this in svelte

So I make a js file and import store and then was trying to make a function that I could call on multiple components and act individually

swipe.js file

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();

then in .svelte component import function in script and decompose into subparts

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

Well eventually I want to turn into a swipe component hence name but trying to get fundamentals down. So I want to be able to have unique store for each component and for this if I use multiple of this .svelte component the state is shared amongst all.

And not just like three idk modal.svelte components I want to use swipe for a bunch of diff components maybe a photoViewer.svelte right just generic swipe function and use same code for all.

or would I just have to keep the state like const dyFromStart = writable(0) be just let dyFromStart = 0 in each .svelte component and pass it into a pure js function that returns results and update local .svelte variables

Adding this as the non store more pure js things I was trying but couldn't get to be reactive so accepting the answer below on store method that worked and sounds like is the correct approach

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
  };
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
  };

I suppose that works fine just not reactive with $ and need to call to update a diff local var if doing that

this would seem most sveltey to me or something like it as far as composable function type style not store type

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, 
  };
}
1 Answers

I don't understand the question fully, so I try to reiterate first what I think you want:

  • You want to use your swipe function in multiple places
  • Each usage of that swipe function should be independent of all others

If that's correct, then the answer is simple: Don't do export const swipe = createSwipe(). Delete that part and instead export the create function to use directly within your components. That way you create a new independent instance each time:

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