Vue.js Composition API this.$route, this.$routes => composable

강정우·2023년 5월 6일
0

vue.js

목록 보기
53/72
post-thumbnail

1. props 사용하기

  • 얘는 주로 dynamic route의 매개변수 얻을 때 사용된다.
const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', redirect: '/products' },
    { path: '/products', component: AllProducts },
    { path: '/products/:pid', component: ProductDetails },
    { path: '/products/add', component: AddProduct }
  ]
});
  • 기존에 위와같은 route.js가 있었다면 ProductDetails 컴포넌트에서는 this.route를이용하여해당url에대하여접근할수있었다.그런데수차례말하지만setup메서드는lifecyclecreate시에일어남으로this.키워드가존재하기이전에실행되어this.route를 이용하여 해당 url에 대하여 접근할 수 있었다. 그런데 수차례말하지만 setup 메서드는 life-cycle상 create시에 일어남으로 `this.` 키워드가 존재하기 이전에 실행되어 this.route는 접근할 수 없는 것이다.

  • 그러다면 어떻게 접근하면 될까?

route.js에서 props으로써 전달

  • 먼저 route.js 에서 처리할 수 있다.
    동적 세그먼트를 프로퍼티로 전달하여 컴포넌트에 로드되도록 이 라우트를 구성할 수 있다.
const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', redirect: '/products' },
    { path: '/products', component: AllProducts },
    { path: '/products/:pid', component: ProductDetails, props:true},
    { path: '/products/add', component: AddProduct }
  ]
});
  • 이 라우트 구성에 props 옵션을 넣고 true로 설정하면 된다.
    제품 ID인 pid에 대한 값은 ProductDetails.vue 컴포넌트에서 props로 제공된다.

컴포넌트에서 defineProps 메서드로 받아서 사용하기

<script setup>
import {defineProps, inject} from 'vue';

const props = defineProps({
  pid:String
})

const products = inject('products');
const selectedProduct = products.value.find((product)=>product.id===props.pid)
const title = selectedProduct.title;
const price = selectedProduct.price;
const description = selectedProduct.description;
</script>
  • 그래서 위와 같이 접근하여 사용해도 된다.

컴포넌트에서 computed까지 함께 사용하여 동적 라우팅하기

그러데 만약 아래와 같은 코드가 있다고 해보자

<template>
  <section>
    <h2>{{ title }}</h2>
    <h3>${{ price}}</h3>
    <p>{{ description}}</p>
    <router-link to="/products/p2">Product P2</router-link>
  </section>
</template>
  • 해당 router-link를 클릭하면 동작할까? => 아니다 => 왜? 마크업에 표시해주는 title, price, description이 현재 reactive하지 않기 때문이다. => 이를 반응형을 바꿔주려면? => ref나 computed를 사용하면 된다~
import {computed, defineProps, inject} from 'vue';

const props = defineProps({
  pid:String
})

const products = inject('products');
const selectedProduct = computed(()=>products.value.find((product)=>product.id===props.pid))
const title = computed(()=>selectedProduct.value.title);
const price = computed(()=>selectedProduct.value.price);
const description = computed(()=>selectedProduct.value.description);

2. composable

useRoute

  • 만약 단순 route가 아니라 query나 path를 알고싶으면 어떻게 해야할까?

  • 바로 vue-router 라이브러리에 내장된 훅 또는 composable을 사용하면 된다.

  • composable은 뭘까? 특별한 종류의 함수를 가르킨다.
    훅, 컴포저블 사용자 지정 컴포지션 함수는 JavaScript로 쓰인 특별한 함수로 컴포지션 API에 내장되어 있다.

  • 따라서 setup 메서드 내부에서 사용되며 이 함수들은 보통 내부적으로 참조(ref)와 연산(computed)과 같은 컴포지션 API 기능을 사용한다.

import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route);
  • react와 굉장히 유사한 모습이다. 무튼 아래 사진과 같이

  • 모든 라우트 데이터가 들어있는 이 Proxy 값이 나오는데 이는 반응형이기 때문에 watchcomputed 프로퍼티를 사용하여 라우트가 변경될 때 여기에 의존하는 데이터를 업데이트할 수 있다.
import {computed, inject} from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();

const products = inject('products');
const selectedProduct = computed(()=>products.value.find((product)=>product.id===route.params.pid))
const title = computed(()=>selectedProduct.value.title);
const price = computed(()=>selectedProduct.value.price);
const description = computed(()=>selectedProduct.value.description);
  • 이렇게 하면 props로 값을 가져오는 귀찮은 방법을 사용하지 않아도 된다.

useRouter

  • composable로 프로그래밍 방식으로 탐색하기 위해선 useRoute가 아닌 useRouter가 필요하다
<script>
import { ref, inject } from 'vue';
import {useRouter} from "vue-router";

export default {
  setup() {
    const addProduct = inject('addProduct');
    const router = useRouter();
    const enteredTitle = ref('');
    const enteredPrice = ref(null);
    const enteredDescription = ref('');

    function submitForm() {
      addProduct({
        title: enteredTitle,
        description: enteredDescription,
        price: enteredPrice,
      });
      router.push('/products');
    }

    return {
      enteredTitle,
      enteredPrice,
      enteredDescription,
      submitForm,
    };
  },
};
</script>
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글