Сохранить привязку окна в svelte store

Привет милые люди интернета,

Я создал слушателя для позиции прокрутки пользователя: <svelte:window bind:scrollY={y} /> Я хотел бы сохранить эту переменную в магазине, чтобы сделать ее доступной для всего веб-сайта. Но для этого мне понадобится сеттер. Есть ли эффективный способ сделать это?

Я пробовал это, но не работает:

  $: () => scrollPos.set(y);
  $: console.log("LOG: scrollPos", $scrollPos);```

person Gh05d    schedule 31.10.2019    source источник


Ответы (3)


Вот код:

<script>
import { y } from './store.js';
import LogScrollPosition from './LogScrollPosition.svelte';

let scrollY;
$: y.set(scrollY);
</script>

<button on:click={() => scrollY = 200}>
    Go down
</button>

<h1>Hello!</h1>

<LogScrollPosition />

<p>
Vestibulum arcu turpis, condimentum non lorem quis, volutpat laoreet turpis. Praesent euismod, libero eu pulvinar imperdiet, dolor ex molestie lacus, sed egestas arcu felis non libero. Aenean laoreet arcu porttitor dolor pulvinar eleifend. Pellentesque lacinia neque sit amet nulla blandit, at ullamcorper orci ultricies. Cras pulvinar nec est sit amet sollicitudin. Sed luctus massa nibh, eu luctus magna tincidunt vel. Morbi tempor velit elit, nec cursus risus pellentesque quis. Aliquam erat volutpat. Vivamus tristique lacus vel lorem lacinia, a accumsan turpis gravida. Maecenas dapibus gravida mauris, iaculis placerat urna rhoncus at. Vivamus vel malesuada nisi. Suspendisse pulvinar pellentesque lectus, non imperdiet nisi tempus sed. Maecenas vel magna eu diam faucibus semper ut nec neque.

Aliquam malesuada gravida libero, sit amet pellentesque felis viverra vel. Maecenas est tortor, eleifend ut est nec, maximus vehicula eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque tincidunt fringilla urna id fermentum. Proin rhoncus iaculis ipsum. In a sapien sapien. Sed eget justo ac turpis sodales imperdiet. In condimentum mauris ut ex sagittis, id malesuada ligula dictum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

Vivamus volutpat id velit et vehicula. Vivamus lectus orci, aliquam a maximus et, rhoncus in nibh. Etiam interdum sagittis justo et scelerisque. Quisque dapibus pulvinar pulvinar. Curabitur pulvinar, odio id eleifend consequat, sapien nulla congue metus, ut porttitor massa ipsum eget mauris. Duis a facilisis velit, non semper massa. Vestibulum semper velit nisi, sit amet blandit eros consectetur sit amet. Morbi accumsan magna a ex tempus imperdiet. Duis vitae convallis ipsum, imperdiet efficitur magna. Praesent ultrices turpis nec enim molestie, non aliquet tellus luctus. Sed porttitor nibh sit amet metus malesuada imperdiet et vitae ligula. Donec sit amet ullamcorper nisl. Nulla rhoncus ligula non tellus finibus efficitur. Nullam accumsan mattis risus at cursus. Duis ligula ligula, ullamcorper ac risus nec, hendrerit vulputate massa.

Phasellus pellentesque mauris ligula, id dapibus nisi lobortis a. In eget quam tincidunt, mattis ante eu, dignissim nisl. Proin sollicitudin dolor porttitor, tincidunt ipsum at, consequat leo. Morbi consequat imperdiet mauris, sed maximus tellus venenatis ut. Vestibulum tempus nisi ac semper volutpat. Vivamus rhoncus augue eu erat aliquet sodales. Ut consequat sapien enim, in pulvinar mauris dapibus varius. In mi mi, aliquam vel ante eu, lobortis aliquet lorem. Donec vulputate ac lorem ac laoreet.
</p>

<svelte:window bind:scrollY={scrollY} />

По сути, вы были близки, но не делайте функцию реактивной с $: () => .... Просто сделай $: scrollPos.set(y).

Вот пример REPL.

person parker_codes    schedule 31.10.2019

Вы должны иметь возможность просто привязать непосредственно к значению магазина:

<script>
    import { writable } from 'svelte/store';

    const y = writable(0);
</script>

<svelte:window bind:scrollY={$y}/>

К сожалению, вы обнаружили ошибку, которая в настоящее время не работает по какой-либо причине. Я открыл здесь проблему: https://github.com/sveltejs/svelte/issues/3832

person Rich Harris    schedule 31.10.2019

Реактивные операторы будут повторно оцениваться, когда значения, от которых они зависят, изменятся, поэтому вы можете просто сделать scrollPos.set(y) реактивным, и он будет работать, как ожидалось.

Пример (REPL)

<svelte:window bind:scrollY={y} />

<script>
  import { writable } from 'svelte/store';

  let y;
  const scrollPos = writable(0);

  $: scrollPos.set(y);
</script>

<div style="height:1000px;">
  <h1 style="margin-top:200px;">{$scrollPos}</h1>
</div>
person Tholle    schedule 31.10.2019