SvelteKit 차세대 애플리케이션 프레임워크라고 부르는 것 중 최신 버전입니다. 물론 Next가 영원히 수행한 파일 기반 라우팅, 배포 및 서버 측 렌더링을 통해 애플리케이션을 스캐폴드합니다. 그러나 SvelteKit은 중첩된 레이아웃, 페이지의 데이터를 동기화하는 서버 변형 및 우리가 다룰 기타 세부 사항도 지원합니다.
이 게시물은 SvelteKit을 한 번도 사용해 본 적이 없는 모든 사람에게 약간의 흥미를 불러일으킬 수 있는 높은 수준의 소개를 제공하기 위한 것입니다. 편안한 투어가 될 것입니다. 당신이 보는 것을 좋아한다면, 전체 문서는 여기.
어떤 의미에서 이것은 작성하기 어려운 게시물입니다. SvelteKit은 애플리케이션 프레임워크. 응용 프로그램을 구축하는 데 도움이 되도록 존재합니다. 데모하기가 어렵습니다. 블로그 게시물에 전체 애플리케이션을 구축하는 것은 불가능합니다. 그래서 대신 우리는 우리의 상상력을 조금 사용할 것입니다. 우리는 응용 프로그램의 뼈대를 만들고 일부 빈 UI 자리 표시자와 하드 코딩된 정적 데이터를 갖게 됩니다. 목표는 실제 애플리케이션을 구축하는 것이 아니라 SvelteKit의 움직이는 부분이 작동하는 방식을 보여주어 자신만의 애플리케이션을 구축할 수 있도록 하는 것입니다.
이를 위해 검증된 To-Do 애플리케이션을 예제로 빌드합니다. 하지만 걱정하지 마세요. 이것은 또 다른 To-Do 앱을 만드는 것보다 SvelteKit이 어떻게 작동하는지 보는 것에 관한 것입니다.
이 게시물의 모든 코드는 GitHub에서 사용 가능. 이 프로젝트는 또한 Vercel에 배포 라이브 데모.
프로젝트 만들기
새로운 SvelteKit 프로젝트를 시작하는 것은 충분히 간단합니다. 달리다 npm create your-app-name
터미널에서 질문 프롬프트에 답하십시오. "Skeleton Project"를 선택해야 하지만 TypeScript, ESLint 등에 대해 원하는 대로 선택하십시오.
프로젝트가 생성되면 다음을 실행합니다. npm i
및 npm run dev
개발 서버가 실행되기 시작해야 합니다. 불을 붙이다 localhost:5173
브라우저에 스켈레톤 앱의 자리 표시자 페이지가 표시됩니다.
기본 라우팅
공지 사항 routes
아래의 폴더 src
. 여기에는 모든 경로에 대한 코드가 있습니다. 이미 +page.svelte
루트에 대한 내용이 있는 파일 /
노선. 파일 계층 구조의 어디에 있든 해당 경로의 실제 페이지에는 항상 이름이 있습니다. +page.svelte
. 이를 염두에 두고 페이지를 만들어 보겠습니다. /list
, /details
, /admin/user-settings
및 admin/paid-status
, 또한 각 페이지에 대한 일부 텍스트 자리 표시자를 추가합니다.
파일 레이아웃은 다음과 같아야 합니다.
브라우저 주소 표시줄에서 URL 경로를 변경하여 탐색할 수 있어야 합니다.
레이아웃
우리는 앱에 내비게이션 링크를 원하지만 우리가 만드는 각 페이지에 대한 마크업을 복사하고 싶지는 않습니다. 그래서, 생성하자 +layout.svelte
우리의 루트에 파일 routes
SvelteKit이 모든 페이지에 대한 전역 템플릿으로 취급할 폴더입니다. 콘텐츠를 추가해 보겠습니다.
<nav> <ul> <li> <a href="/ko/">Home</a> </li> <li> <a href="/ko/list">To-Do list</a> </li> <li> <a href="/ko/admin/paid-status">Account status</a> </li> <li> <a href="/ko/admin/user-settings">User settings</a> </li> </ul>
</nav> <slot /> <style> nav { background-color: beige; } nav ul { display: flex; } li { list-style: none; margin: 15px; } a { text-decoration: none; color: black; }
</style>
몇 가지 기본 스타일이 포함된 기본적인 탐색. 특히 중요한 것은 <slot />
꼬리표. 이것은 지원 웹 구성 요소 및 Shadow DOM과 함께 사용하는 슬롯가 아니라 콘텐츠를 넣을 위치를 나타내는 Svelte 기능입니다. 페이지가 렌더링되면 페이지 콘텐츠가 슬롯이 있는 곳으로 슬라이드됩니다.
이제 내비게이션이 생겼습니다! 우리는 어떤 디자인 대회에서도 이기지 못할 것입니다. 그러나 우리는 그렇게 하려고 하지 않습니다.
중첩된 레이아웃
모든 관리 페이지가 방금 구축한 일반 레이아웃을 상속하고 모든 관리 페이지(관리 페이지만 해당)에 공통적인 몇 가지 사항을 공유하려면 어떻게 해야 합니까? 문제 없습니다. 다른 항목을 추가합니다. +layout.svelte
루트에 있는 파일 admin
그 아래에 있는 모든 항목에 상속됩니다. 그렇게 하고 다음 콘텐츠를 추가해 보겠습니다.
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
관리자 페이지임을 나타내는 빨간색 배너를 추가한 다음 이전과 마찬가지로 <slot />
페이지 콘텐츠를 이동하려는 위치를 나타냅니다.
렌더링 전의 루트 레이아웃입니다. 루트 레이아웃 내부에는 <slot />
꼬리표. 중첩된 레이아웃의 콘텐츠는 루트 레이아웃의 <slot />
. 마지막으로 중첩된 레이아웃은 자체적으로 정의합니다. <slot />
, 페이지 콘텐츠가 렌더링됩니다.
관리자 페이지로 이동하면 새로운 빨간색 배너가 표시됩니다.
데이터 정의
이제 실제 데이터를 렌더링해 보겠습니다. 최소한 실제 데이터를 렌더링하는 방법을 살펴보겠습니다. 데이터베이스를 만들고 연결하는 XNUMX가지 방법이 있습니다. 이 게시물은 DynamoDB를 관리하는 것이 아니라 SvelteKit에 관한 것이므로 대신 일부 정적 데이터를 "로드"합니다. 그러나 실제 데이터에 사용하는 것과 동일한 모든 기계를 사용하여 읽고 업데이트합니다. 실제 웹 앱의 경우 정적 데이터를 반환하는 함수를 사용하는 모든 데이터베이스에 연결하고 쿼리하는 함수로 교체하십시오.
아주 간단한 모듈을 만들어 봅시다. lib/data/todoData.ts
실제 쿼리를 시뮬레이션하기 위해 인공 지연과 함께 일부 정적 데이터를 반환합니다. 당신은 이것을 볼 수 있습니다 lib
다음을 통해 다른 곳에서 가져온 폴더 $lib
. 이것은 특정 폴더에 대한 SvelteKit 기능이며 자신의 별칭 추가.
let todos = [ { id: 1, title: "Write SvelteKit intro blog post", assigned: "Adam", tags: [1] }, { id: 2, title: "Write SvelteKit advanced data loading blog post", assigned: "Adam", tags: [1] }, { id: 3, title: "Prepare RenderATL talk", assigned: "Adam", tags: [2] }, { id: 4, title: "Fix all SvelteKit bugs", assigned: "Rich", tags: [3] }, { id: 5, title: "Edit Adam's blog posts", assigned: "Geoff", tags: [4] },
]; let tags = [ { id: 1, name: "SvelteKit Content", color: "ded" }, { id: 2, name: "Conferences", color: "purple" }, { id: 3, name: "SvelteKit Development", color: "pink" }, { id: 4, name: "CSS-Tricks Admin", color: "blue" },
]; export const wait = async amount => new Promise(res => setTimeout(res, amount ?? 100)); export async function getTodos() { await wait(); return todos;
} export async function getTags() { await wait(); return tags.reduce((lookup, tag) => { lookup[tag.id] = tag; return lookup; }, {});
} export async function getTodo(id) { return todos.find(t => t.id == id);
}
할 일 항목의 플랫 배열을 반환하는 함수, 태그 조회, 단일 할 일을 가져오는 함수(세부 정보 페이지에서 마지막 항목 사용).
데이터 로드
해당 데이터를 Svelte 페이지로 가져오려면 어떻게 해야 합니까? 여러 가지 방법이 있지만 지금은 +page.server.js
우리의 파일 list
폴더에 넣고 다음 콘텐츠를 넣습니다.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
우리는 정의 load()
페이지에 필요한 데이터를 가져오는 기능. 우리는 지원 await
-ing 호출 우리 getTodos
및 getTags
비동기 함수. 이렇게 하면 태그를 로드하기 전에 할 일 항목이 들어올 때까지 기다릴 때 데이터 로드 폭포가 생성됩니다. 대신, 우리는 원시 약속을 반환합니다. load
, SvelteKit은 필요한 작업을 수행합니다. await
그들.
그렇다면 페이지 구성 요소에서 이 데이터에 어떻게 액세스합니까? SvelteKit은 data
데이터가 있는 구성 요소를 위한 소품입니다. 다음을 사용하여 할 일 항목과 태그에 액세스합니다. 반응 할당.
목록 페이지 구성 요소는 이제 다음과 같습니다.
<script> export let data; $: ({ todo, tags } = data);
</script> <table cellspacing="10" cellpadding="10"> <thead> <tr> <th>Task</th> <th>Tags</th> <th>Assigned</th> </tr> </thead> <tbody> {#each todos as t} <tr> <td>{t.title}</td> <td>{t.tags.map((id) => tags[id].name).join(', ')}</td> <td>{t.assigned}</td> </tr> {/each} </tbody>
</table> <style> th { text-align: left; }
</style>
그리고 이것은 할 일 항목을 렌더링해야 합니다!
레이아웃 그룹
세부 정보 페이지로 이동하여 데이터를 변경하기 전에 정말 깔끔한 SvelteKit 기능을 살펴보겠습니다. 레이아웃 그룹. 우리는 이미 모든 관리 페이지에 대한 중첩된 레이아웃을 보았지만 파일 시스템의 동일한 수준에서 임의의 페이지 간에 레이아웃을 공유하려면 어떻게 해야 할까요? 특히 List 페이지와 Details 페이지 사이에서만 레이아웃을 공유하려면 어떻게 해야 할까요? 우리는 이미 그 수준에 글로벌 레이아웃을 가지고 있습니다. 대신 다음과 같이 괄호 안에 있는 이름으로 새 디렉터리를 만들 수 있습니다.
이제 목록 및 세부 정보 페이지를 포함하는 레이아웃 그룹이 생겼습니다. 나는 그것을 명명했다 (todo-management)
하지만 원하는 대로 이름을 지정할 수 있습니다. 명확히 하기 위해 이 이름은 지원 레이아웃 그룹 내부 페이지의 URL에 영향을 미칩니다. URL은 동일하게 유지됩니다. 레이아웃 그룹을 사용하면 디렉토리 전체를 구성하지 않고 공유 레이아웃을 페이지에 추가할 수 있습니다. routes
.
We 수 추가하다 +layout.svelte
파일과 약간의 바보 <div>
"Hey we're management to-dos"라는 배너. 하지만 좀 더 흥미로운 일을 해봅시다. 레이아웃은 다음을 정의할 수 있습니다. load()
그 아래의 모든 경로에 대한 데이터를 제공하기 위해 기능합니다. 이 기능을 사용하여 태그를 로드해 보겠습니다. details
페이지 — 추가로 list
우리가 이미 가지고 있는 페이지.
실제로 레이아웃 그룹이 단일 데이터를 제공하도록 강제하는 것은 거의 가치가 없습니다. 해당 데이터를 load()
페이지별 기능입니다. 그러나 이 게시물에서는 새로운 SvelteKit 기능을 확인해야 하는 변명을 제공할 것입니다!
먼저 우리의 list
페이지의 +page.server.js
파일에서 태그를 제거합니다.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
우리의 목록 페이지는 이제 오류를 생성해야 합니다. tags
물체. 를 추가하여 이 문제를 해결해 보겠습니다. +layout.server.js
레이아웃 그룹에 파일을 추가한 다음 load()
태그를 로드하는 함수입니다.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
그리고 마찬가지로 목록 페이지가 다시 렌더링됩니다!
여러 위치에서 데이터를 로드하고 있습니다.
여기서 무슨 일이 일어나고 있는지 잘 살펴보겠습니다.
- 우리는 정의
load()
우리가 넣은 레이아웃 그룹의 기능+layout.server.js
. - 이것은 다음에 대한 데이터를 제공합니다. 모든 레이아웃이 제공하는 페이지의 수 — 이 경우 목록 및 세부 정보 페이지를 의미합니다.
- 우리 목록 페이지는 또한
load()
그 안에 들어가는 기능+page.server.js
파일. - SvelteKit은 이러한 데이터 소스의 결과를 가져와 함께 병합하고 두 가지 모두를
data
.
세부 정보 페이지
세부 정보 페이지를 사용하여 할 일 항목을 편집합니다. 먼저 쿼리 문자열에 할 일 항목의 ID가 있는 세부 정보 페이지로 연결되는 목록 페이지의 테이블에 열을 추가해 보겠습니다.
<td><a href="/ko/details?id={t.id}">Edit</a></td>
이제 세부 정보 페이지를 구축해 보겠습니다. 먼저 편집 중인 작업 항목을 가져오기 위해 로더를 추가합니다. 만들기 +page.server.js
in /details
, 이 콘텐츠와 함께:
import { getTodo, updateTodo, wait } from "$lib/data/todoData"; export function load({ url }) { const id = url.searchParams.get("id"); console.log(id); const todo = getTodo(id); return { todo, };
}
우리의 로더는 url
쿼리 문자열 값을 가져올 수 있는 속성입니다. 이렇게 하면 편집 중인 할 일 항목을 쉽게 찾을 수 있습니다. 할 일을 편집하는 기능과 함께 렌더링해 봅시다.
SvelteKit에는 양식을 사용하는 한 놀라운 내장 변형 기능이 있습니다. 양식을 기억하십니까? 다음은 세부 정보 페이지입니다. 간결함을 위해 스타일을 생략했습니다.
<script> import { enhance } from "$app/forms"; export let data; $: ({ todo, tags } = data); $: currentTags = todo.tags.map(id => tags[id]);
</script> <form use:enhance method="post" action="?/editTodo"> <input name="id" type="hidden" value="{todo.id}" /> <input name="title" value="{todo.title}" /> <div> {#each currentTags as tag} <span style="{`color:" ${tag.color};`}>{tag.name}</span> {/each} </div> <button>Save</button>
</form>
이전과 같이 레이아웃 그룹의 로더에서 태그를 가져오고 페이지 로더에서 할 일 항목을 가져옵니다. 우리는 실제를 잡아 tag
할 일의 태그 ID 목록에서 개체를 가져온 다음 모든 것을 렌더링합니다. ID에 대한 숨겨진 입력과 제목에 대한 실제 입력이 있는 양식을 만듭니다. 태그를 표시한 다음 양식을 제출할 수 있는 버튼을 제공합니다.
눈치채셨다면 use:enhance
, 이는 단순히 SvelteKit에 점진적 개선을 사용하고 Ajax를 사용하여 양식을 제출하도록 지시합니다. 당신은 항상 그것을 사용할 것입니다.
편집 내용을 어떻게 저장합니까?
공지 사항 action="?/editTodo"
양식 자체의 속성? 편집된 데이터를 제출할 위치를 알려줍니다. 우리의 경우, 우리는 editTodo
"행동."
다음을 추가하여 생성해 봅시다. +page.server.js
세부 정보에 대해 이미 가지고 있는 파일(현재 load()
할 일을 파악하기 위한 함수):
import { redirect } from "@sveltejs/kit"; // ... export const actions = { async editTodo({ request }) { const formData = await request.formData(); const id = formData.get("id"); const newTitle = formData.get("title"); await wait(250); updateTodo(id, newTitle); throw redirect(303, "/list"); },
};
폼 액션은 우리에게 request
객체에 대한 액세스를 제공합니다. formData
, 어떤 get
다양한 양식 필드에 대한 방법입니다. 편집 중인 할 일 항목을 찾기 위해 여기에서 가져올 수 있도록 ID 값에 대한 숨겨진 입력을 추가했습니다. 지연을 시뮬레이트하고 새 updateTodo()
그런 다음 사용자를 다시 /list
페이지. updateTodo()
메서드는 단지 정적 데이터를 업데이트할 뿐입니다. 실생활에서는 사용 중인 데이터 저장소에 관계없이 일종의 업데이트를 실행합니다.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
시도해 봅시다. 먼저 목록 페이지로 이동합니다.
이제 할 일 항목 중 하나에 대해 편집 버튼을 클릭하여 편집 페이지를 불러오겠습니다. /details
.
새 제목을 추가할 예정입니다.
이제 저장을 클릭합니다. 그것은 우리를 우리의 /list
새 할 일 제목이 적용된 페이지입니다.
새 제목이 어떻게 그렇게 표시 되었습니까? 자동이었습니다. 일단 우리가 /list
페이지에서 SvelteKit는 상관 없이 모든 로더를 자동으로 다시 실행했습니다. 이것은 SvelteKit과 같은 차세대 애플리케이션 프레임워크가 리믹스및 다음 13 제공하다. 페이지를 렌더링하는 편리한 방법을 제공한 다음 데이터를 업데이트해야 할 수 있는 끝점을 가져오는 행운을 빌기보다는 데이터 로딩과 함께 데이터 변이를 통합하여 두 가지가 동시에 작동할 수 있도록 합니다.
궁금하실 수 있는 몇 가지…
이 돌연변이 업데이트는 그리 인상적이지 않은 것 같습니다. 탐색할 때마다 로더가 다시 실행됩니다. 양식 작업에 리디렉션을 추가하지 않고 현재 페이지에 그대로 있으면 어떻게 될까요? SvelteKit은 이전과 같이 양식 작업에서 업데이트를 수행하지만 여전히 페이지 레이아웃의 로더를 포함하여 현재 페이지의 모든 로더를 다시 실행합니다.
데이터를 무효화하는 보다 표적화된 수단을 가질 수 있습니까? 예를 들어 태그는 편집되지 않았으므로 실생활에서는 태그를 다시 쿼리하고 싶지 않을 것입니다. 예, 제가 보여드린 것은 SvelteKit의 기본 양식 동작입니다. 다음과 같이 기본 동작을 끌 수 있습니다. 콜백 제공 use:enhance
. 그런 다음 SvelteKit은 설명서를 제공합니다. 무효화 함수.
모든 내비게이션에서 데이터를 로드하는 것은 잠재적으로 비용이 많이 들고 불필요합니다. 다음과 같은 도구를 사용하는 것처럼 이 데이터를 캐시할 수 있습니까? react-query
? 예, 다릅니다. SvelteKit을 사용하면 웹에서 이미 제공하는 캐시 제어 헤더를 설정(및 존중)할 수 있습니다. 그리고 후속 게시물에서 캐시 무효화 메커니즘을 다룰 것입니다.
이 기사에서 수행한 모든 작업은 정적 데이터를 사용하고 메모리의 값을 수정합니다. 모든 것을 되돌리고 다시 시작해야 하는 경우 npm run dev
노드 프로세스.
최대 포장
우리는 SvelteKit의 표면을 거의 긁지 않았지만, 당신이 그것에 대해 충분히 보았기를 바랍니다. 웹 개발이 이렇게 재미있었던 때가 언제였는지 기억이 나지 않습니다. 번들링, 라우팅, SSR 및 배포와 같은 모든 것이 즉시 처리되므로 구성보다 코딩에 더 많은 시간을 할애하게 됩니다.
다음은 SvelteKit 학습의 다음 단계로 사용할 수 있는 몇 가지 추가 리소스입니다.
- SEO 기반 콘텐츠 및 PR 배포. 오늘 증폭하십시오.
- 플라토 블록체인. Web3 메타버스 인텔리전스. 지식 증폭. 여기에서 액세스하십시오.
- 출처: https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- 할 수 있는
- 소개
- IT에 대해
- ACCESS
- 계정
- 동작
- 행위
- 아담
- 추가
- 또한
- 주소
- 관리자
- 많은
- 영향을
- All
- 허용
- 함께
- 이미
- 항상
- 양
- 및
- 다른
- 답변
- 누군가
- 앱
- 어플리케이션
- 어플리케이션
- 적용된
- 약
- 배열
- 기사
- 인조의
- 할당 된
- Automatic
- 자동적으로
- 가능
- 기다리다
- 뒤로
- 배경
- 기치
- 바
- 기본
- 전에
- BEST
- 더 나은
- 사이에
- 비트
- 검정
- 블로그
- 블로그 게시물
- 파란색
- 보물상자
- 가져
- 브라우저
- 버그
- 빌드
- 내장
- 내장
- 단추
- 캐시
- 전화
- 통화
- 기능
- 케이스
- 확실히
- 도전
- 변화
- 선명한
- 암호
- 코딩
- 색
- 단
- 왔다
- 공통의
- 경기
- 구성 요소
- 구성 요소들
- 회의
- 연결하기
- 연결
- 콘솔에서
- 함유량
- 편리한
- 수
- 코스
- 피복
- 커버
- 만들
- 만든
- 만들기
- Current
- 현재
- 데이터
- 데이터베이스
- 태만
- 정의
- 지연
- 지연
- 전개
- 디자인
- 세부설명
- 데브
- 개발
- DID
- 디스플레이
- 하지 않습니다
- 하기
- 말라
- 마다
- 다른
- 충분히
- 전체의
- 전체
- 오류
- 등
- 조차
- 모든
- 모두
- 예
- 흥분한
- 흥분
- 존재
- 비싼
- 수출
- 실행할 수 있는
- 특색
- 를
- Fields
- 입양 부모로서의 귀하의 적합성을 결정하기 위해 미국 이민국에
- 파일
- 최종적으로
- 끝
- 화재
- 먼저,
- 수정
- 플랫
- 수행원
- 영원히
- 형태
- 체재
- 양식
- 발견
- 프레임 워크
- 에
- 가득 찬
- 장난
- 기능
- 기능
- 기능
- 얻을
- 점점
- 주기
- 기부
- 글로벌
- Go
- 골
- 간다
- 가는
- 잡아요
- 그룹
- 여러 떼
- 발생
- 하드
- 헤더
- 도움
- 여기에서 지금 확인해 보세요.
- 숨겨진
- 계층
- 고수준
- 보유
- 희망
- 수평
- 방법
- HTML
- HTTPS
- 악
- 상상력
- import
- 중요성
- 인상
- in
- 포함
- 처음에는
- 입력
- 를 받아야 하는 미국 여행자
- 통합
- 흥미있는
- 개요
- IT
- 항목
- 그 자체
- 자바 스크립트
- 키
- 성
- 최근
- 레이아웃
- 배우기
- 수
- 레벨
- Li
- 생활
- 빛
- 아마도
- 모래밭
- 명부
- 살고있다
- 하중
- 짐을 싣는 사람
- 로드
- 잔뜩
- 긴
- 보기
- 봐라.
- 조회
- 운
- 기계
- 확인
- 제작
- 유튜브 영상을 만드는 것은
- 관리
- 조작
- 한계
- 문제
- 방법
- 메모리
- 단지
- 합병
- 방법
- 수도
- 신경
- 모듈
- 배우기
- 움직임
- 움직이는
- 여러
- name
- 이름
- 탐색
- 이동
- 카테고리
- 필요한
- 필요
- 신제품
- 다음 것
- 노드
- 표준
- 번호
- 대상
- 사물
- ONE
- 주문
- 기타
- 그렇지 않으면
- 자신의
- 특별한
- 통로
- 수행
- 선택
- 조각
- 개
- 자리
- 플라톤
- 플라톤 데이터 인텔리전스
- 플라토데이터
- 포인트 적립
- 게시하다
- 게시물
- 잠재적으로
- Prepare
- 문제
- 방법
- 생산
- 진보
- 프로젝트
- 약속
- 재산
- 보호
- 제공
- 제공
- 했었어요
- 놓다
- 문제
- 살갗이 벗어 진
- 읽기
- 현실
- 실생활
- 현실
- 빨간색
- 리디렉션
- 관계없이
- 남아
- 기억
- 제거
- 렌더링
- 렌더링
- 의뢰
- 제품 자료
- 결과
- return
- 반환
- 반품
- 돌아가는 것
- 풍부한
- 뿌리
- 길
- 노선
- 달리기
- 달리는
- 같은
- 찜하기
- 보고
- 봉사하다
- 세트
- 그림자
- 공유
- 공유
- 영상을
- 표시
- 단순, 간단, 편리
- 간단히
- 이후
- 단일
- 슬라이드
- So
- 일부
- 무언가
- 지우면 좋을거같음 . SM
- 지출
- 스타트
- 시작
- 머물렀던
- 단계
- 중지
- 제출
- 지원
- 표면
- 체계
- 테이블
- TAG
- 받아
- 복용
- 이야기
- 자전거
- 대상
- 말하다
- 이 템플릿
- 단말기
- XNUMXD덴탈의
- 일
- 도처에
- 시간
- Title
- 에
- 함께
- 너무
- 검색을
- 둘러보기
- 치료
- 참된
- 회전
- 타이프 스크립트
- ui
- 아래에
- 업데이트
- 업데이트
- URL
- us
- 사용
- 사용자
- 가치
- 마케팅은:
- 여러
- 를 통해
- 관측
- 기다리다
- 원
- 방법
- 웹
- 웹 구성 요소
- 웹 개발
- 뭐
- 어느
- 화이트
- 의지
- 승리
- 없이
- 훌륭한
- 작업
- 일
- 가치
- 겠지
- 쓰다
- 자신의
- 너의
- 제퍼 넷