/VanillaJS-SPA-Router

[๐ŸŒVanillaJS] Component, Router ๊ตฌํ˜„

Primary LanguageJavaScript

Vanilla JS SPA ๊ตฌํ˜„

๋ชฉ์ฐจ

  • ์ปดํฌ๋„ŒํŠธ
  • ๋ผ์šฐํ„ฐ

Comonent

์ปดํฌ๋„ŒํŠธ๋Š” ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ์™€, ์ผ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๊ณตํ†ต

  • ํŽ˜์ด์ง€, ์ผ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ ๋ชจ๋‘ Element๋ฅผ ๋ฐ˜ํ™˜ ํ•˜๋„๋ก ํ•จ
  • ์ด๋ฒคํŠธ๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์—์„œ ๋“ฑ๋ก

์ผ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ

  1. wrapper ์š”์†Œ ๋งŒ๋“ค๊ธฐ (createElement)
  2. template ๋งŒ๋“ค๊ธฐ
  3. ์š”์†Œ์— template ์ถ”๊ฐ€ (innerHTML)
  4. ์ด๋ฒคํŠธ ๋“ฑ๋ก (addEventListener)
  5. wrapper ์š”์†Œ ๋ฐ˜ํ™˜
function Component() {
  const $wrapper = document.createElement('div');

  const template = `<div>foo</div>`;

  $wraaper.innerHTML = template;
  $wrapper.addEventListener('click', () => console.log('foo'));

  return $wrapper;
};

ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ

  • wrapper ์š”์†Œ ๋งŒ๋“ค๊ธฐ (createElement)
  • ํ•ด๋‹น ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ ๋“ฑ๋ก (append)
  • wrapper ์š”์†Œ ๋ฐ˜ํ™˜
function MainPage() {
  const $wrapper = document.createElement('div');

  $wrapper.append(
    Header(),
    OtherComponent(),
    Footer(),
  );

  return $wrapper;
}

Router

ํ•จ์ˆ˜

  • routes
  • router
  • navigate

routes

๊ฒฝ๋กœ์™€ ํ•ด๋‹น ๊ฒฝ๋กœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ

  • 'posts/1', 'posts/2' ๋“ฑ์˜ path์— ๋Œ€์‘ ํ•˜๊ธฐ ์œ„ํ•ด regExp ์ ์šฉ
const routes = [
  { path: /^\/$/, component: Landing },
  { path: /^\/main$/, component: Main },
];

router

๊ฒฝ๋กœ์— ํ•ด๋‹น๋˜๋Š” ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ '.app'์— ์‚ฝ์ž…

  1. routes์—์„œ path์— ํ•ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ฐพ๊ธฐ
  2. '.app' ์ดˆ๊ธฐํ™” (ํŽ˜์ด์ง€ ์ค‘๋ณต ๋ฐฉ์ง€)
  3. ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ '.app'์— ์‚ฝ์ž…
export const router = (routes, path) => {
  const component = routes
    .find(route => route.path.test(path))
    .component;
  
  $('.app').innerHTML = '';
  $('.app').append(component());
};

navigate ํ•จ์ˆ˜ ๊ตฌํ˜„

a ํƒœ๊ทธ ํด๋ฆญ์‹œ navigate ํ•จ์ˆ˜ ํ˜ธ์ถœ

  1. ํŽ˜์ด์ง€ ์š”์ฒญ ๋ง‰๊ธฐ (preventDefault)
  2. target์˜ href ์†์„ฑ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ (getAttribute)
  3. url ๋ณ€๊ฒฝ (history.pushState)
  4. router ํ•จ์ˆ˜ ํ˜ธ์ถœ
export const navigate = e => {
  e.preventDefault();

  const path = e.target.getAttribute('href');
  
  window.history.pushState({}, null, path);
  router(routes, path);
};