Svelte#2 - Svelte + graphQL + apollo

이강원·2020년 3월 4일
0

svelte

목록 보기
2/2
post-thumbnail

svelte에서 graphql 을 사용해보자.

기본적인 Svelte install 및 setting은 알고 있다는 전제로 이 포스트를 쓴다. 또한 이 안에서 쓴 scss코드들을 일일이 적진 않겠다.

Svelte 소개에 관한 포스트만 좀 많이 보이고, 더군다나 Svelte기능중에 slot 및 graphQL과 같이 쓴 포스트는 아직까지는 다른 svelte관련 자료들에 비해 양이 적은거 같아 이 포스트에서는 가상의 event list Data를 Graphql로 받아와서 Svelte기능중 Slot을 사용해 테스트해본 기록을 써보고자 한다.

Setting

svelte에서 graphqlapollo client server를 세팅하려면 3가지 추가 모듈이 필요하다. graphql / apollo-boost / svelte-apollo 이 3가지를 설치해보자.

npm i -D graphql apollo-boost svelte-apollo 
yarn add --dev graphql apollo-boost svelte-apollo 

App.svelte

svelte에서 apollo를 Basic 기준에서 쓰는법은 굉장히 간단했다. 그냥 개인적으로는 쉽게 풀어보자면 Main Entry 파일인 App.svelte 파일에서 Apollo client server를 setting해주고 필요한 component에서 get해서 쓰면 된다라고 생각하자.

물론 Deep 하게 들어가면 다르지만, 이렇게 마인드 컨트롤해야 진입장벽이 낮아지지 않을까..?

App.svelte

<script>
  import ApolloClient from 'apollo-boost';
  import { setClient } from 'svelte-apollo';
  
  const client = new ApolloClient({
    uri: 'http://localhost:7077/graphql',
  });

  setClient(client);
</script>

<section class="contents">
  <Router {routes}/>
</section>

<style lang="scss">
  ...your style
</style>

sampleData

하단의 예시 Data는 지난 Graphql 포스트 내용에서 추가했던 Data이다.
이 Data를 기준으로 slot을 이용해서 component를 만들어보자.

[
  {
    "duration": {
      "date": "YYYY.MM.DD ~ YYYY.MM.DD",
      "time": "08:00 ~ 18:00"
    },
    "value": {
      "type": "EVENT",
      "link": "https://www.dummylink.com",
      "imgUrl": "https://dummyimage.com/720x400/ff0808/fff.png&text=event+01",
      "imgAlt": "event01",
      "imgWidth": 720,
      "imgHeight": 400
    },
    "pushAgree": false
  },
  {
    "duration": {
      "date": "YYYY.MM.DD ~ YYYY.MM.DD",
      "time": "08:00 ~ 18:00"
    },
    "value": {
      "type": "EVENT",
      "link": "https://www.dummylink.com",
      "imgUrl": "https://dummyimage.com/720x400/ff8400/fff.png&text=event+02",
      "imgAlt": "event02",
      "imgWidth": 720,
      "imgHeight": 400
    },
    "pushAgree": false
  }
]

svelte slot

slot이란 Vue,web componentslot, reactchildren이랑 비슷한 개념이다.
이벤트 Data를 받아서 뿌려줄 흔한 리스트 레이아웃을 짜보자.

cardList.svelte

<script>
  export let list;
</script>

<ul>
  {#each list as item, index}
  <li>
    <slot {item} {index}>
      <span>"컨텐츠가 없습니다"</span>
    </slot>
  </li>
  {/each}
</ul>

<style lang="scss">
  ...your style
</style>

li tag 밑에 slot 이라는 태그가 들어가있는걸을 확인했을 것이다. 이 slot이라는걸 쉽게 생각해보면 slot을 대신해 같은 props를 받아서 활용할 수 있는 어떠한 컴포넌트를 넣어도 사용할수가 있다 라는 얘기다.

  • list: 상위 컴포넌트에서 props로 받는 Array가 된다.
  • item: Array[index]값이다.
  • index: each 문의 2번째 인자로 말 그대로 index이다.
  • Slot태그 안에 있는 내용은 Default값이다.
  • Slot 안에는 String, HTML, Component중 어떤것이든 들어갈 수 있다.

제일 중요한 점은 slot 태그를 포함하고 있는 component안에는 절대로 business logic이 들어가면 안된다!!!!!

위에서 item과 index를 props로 받아서 하위에 component를 slot에다 맞게 껴주게 되면 작동하게 된다. 이 컴포넌트를 다른곳에서 쓰려면 아래처럼 쓰인다.

<CardList list={data} let:item={item} let:index={index}></CardList>

Event.svelte

이 파일은 CardList.svelte파일의 부모 component로써 App.svelte에서 setting 해놓은 Apollo client server를 여기에서 get할 것이다.

script

<script>
  import { gql } from 'apollo-boost';
  import { getClient, query } from 'svelte-apollo';
  import CardList from '~/components/common/CardList';

  const DATA = gql`
    {
      events{
        duration{
          date
          time
        }
        value{
          type
          link
          imgUrl
          imgAlt
          imgWidth
          imgHeight
        }
        pushAgree
      }
    }
  `;

  const client = getClient();
  export const datas = query(client, { query: DATA });
</script>

CardList Component with slot

{#await $datas}
<Loading />
  {:then result}
  <CardList list={result.data.events} let:item={item} let:index={index}>
    <!-- S: Slot 에 들어가는 html -->
    <a href="{item.value.link}" class="link">
      <img src="{item.value.imgUrl}" class="img" alt="{item.value.imgAlt}">
      <div class="title">
        <b>{item.value.imgAlt}</b>
        <span class="date">({item.duration.date}) - {item.duration.time}</span>
      </div>
      <div class="notic">
        <span class="text">이벤트 알림을 받겠습니다.</span>
        <Checkbox agree={item.pushAgree} {index} />
      </div>
    </a>
    <!-- E: Slot 에 들어가는 html -->
  </CardList>
  {:catch error}
  <p>ERROR : {error}</p>
{/await}
  • $: datas<code>datas의 <code>은 Apollo에서 제공하는 watchQuery로서 쿼리를 다시 가져 오거나 해당 쿼리와 관련된 데이터가 다른 곳에서 변경 될 때마다 지속적으로 쿼리를 감시하는 method로 업데이트 된 데이터를 계속 생성한다.
  • result: graphQL 통신후 result라는 method로 promise를 반환하고 그 안에 data에 설정해 두었던 Event Data가 들어있다.

여기까지 하면 아래와 같은 테스트 페이지가 완성이 된다.

test완성본

Svelte html안에서 console 사용법

  1. 일반 script파일 안에서야 그냥 console을 보고싶다면 console.log를 찍으면 되지만 html template안에서 그냥 찍으면 볼수가 없다. 이때는 {(console.log(datas))}이런식으로 html 안에서 사용하면 실제 화면에는 안찍힐지 몰라도 console에는 찍히게 된다.
  2. 2번째 방법은 console을 찍는건 아니지만 debugging tool에 break point를 거는 방법이다. 이 역시 마찬가지로 html tag안에 어디서든 {@debug datas}이런식으로 찍게되면 그 시점에 break point가 걸리게 되고 debugging이 가능하다.

마치며,

Svelte의 관심도가 날로 갈수록 커져가고 있다. 하지만 어떤 회사든 FrameWork를 바꾸기는 어려운일이기에 실제 적용한 사례는 많이 찾아보기 힘들다. Library인 React와 Framework인 Vue가 워낙 강력하게 지키고 있어서일까... 그래서인지 현재는 이렇게라도 사용해 보고싶었다. 기회가 되면 오늘 쓴 포스트랑 연결해서 특정 이벤트를 크롤링 해오는 PWA(Progressive Web App)를 이용한 Side project로 연결시켜 Svelte 개발을 이어가보고 싶다.

profile
양산현 포스트를 쓰고싶진 않다. 공식예제를 그대로 가져다 붙이기도 싫다.그냥 내가 경험했던걸 토대로 기록하고자 한다. 내 글의 헤비 커스토머는 내 자신이다.

0개의 댓글