본문 바로가기

개발/Vue.js

[Routing] Vue-Router 없이 라우팅하기

728x90
반응형

화면이 좌/우로 트랜지션(?)되는 라우터를 만들어보자.


App.vue

<script setup>
import { ref } from 'vue';
import Component1 from './components/Component1.vue';
import Component2 from './components/Component2.vue';
import Component3 from './components/Component3.vue';
import Component4 from './components/Component4.vue';

const showComponent2 = ref(false);
const showComponent3 = ref(false);
const showComponent4 = ref(false);
const transitionName = ref('slide');
</script>

<template>
  <div id="app">
    <transition :name="transitionName">
      <Component1 class="component"  v-if="!showComponent2 && !showComponent3 && !showComponent4"
        @show-component2="showComponent2 = $event; transitionName = 'slide-left'" key="component1" />
    </transition>
    <transition :name="transitionName">
      <Component2 class="component"  v-if="showComponent2 && !showComponent3 && !showComponent4"
        @show-component3="showComponent3 = $event; showComponent2 = false; transitionName = 'slide-left'"
        @show-component4="showComponent4 = $event; showComponent2 = false; transitionName = 'slide-left'"
        :key="showComponent2" />
    </transition>
    <transition :name="transitionName">
      <Component3 class="component"  v-if="!showComponent2 && showComponent3 && !showComponent4"
        @show-component2="showComponent2 = $event; showComponent3 = false; transitionName = 'slide-right'"
        :key="showComponent3" />
    </transition>
    <transition :name="transitionName">
      <Component4 class="component"  v-if="!showComponent2 && !showComponent3 && showComponent4"
        @show-component2="showComponent2 = $event; showComponent4 = false; transitionName = 'slide-left'"
        :key="showComponent4" />
    </transition>
  </div>
</template>

<style>
#app {
  display: flex; 
  flex-direction: row;
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100vh;
}

.component {
  position: absolute;
  width: 100%;
  height: 100%;
}

.slide-left-enter-active,
.slide-left-leave-active {
  transition: all 0.3s;
}

.slide-right-enter-active,
.slide-right-leave-active {
  transition: all 0.3s;
}

.slide-left-enter-from,
.slide-right-leave-to {
  transform: translateX(100%);
}

.slide-left-enter-to,
.slide-right-leave-from {
  transform: translateX(0);
}

.slide-right-enter-from,
.slide-left-leave-to {
  transform: translateX(-100%);
}

.slide-right-enter-to,
.slide-left-leave-from {
  transform: translateX(0);
}
</style>

 

각 컴포넌트의 표시 여부를 관리하는 showComponent2, showComponent3, showComponent4 변수를 선언했다.

전환 효과를 위한 transitionName 변수를 선언했다.

 

초기 화면에는 Component1만 보이게 하고

Component1에서 이벤트를 발생시키면, Component2가 나타나고, Component1은 사라진다.
Component2에서 이벤트를 발생시키면, Component3 또는 Component4가 나타나고, Component2는 사라진다.
Component3에서 이벤트를 발생시키면, Component2가 다시 나타나고, Component3은 사라진다.
Component4에서 이벤트를 발생시키면, Component2가 다시 나타나고, Component4는 사라진다.

v-if를 사용하여 각 컴포넌트의 표시 여부를 제어했다.


각 컴포넌트에서 발생하는 이벤트를 처리하는 이벤트 리스너를 설정하여, 이를 통해 다른 컴포넌트로 전환하거나 전환 효과를 변경할 수 있게 했다.


전환 애니메이션은 slide 클래스를 이용하여 translateX() 함수를 사용하여 컴포넌트가 화면에 나타나거나 사라지는 애니메이션을 구현했다.

 

transition 컴포넌트에서 :name 속성을 이용하여 해당 애니메이션 클래스를 설정했다.


Component1.vue

<template>
  <div>
    <h1>컴포넌트 1</h1>
    <button @click="showComponent2">컴포넌트 2 보여주기</button>
  </div>
</template>

<script setup>

const showComponent2 = () => {
  emit('show-component2', true);
};

const emit = defineEmits(['show-component2']);
</script>

<style scoped>

</style>

Component2.vue

<template>
  <div>
    <h1>컴포넌트 2</h1>
    <button @click="showComponent3">컴포넌트 3 보여주기</button>
    <button @click="showComponent4">컴포넌트 4 보여주기</button>
  </div>
</template>

<script setup>
const emit = defineEmits(["show-component3", "show-component4", "transition"]);

const showComponent3 = () => {
  emit("show-component3", true);
};

const showComponent4 = () => {
  emit("show-component4", true);
};
</script>


<style scoped>

</style>

Component3.vue

<template>
  <div>
    <h1>컴포넌트 3</h1>
    <button @click="showComponent2">컴포넌트 2 보여주기</button>
  </div>
</template>

<script setup>
const emit = defineEmits(["show-component2", "transition"]);

const showComponent2 = () => {
  emit("show-component2", true);
};
</script>
<style scoped>

</style>

Component4.vue

<template>
  <div>
    <h1>컴포넌트 4</h1>
  </div>
</template>

<script setup>
</script>
<style scoped>

</style>

각 2,3,4 컴포넌트에서는 showComponent 함수를 정의했다.

 

이 함수는 버튼 클릭 시 호출되며, show-component 사용자 정의 이벤트를 발생시키고 이벤트 값으로 true를 전달한다.


defineEmits를 사용하여 사용자 정의 이벤트 show-component를 정의하고, emit 변수에 할당했다.


결과물

 

 

728x90
반응형