svelte에서 graphql 을 사용해보자.
기본적인 Svelte install 및 setting은 알고 있다는 전제로 이 포스트를 쓴다. 또한 이 안에서 쓴 scss코드들을 일일이 적진 않겠다.
Svelte 소개에 관한 포스트만 좀 많이 보이고, 더군다나 Svelte기능중에 slot 및 graphQL과 같이 쓴 포스트는 아직까지는 다른 svelte관련 자료들에 비해 양이 적은거 같아 이 포스트에서는 가상의 event list Data를 Graphql로 받아와서 Svelte기능중 Slot을 사용해 테스트해본 기록을 써보고자 한다.
svelte
에서 graphql 및 apollo 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
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>
하단의 예시 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
}
]
slot
이란 Vue
,web component
의 slot, react
의 children이랑 비슷한 개념이다.
이벤트 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를 받아서 활용할 수 있는 어떠한 컴포넌트를 넣어도 사용할수가 있다 라는 얘기다.
제일 중요한 점은 slot 태그를 포함하고 있는 component안에는 절대로 business logic이 들어가면 안된다!!!!!
위에서 item과 index를 props로 받아서 하위에 component를 slot에다 맞게 껴주게 되면 작동하게 된다. 이 컴포넌트를 다른곳에서 쓰려면 아래처럼 쓰인다.
<CardList list={data} let:item={item} let:index={index}></CardList>
이 파일은 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}
watchQuery
로서 쿼리를 다시 가져 오거나 해당 쿼리와 관련된 데이터가 다른 곳에서 변경 될 때마다 지속적으로 쿼리를 감시하는 method로 업데이트 된 데이터를 계속 생성한다.여기까지 하면 아래와 같은 테스트 페이지가 완성이 된다.
test완성본{(console.log(datas))}
이런식으로 html 안에서 사용하면 실제 화면에는 안찍힐지 몰라도 console에는 찍히게 된다.{@debug datas}
이런식으로 찍게되면 그 시점에 break point가 걸리게 되고 debugging이 가능하다.Svelte의 관심도가 날로 갈수록 커져가고 있다. 하지만 어떤 회사든 FrameWork를 바꾸기는 어려운일이기에 실제 적용한 사례는 많이 찾아보기 힘들다. Library인 React
와 Framework인 Vue
가 워낙 강력하게 지키고 있어서일까... 그래서인지 현재는 이렇게라도 사용해 보고싶었다. 기회가 되면 오늘 쓴 포스트랑 연결해서 특정 이벤트를 크롤링 해오는 PWA
(Progressive Web App)를 이용한 Side project로 연결시켜 Svelte 개발을 이어가보고 싶다.