
Vue2 프로젝트에서 사용했던 vue-router(3.x)는 params를 이용함에도 url에 노출하지 않고 다른 페이지로 데이터를 전달 할 수 있었다.
Ex) https://example/id/1 형태가 아닌 https://example/id 만으로도 id=1인 params를 보낼 수 있었다.
하지만, 현재 프로젝트에서 사용 중인 vue-router4 부터는 url에 노출시키지 않는 방식을 지원하지 않게 되었다. - 참조
This change will break your app. This behavior has worked in some scenarios but has been advised against for years as it's an anti-pattern in routing for many reasons, one of them being reloading the page lose the params. Fortunately, there are multiple alternatives to this anti-pattern:
: 이 변경 사항은 앱을 손상시킬 것입니다. 이 동작은 몇 가지 시나리오에서 효과가 있었지만, 페이지를 다시 로드하는 중 params를 잃게 되는 등의 여러 이유로 라우팅에서는 안티 패턴이기 때문에 수년 동안 권장되지 않았습니다. 다행이도, 이 안티 패턴에 대응하는 여러 대안들이 있습니다.
(1) [pinia](https://pinia.vuejs.org/)와 같은 데이터를 저장소에 저장하는 기술 사용 : 여러 페이지에 걸쳐 데이터가 사용된다면 좋을 것입니다.
(2) 기존 정의된 방식대로 params와 query 사용하기 : URL에 들어갈 정도로 데이터가 작다면 적합합니다. 그리고 페이지 리로딩시 데이터 손실을 예방할 수 있습니다.
(3) History API state를 이용하여 데이터를 state로 전달하기
<router-link :to="{ name: 'somewhere', state: { myData } }">...</router-link>
<button
@click="$router.push({ name: 'somewhere', state: { myData } })"
>...</button>
(4) 네비게이션 가드 동안 to.meta라는 새로운 property로 전달하기
router.beforeEach(async to => {
if (to.meta.shouldFetch) {
// name `data` whatever you want
to.meta.data = await fetchSomething()
}
})
reactive()) 등(1) 위 3번에 명시된 history을 이용한 state 전달
// Main.vue
import { useRouter } from 'vue-router'
setup() {
const data = ref({ value: 'A', text: '1'})
const router = useRouter()
const onClicked = () => {
router.push({
name: 'SubContainer',
state: {
data: { JSON.stringify(data) }
}
})
}
}
// SubContainer.vue
export default {
name: 'SubContainer',
setup() {
const dataObj = JSON.parse(history.state.data)
console.log(dataObj)
// { value: 'A', text: '1' }
}
}
Object나 reactive인 데이터를 JSON.stringify()로 보내지 않으면, 오류 뜬다. JSON.stringify()대신 map()을 이용하시던데 사용법을 잘 모르겠다.(2) params로 전달
: vue-router에서 params을 통한 전달은 권장하지 않는다.
// Main.vue
import { useRouter } from 'vue-router'
setup() {
const data = ref({ value: 'A', text: '1'})
const router = useRouter()
const onClicked = () => {
router.push({
name: 'SubContainer',
params: {
objectParam: JSON.stringify({
data: {
value: location.value.value,
text: location.value.text
}
})
}
})
}
}
// SubContainer.vue
import { useRoute } from 'vue-router'
export default {
name: 'SubContainer',
setup() {
const route = useRoute()
if (route.params.objectParam) {
const dataObj= JSON.parse(route.params.objectParam)
console.log(dataObj)
// data: {value: 'A', text: '1'}
}
}
}
String, Number 등) - 값 1개만 전달할 경우, 적합 : // Main.vue
import { useRouter } from 'vue-router'
setup() {
const router = useRouter()
const data = ref(3)
const onClickedNext = () => {
router.push({
name: 'SubContainer',
state: { data: data.value },
})
}
}
// SubContainer.vue
export default {
name: 'SubContainer',
setup() {
const dataObj = history.state.data;
console.log(dataObj);
// 3
}
}
덕분에 이틀이나 골머리를 앓았다. Vue3와 vue-router4는 시작한지 얼마 안 돼서 미숙한 점이 많지만, 프론트엔드 개발자를 지망하는 것은 아니기에 이정도까지만 아는 것으로 넘기는게 좋을 거 같다.