Svelte

<select><option> component

개바새바 2023. 5. 31. 13:45
728x90
  • +page.svelte
<select bind:value={group} class="text-xs">
   <option value='all'>전체</option>
 {#each data.group as {num, name}}
   <option value={num}>{name}</option>
 {/each}
</select>

위의 select 코드를 컴포넌트화하는 것이 최종 목표

 

  • Select.svelte
<script>
  export let value;
  export let options;
</script>

<select bind:value={value} class="text-xs">
  {#each options as option}
    <option value={option.value}>{option.text}</option>
  {/each}
</select>

  • +page.svelte
<Select bind:value={choose} options={['전체', '선택1', '선택2']} />

value와 text가 같을 때의 방식

<Select bind:value={choose} options={[
   { value: 'all', text: '전체' }, 
   { value: '1', text: '선택1' }, 
   { value: '2', text: '선택2' }]} />

value와 text가 다를 때의 방식

 

 

위의 방식은 데이터를 직접적으로 작성할 때의 방식이다.

데이터를 직접적으로 작성하지않고 외부 데이터에서 값을 가져와서 제작할 때의 방식이 코드는 다르게 작성되어야한다.

 


 

※ error : 외부 데이터를 불러오는 코드를 제작하여 실행 중 클라이언트단에서 발생한 에러.

proxy.js?v=721fd953:19 Error: 'data' is not a store with a 'subscribe' method


위의 코드에서 발생한 오류는 data 객체가 스토어가 아닌 일반적인 객체로 인식되어 오류가 발생한 것입니다.
스토어를 사용하기 위해서는 data 객체를 writable 또는 derived 스토어로 감싸주어야 합니다.

 

dataStore 변수를 writable 스토어로 감싸주는 역할은

Svelte에서 상태(state)를 관리하기 위한 메커니즘을 제공하는 것입니다.

스토어는 애플리케이션의 데이터를 저장하고, 상태 변경을 추적하며,

변경사항을 감지하여 컴포넌트에 자동으로 업데이트를 적용하는 기능을 제공합니다.

 

일반적으로, 컴포넌트의 상태는 컴포넌트의 로컬 변수로 관리됩니다.

하지만 때로는 여러 컴포넌트에서 동일한 데이터에 접근해야 할 경우가 있습니다.

이럴 때 스토어를 사용하면 데이터를 중앙에서 관리하고, 필요한 곳에서 해당 데이터에 액세스할 수 있습니다.

 

writable 스토어는 상태를 생성하고, 읽기 및 쓰기 작업을 수행할 수 있는 스토어입니다.

위의 예시에서는 data 객체를 writable 스토어로 감싸서 dataStore 변수에 할당하였습니다.

이렇게 하면 dataStore는 data 객체를 포함한 상태를 관리하는 스토어가 되는 것입니다.

 

writable 스토어는 subscribe 메서드를 제공하여 상태 변경을 감지할 수 있습니다.

따라서 dataStore의 값이 변경될 때마다 해당 값을 구독(subscribe)하고 있는 컴포넌트들은 자동으로 업데이트됩니다.

이는 Svelte의 리액티브성(reactivity)의 핵심 원리 중 하나입니다.

 

따라서 dataStore를 사용하여 data.group와 같이 스토어의 데이터에 접근하여 옵션을 생성하면,

데이터 변경이 있을 때마다 자동으로 업데이트되는 동적인 옵션을 가진 Select 컴포넌트를 구현할 수 있습니다.

 


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

    export let data;
    let dataStore = writable(data);
    let group;
</script>

<Select bind:value={group} 
    options={[{ value: 'all', text: '전체' }, ...$dataStore
    .group.map(item => ({ value: item.num, text: item.name }))]} />

최종 완성 코드

 

위의 예시 코드에서는 data.group 배열의 각 객체를 map 함수를 사용하여 options 배열에 추가하고 있습니다.
data.group 배열의 각 객체를 options 배열에 추가하기 위해 전개 연산자(...)를 사용하고 있습니다.

 

map 함수를 사용하여 배열의 각 요소에 대해 새로운 객체를 생성하고, 

해당 객체의 value 속성과 text 속성을 각각 item.num와 item.name으로 설정하고 있습니다.

이렇게 작성하면 data.group 배열의 각 객체를 순회하며 옵션 객체를 생성하여 options 배열에 추가할 수 있습니다.


따라서 위의 코드를 사용하면 data.group 배열의 데이터를 each 문을 통해 동적으로 불러와 

Select 컴포넌트의 옵션으로 사용할 수 있습니다.

 

이렇게 작성된 코드를 사용하면 Select 컴포넌트가 렌더링되고, 옵션들이 표시됩니다. 

선택된 옵션의 값은 group 변수에 바인딩되어 있으며, 변경될 때마다 group 변수의 값이 업데이트됩니다.

 

 

 


  • Select.svelte
<select bind:value={choose} class="text-xs">
  <slot/>
</select>

Select 컴포넌트에 option 을 직접적으로 작성하고 싶다면

<slot/> 선언을 하여 내부에 코드를 작성하여 사용할 수 있도록 해야한다.

 

 

 

728x90