์์ด์ฝ์ ๋๋ฅด๋ฉด,
ํ๋ฉด์ด ์ฌ๋ผ์ด๋ฉ๋์ด
๋ํ๋๋๋ก ๋ง๋ค ๊ฒ์ด๋ค.
1. ํ๋ฉด ๋์๊ณผ ์ ์ฒด์ฝ๋
2. ์ฝ๋ ์ดํด๋ฅผ ๋๊ธฐ ์ํ ๊ฐ๋ตํ ์ค๋ช
3. RightSide.vue ์์ฑ
4. MainView.vue ์์ฑ
5. ํ๋ฆ
1. ํ๋ฉด ๋์๊ณผ ์ ์ฒด์ฝ๋
- ๋์ํ๋ฉด

- ์ ์ฒด์ฝ๋
[MainView.vue์ ๋ฉ์ธํ๋ฉด ์ฝ๋๊ฐ ์์ต๋๋ค.]
Register-Web-frontend/src/views at master · hyeong-ing/Register-Web-frontend
์ผ๋ฐ ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ, ๊ฐํธ ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ์ ๊ตฌํํ์ต๋๋ค. WebStrom์ผ๋ก Vue.js์ Vite๋ฅผ ์ฌ์ฉํ์ต๋๋ค. - hyeong-ing/Register-Web-frontend
github.com
[RightSide.vue์ ์ค๋ฅธ์ชฝ ์ฌ์ด๋ ๋ทฐ ์ฝ๋๊ฐ ๋ค์ด์์ต๋๋ค.]
Register-Web-frontend/src/components/mainview/RightSide.vue at master · hyeong-ing/Register-Web-frontend
์ผ๋ฐ ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ, ๊ฐํธ ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ์ ๊ตฌํํ์ต๋๋ค. WebStrom์ผ๋ก Vue.js์ Vite๋ฅผ ์ฌ์ฉํ์ต๋๋ค. - hyeong-ing/Register-Web-frontend
github.com
2. ์ฝ๋ ์ดํด๋ฅผ ๋๊ธฐ ์ํ ๊ฐ๋ตํ ์ค๋ช
์ด์ฐ์ ์ฐ ๋ง๋ค๊ธด ํ์ง๋ง... ์ฝ๋ ๋ณต๋ถํ๊ณ ์ด๊ฒ์ ๊ฒ ์๋ํ๋ฉฐ ์ป์ด ๊ฑธ๋ฆฌ๋ค ๋ณด๋, ์ ๋ ์ฝ๋๊ฐ ์ด๋ป๊ฒ ์งํ๋๋์ง ๋ชจ๋ฅด๊ฒ ๋๋ผ๊ณ ์. ๊ทธ๋์ ์ ์ดํด๋ฅผ ๋๊ธฐ ์ํด(?) ์งง๋งํ ์ค๋ช ์ ์ ์ด๋ณด์์ต๋๋ค.

3. RightSide.vue ์์ฑ
- ํ๋ฉด ์์๋ณธ

- ์ด๋ป๊ฒ ๋ง๋ค๊น?
์ด๋ฒ ํฌ์คํ ์์๋ ์ฌ๋ผ์ด๋ฉ ๋ชจ์ ๋ง ์ค๋ช ํ๊ณ , ํ ์คํธ ์ปฌ๋ฌ ๋ณํ๋ ๋ค์ ํฌ์คํ ์ ์ ๊ฒ ์ต๋๋ค.

์์ด์ฝ์ ๋๋ฅด๋ฉด ์ค๋ฅธ์ชฝ ์ฌ์ด๋์์ ์์ ๋ทฐ๊ฐ ๋์ค๋๋ก ํ ๊ฒ์ด๋ค.MainView์ ๋ง๋ค๊ธฐ๋ณด๋ค ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ์ ์งํ๊ธฐ ์ํด ๋ฐ๋ก vue๋ฅผ ๋ง๋ค์ด ์์ฑํ๋ค.SIGN IN์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ฐ๋๋๋ค. ๊ทธ๋ฆฌ๊ณ GUEST ORDER INQURY๋ ๋นํ์ ์กฐํ๋ฅผ ๋ง๋ค ๊ฒ์ด๋ค.
์๋์ ์๋ KAKAO์ ์ ํ๋ฒํธ๋ ํ์์ ์ผ๋ก ๋ฃ์ ๊ฒ์ด๊ณ , ์์ง ์ด๋ค ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ง ์๊ฐํ์ง ์์๋ค. ์ฒ์ฒํ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ์ด๋ป๊ฒ ํ ์ง ๊ฒฐ์ ํ ๊ฒ์ด๋ค. (์ค์ ๋ก ์ด์๋๋ ํ์ด์ง๊ฐ ์๋๋ผ์, ์ฐ๋๋ ์ด์ ๊ฐ ์๊ธฐ์ ์ด๋ป๊ฒ ํ ์ง ๋ชจ๋ฅด๊ฒ ๋ค.)
ํ๋ก ํธ๋ฅผ ๋์ถฉํ ์๊ฐ์ ์๋ค. ์ด์ฐจํผ ํ๋๊ฑฐ ์ ๋๋ก ํ์๋ ์ฃผ์๋ผ์ ๋์ ์ทจํฅ์ ์ต๋ํ ๋ด์๋ณผ ๊ฒ์ด๋ค. ๊ฐ ๋ฒํผ์ ์ปค์๋ฅผ ๋๋ฉด ์ปฌ๋ฌ๊ฐ ๋ฐ๋๋ฉฐ ์ฝ๊ฐ์ ์์ง์์ ์ถ๊ฐํ ๊ฒ์ด๊ณ , ์ฌ์ํ ๋ํ ์ผ๋ ์ ๊ฒฝ์ธ ๊ฒ์ด๋ค.
์ฐธ๊ณ ๋ก Vue๋ฅผ ์ฒ์ ๋ค๋ค๋ด์ ์ ๋ชจ๋ฆ ๋๋ค. ์ํ๋ ๋ชจ์ต์ ์ํด ์ฝ๋ ์ฐพ๊ณ ์ด๋ป๊ฒ ๋ณด์ด๋์ง ํ์ธํ๋ฉฐ ์์ฑํ๊ณ ์์ด์ ์ฝ๋ ํจ์จ์ด ๋จ์ด์ง๊ฑฐ๋ ๊ฐ๊ฒฐํ์ง ์์ ์ ์์ต๋๋ค!
- template ์ฝ๋
<div class="right-side" :class="{ open: open }">
<div class="right-side-content">
<p class="change-color" @click="$router.push('/simpleRegister')" style="cursor:pointer;"> SIGN UP </p>
<p class="change-color" style="cursor:pointer;"> SIGN IN </p>
<p class="change-color" style="cursor:pointer;"> GUEST ORDER INQUIRY </p>
<div class="right-side-bottom">
<p> KAKAO</p>
<p> consultation call_ </p>
<p> 02 - 0000 - 0000 </p>
</div>
</div>
</div>
๊ฐ์ฅ ์์ ํด๋์ค๋ right-side ํด๋์ค๋ก ์ด ํด๋์ค์ ์์ง์์ ๋ถ์ฌํ ๊ฒ์ด๋ค. ์์ง์์ ์ถ๊ฐํ๊ธฐ ์ํด v-bind๋ฅผ ์จ์ผํ๋ค. v-bind๋ ๋์ ๋ฐ์ธ๋ฉ์ผ๋ก ์ด๋ค ์ํ์ ๊ฐ์ด ๋ณํํ๋ฉด ํ๋ฉด์ด ์๋์ ๋ฐ๋๋ค๋ ๊ฑธ ์๋ฏธํ๋ค. :open์ด v-bind์ ์ถ์ฝํ์ด๋ค. ์๋๋ v-bind: class--- ํํ์ง๋ง, ์ถ์ฝํ์ผ๋ก ๋ง์ด ์ฐ๋ ๊ฒ ๊ฐ๋ค. open: open์ ๊ฐ๋ฐ์๊ฐ ์ค์ ํ๋ ์ด๋ฆ์ด๋ฉฐ, ์ผ์ชฝ open์ ํด๋์ค๋ช ์ค๋ฅธ์ชฝ open์ ๋ณ์๋ช ์ด๋ค. script๋ฅผ ์์ฑํ ๋, open์ true ๊ฐ์ด ์์ผ ๋ณด์ด๋๋ก ์์ฑ์ ์ค์ ํ ๊ฒ์ด๋ค.
๋ฐฉ๊ธ open์ ํด๋์ค๋ช ์ด๋ผ๊ณ ์ ์๋๋ฐ, ์ด๊ฒ ๋ฌด์จ ๋ง์ธ์ง ์ค๋ช ํ ๊ฒ์ด๋ค. open์ ๊ฐ์ด false๋ฉด ํด๋์ค ์ด๋ฆ์ ๊ทธ๋ฅ right-side๊ฐ ๋๋ค. ๊ทธ๋ฐ๋ฐ open์ true๊ฐ์ด ์ค๋ฉด right-side open์ด ๋๋ค. ๊ทธ๋ ๊ฒ ํด๋์ค ๋ชฉ๋ก์ ๋ ๊ฐ์ ํด๋์ค๊ฐ ์๊ฒ๋๋ค. ์๋ vue ๊ณต์๋ฌธ์๋ฅผ ๋จ๊ฒจ๋์ํ ๋ ์ฒ์ฒํ ์ฝ์ด๋ณด๋ฉด ๋์์ด ๋ ๊ฒ์ด๋ค. (๋ฌผ๋ก ์ฝ๊ธฐ ์ซ๊ฒ ์๊ฒผ๋ค!)
๊ทธ ๋ค์์ ์ฝ๋๋ ๊ฐ๋จํ๋ค. ํ ์คํธ์ ์ปค์๋ฅผ ๋๋ฉด ์์ด ๋ณํ๋๋ก ๋ง๋ค๊ธฐ ์ํด class = "chage.color"๋ก ๋์ผ์์ผฐ๋ค.(์ด ๋ถ๋ถ์ ๋ค์ ํฌ์คํธ๋ก ์ค๋ช ํ๊ฒ ๋ค) ๊ทธ๋ฆฌ๊ณ ํ์๊ฐ์ ํ์ด์ง๋ฅผ ํ์ฌ ์์ ์๋ ๋ง๋ค์๊ธฐ ๋๋ฌธ์, @click์ ํตํด ํ ์คํธ ํด๋ฆญ์ simpleRegister ๊ฒฝ๋ก๋ก ๊ฐ๋๋ก ์ค์ ํ๋ค.
Vue.js
Vue.js - ํ๋ก๊ทธ๋์๋ธ ์๋ฐ์คํธ๋ฆฝํธ ํ๋ ์์ํฌ
ko.vuejs.org
Vue.js
Vue.js - The Progressive JavaScript Framework
vuejs.org
- style ์ฝ๋
.right-side {
position: fixed;
top: 0;
right: 0;
width:22vw;
height: 100vh;
background: #9f9f9f;
border-left: 4px solid #020202;
border-radius: 10px;
box-shadow: -4px 0 12px rgba(0, 0, 0, 0.23);
transform: translateX(100%);
transition: transform 0.4s cubic-bezier(.71,1.7,.58,.98);
z-index: 1000;
}
.right-side.open {
transform: translateX(0%);
}
position์ fixed๋ก ํ๋ฉด์ ๊ณ ์ ์์ผฐ๋ค. ๋์ค์ ๋ฉ์ธํ๋ฉด์ ๊ฒ์๊ธ์ด ๋์ณ์ ์คํฌ๋กค์ ๋ด๋ ค๋, ์์๊ฐ ๊ณ ์ ๋์ด ์๊ธธ ๋ฐ๋์ ์ผ๋จ ๊ทธ๋ ๊ฒ ์ค์ ํด๋๊ธด ํ๋ค.
right-side๋ main-view์ ํ์ ํด๋์ค๊ฐ ๋ ๊ฒ์ด๋ค. width๋ ๋๋น ํฌ๊ธฐ๋ฅผ ๋ํ๋ธ๋ค. 22vw๋ก ์์ ํด๋์ค์ 22% ์ ๋ ์ฐจ์ง ํ๋ ๋น์จ์ด๋ค. ๊ทธ๋ฌ๋๊น main-view์ ์ค์ ํ ํ๋ฉด ํฌ๊ธฐ์ 22%๋ฅผ ์ฐจ์งํ๋ค๋ ๊ฒ์ด๋ค. height๋ ๋์ด๋ก 100vh๋ฅผ ์ค์ ํ์ฌ ์์ ํด๋์ค์ ๋์ด์ ๋๊ฐ์ด ์ ์ง๋๋๋ก ํ๋ค.
background๋ ๋ฐฐ๊ฒฝ์์ด๋๋ค. ์ด ์ฝ๋์ ์์ง๋ง color๋ ํ ์คํธ ์์ด ๋๋ค.
border์ ํ ๋๋ฆฌ๋ฅผ ์ค์ ํ๋ ๊ฒ์ผ๋ก ์ผ์ชฝ ํ ๋๋ฆฌ๋ง ์ค์ ํ๊ณ ์ถ์ด์ border-left๋ฅผ ์ ์๋ค. solid๋ ํ ๋๋ฆฌ ์ ์ ํํ๋ฅผ ๋ํ๋ด๋ฉฐ ์๋ ์ฌ์ง์ผ๋ก ๋ค์ํ ์ ์ ํํ์ ์ด๋ฆ์ ์ ์ ์๋ค. 4px๋ ๊ตต๊ธฐ๋ฅผ ์ค์ ํ๋ฉฐ #์ผ๋ก ์์ํ๋ ์ฝ๋๋ ์ปฌ๋ฌ ์ฝ๋๊ฐ ๋๋ค.
box-shadow๋ ์ด ํ๋ ์์ ๊ทธ๋ฆผ์๋ฅผ ์ค์ ํ๋ค. -4px๋ x์ถ, 0์ y์ถ, 12px๋ blur๊ฐ ๋๋ค. rgba๋ ์ปฌ๋ฌ๋ฅผ ์ค์ ํ๋ค.
ํ์ฌ right-side ํด๋์ค๋ true๋ผ๋ ๊ฐ์ด ์ค๊ธฐ ์ ์๋ ๋ณด์ด๋ฉด ์๋๋ค. ๊ทธ๋์ transform: translateX(100%);๋ก ์ค์ ํ๋ค. transform์ ์ค์ ๋ ํ์ฌ ์์น์์ ์์ง์ด๋๋ก ํ๋ค. translateX(100%)๋ ํ์ฌ ์์น์์ x์ถ ๋์ ๋๋ฌํ์ฌ right-side๊ฐ ์๋ณด์ด๋๋ก ์ค์ ํ๋ค. ์ด ๊ฐ์ 90%๋ก ์กฐ์ ํ๋ฉด ์ฝ๊ฐ์ ๋ณด์ด๋๋ก ๋ง๋ค ์ ์๋ค.
transition์ ์์ง์์ ์ฃผ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด transition: transform 0.4s cubic-bezier(.71,1.7,.58,.98);์ transform์ด 0.4์ด ๋์ cubic-bezier ์ฆ, ํน์ ๊ณก์ ์ ๋ฐ๋ผ ๋ณํํ๋ค๋ ์๋ฏธ์ด๋ค. ์๋ ๋์์ด ๋ ์ฌ์ดํธ๋ฅผ ๋ฃ์ด๋๊ฒ ๋ค. ์์ .71๊ณผ 1.7์ ์ถ๋ฐํ ๋ ๋ชจ์ ์ด๊ณ , .58๊ณผ .98์ ๋์ฐฉํ ๋์ ๋ชจ์ ์ด๋ค. ์ด ๋ชจ์ ์ ์ง์ ์ค์ ํ ์์ง์์ด๋ค. transition: transform 0.4s linear; ํน์ transition: transform 0.4s ease-out; ๋ฑ ์ด๋ฏธ ์ค์ ๋์ด ์๋ ์์ง์๋ ์ฌ์ฉํ ์ ์๋ค.
right-side.open์ ๋ณด๋ฉด open ํด๋์ค๊ฐ ๋ถ์ ์, x์ถ์ด 0%๊ฐ ๋์ด ํด๋น ๋ทฐ๊ฐ ์์ ํ ๋ณด์ด๋๋ก ์ค์ ํ๊ณ ์๋ค. ๊ทธ๋ฌ๋๊น ์ค์ ํ transition์ผ๋ก ํ๋ฉด์ x์ถ์ด ์์ง์ด๋๋ก ์ค์ ํ ๊ฒ์ด๋ค.
๋ค์ right-side ํด๋์ค๋ก ๋์๊ฐ๋ฉด z-index๊ฐ ์๋ค. ์ด๊ฑด ์ง๊ธ ์ด๋ค ์ฝ๋์ธ์ง ํฌ๊ฒ ๋์ผ๋ก ๋ณด์ด์ง ์๋๋ค. ๋ง์ฝ ๋ฉ์ธํ๋ฉด์ ์ฌ๋ฌ ์์๋ค์ด ์์ด๊ฒ ๋๋ฉด right-side ๋ทฐ๊ฐ ๊ทธ ์์๋ค์ ๊ฐ๋ ค์ ์๋ณด์ผ์๋ ์๋ค. ๊ทธ๊ฑธ ๋ฐฉ์งํ๊ณ ์ ๋ค๋ฅธ ์์๋ค๋ณด๋ค ์์ ๋ณด์ด๋๋ก ์ค์ ํด๋ ๊ฒ์ด๋ค.

cubic-bezier.com
cubic-bezier.com
.right-side-content {
padding: 40px 32px 32px 32px;
font-size: 1.0rem;
color: #020202;
height: 100%;
display: flex;
gap: 7px;
flex-direction: column;
}
padding์ ์ฌ๋ฐฑ ๊ณต๊ฐ์ ์ค์ ํ ๊ฒ์ด๋ค. ์ฌ๋ฐฑ์ ์ค์ ํ์ง ์๊ณ right-side-content์ ๋๋น์ ํฌ๊ธฐ๋ฅผ ์ ํ ๋ค, top๊ณผ left๋ก ์์น๋ฅผ ์กฐ์ ํด๋ ๋์ง๋ง ๊ทธ๊ฑด ์์์ ํ์ผ๋ ์ด๋ฒ์ padding์ ์ฌ์ฉํ์ฌ ์ํ๋ ์์น๋ฅผ ์ค์ ํ๋ค.
gap์ right-side-content์ ๋ค์ด๊ฐ ๊ฐ ์์๋ค์ด ์ผ๋ง๋ ๋จ์ด์ ธ์์ผ๋ฉด ์ข์์ง ์ค์ ํ ๊ฒ์ด๋ค. flex-direction์ ์ด๋ค ๋ฐฉํฅ์ผ๋ก ์์๋ค์ ๋ฐฐ์นํ ๊ฑด์ง ์ ํ๋ ๊ฒ์ด๋ค. column์ ์์์ ์๋๋ก ์์๊ฐ ๋ค์ด๊ฐ๋ ๊ฒ์ผ๋ก ์๊ฐํ๋ฉด ๋๋ค.(ํ ์ค์ ํ๋์ ์์๊ฐ ๋ค์ด๊ฐ๋ค) ๊ทธ๋ฌ๋ฉด ๊ฐ๋ก๋ก ์์๋ค์ ๋ฐฐ์นํ๊ณ ์ถ๋ค๋ฉด? row ๊ฐ์ ์ฃผ๋ฉด ๋๋ค. ๊ทธ๋ฌ๋ฉด ์์๊ฐ ์ข์์ ์ฐ๋ก ๋ฐฐ์น๋๋ค.
- script ์ฝ๋
<script>
export default {
name: 'RightSide',
props: {
open: {
type: Boolean,
required: true,
}
}
}
</script>
export๋ ์ด ํ์ผ์ ์ปดํฌ๋ํธ๋ฅผ ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๊ฒ ๋ด๋ณด๋ด๋ผ๋ ์๋ฏธ๋ก, default๋ฅผ ๋ถ์ฌ ์ด ํ์ผ์ ๋ํ export๋ ํ๋๋ง ์ง์ ๋๋ค๊ณ ๋ง๋ถ์๋ค. ์ด ์ปดํฌ๋ํธ์ ์ด๋ฆ์ RightSide๋ก ์ง์ ํ๋ค.
props๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์ด ์ปดํฌ๋ํธ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์๊ฒ ํด์ฃผ๋ ์์ฑ์ด๋ค. open์ด๋ผ๋ ์ด๋ฆ์ props๋ ๋ฐ๋์ Boolean ํ์ ์ true ๊ฐ์ ๋ฐ์์ผ ํ๋ค๊ณ ๋ช ์ํ๋ค. open์ true ๊ฐ์ด ์ค๋ฉด transform: translateX(0%)์ด ์ ์ฉ๋์ด ํจ๋์ด ๋ณด์ด๊ฒ ๋๋ค.
4. MainView.vue ์์ฑ
- template ์ฝ๋
<template>
<div class="main-view">
/* ํํธ ์์ด์ฝ ์ด๋ฏธ์ง */
<img src="../assets/leftHeartBar.png" alt="์ผ์ชฝํํธ" class="left-sideBar" :class="{isLeftSideOpen: isLeftSideOpen}"
@click="toggleLeft" :style="heartLeftStyle"/>
<LeftSide :open="isLeftSideOpen" />
<img src="../assets/rightHeartBar.png" alt="์ค๋ฅธ์ชฝํํธ" class="right-sideBar" :class="{isRightSideOpen : isRightSideOpen}"
@click="toggleRight" :style="heartRightStyle"/>
<RightSide :open="isRightSideOpen" />
<div class="center-icon">
<img src="../assets/wings.png" alt="๋ ๊ฐ์์ด์ฝ" class="wings" @click="$router.push('/main')" style="cursor:pointer;" />
<div class="shop-name">
<p class="change-color01" @click="$router.push('/main')"> sori </p>
</div>
</div>
</div>
</template>
main-view์ ํํธ ์์ด์ฝ์ ์ด๋ฏธ์ง๋ก ๋ฑ๋กํ๋ค. src์ ๊ฒฝ๋ก๋ฅผ ์ ์๋ค. ํด๋น ์ด๋ฏธ์ง ๊ฒฝ๋ก๋ src ๋๋ ํ ๋ฆฌ ์์ ์๋ assets ๋๋ ํ ๋ฆฌ์ ํด๋น ์ด๋ฏธ์ง๊ฐ ์๋ค. "@/assets/leftHearBar.png"๋ผ๊ณ ํด๋ ๊ด์ฐฎ๊ณ , "../assets/leftHeartBar.png"๋ผ๊ณ ํด๋ ์ข๋ค. alt๋ ๊ตณ์ด ์ ์ง ์์๋ ๊ด์ฐฎ๋ค. ํด๋น ํ์ผ์ ๋ถ๋ฌ์ฌ ์ ์์ ๋ ํ ์คํธ๋ก ๋์ฒดํ๋ ์ญํ ์ ํ๋๋ฐ, ๊นจ์ง ํ์ผ์ด ์ด๋ค ์ด๋ฏธ์ง์๋์ง ์๊ธฐ ์ฝ๊ฒ ํด์ฃผ์ง๋ง ์ ์ง ์์๋ ์ฝ๋๋ฅผ ์คํ์ํค๋๋ฐ ๋ฌธ์ ๋ ์๋ค. right-sideBar ํด๋์ค์๋ ์์น๊ฐ์ด ๋ค์ด๊ฐ ๊ฒ์ด๋ค.
ํ์ฌ ์ค์ ํด์ผํ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ MainView๊ฐ RightView์ ์๋ :open ๊ฐ์ ์ ๋ฌํด์ผํ๋ค๋ ๊ฒ์ด๋ค. ์์ด์ฝ์ด ๋๋ฆฌ๋ฉด false๋ก ์ค์ ๋ open์ ๊ฐ์ true๋ก ๋ฐ์ ์์ผ์ผํ๋ค. ๊ทธ ๊ฐ์ ๋ฐ์ ์์ผ์ผํ๊ธฐ ๋๋ฌธ์ ์์ด์ฝ์ isRightSideOpen์ด๋ ๋์ ๋ฐ์ธ๋ฉ์ ์คฌ๋ค.
๊ทธ๋ฌ๋ฉด isRightSideOpen์ ๊ฐ์ RightSide๋ก ์ ๋ฌํด์ผํ๋๋ฐ, RightSide์ props์๋ open์ด๋ ๊ฐ ๋ฐ์ ์๋ค. ๊ทธ๋์ <RightSide :open="isRightSideOpen"/> ์ถ๊ฐํ์ฌ MainView์์ isRightSideOpen์ด๋ผ๋ ๋ณ์๋ฅผ open์ด๋ผ๋ props๋ก RightSide.vue์ ์ ๋ฌํ๋ค๊ณ ๋ช ์ํ๋ค. (isRightSideOpen์ true๋ false์ ๊ฐ์ ๋ด๊ณ , isRightSideOpen์ RightSide.vue์ ์๋ open์ ์์ ์ ๊ฐ์ ์ ๋ฌํ๋ค๋ ๊ฒ.) ๋ค์ ํ๋ฆ์ ๋ํด์ ๋์ฑ ์์ธํ๊ฒ ์ค๋ช ํด๋๊ฒ ๋ค.
@Click="toggleRight"๋ ์ด๋ฏธ์ง๋ฅผ ํด๋ฆญ ์ MainView์์ toggleRight( ) ๋ฉ์๋๊ฐ ์คํ๋๋๋ก ํ๋ค.
:style="heartRightStyle"์ ์ด ์ด๋ฏธ์ง์ ์คํ์ผ์ ๋์ ์ผ๋ก ๋ฐ๊พธ๋๋ก ํ๋ค. ์ค๋ฅธ์ชฝ ํจ๋์ด ๋์ค๋ฉด ์์ด์ฝ๋ ๊ทธ ์์น์ ๋ง์ถฐ ์์ง์ฌ์ผํ๋ค. ์ค์ ์ ์ํ๋ฉด ํจ๋ ์์ ์์ด์ฝ์ด ์๋ ์ํฉ์ธ ์ฐ์ถ๋๋ค. ๊ทธ๊ฑธ ๋ฐฉ์งํ๊ณ ์ ์ด๋ฏธ ์ค์ ๋ style์ ๋์ ์ผ๋ก ๋ฐ๊พธ๋๋ก ๋ง๋ค๊ฒ์ด๋ค. ์ด ๋ถ๋ถ์ script์ computed ์์ฑ์์ ํด๊ฒฐํ ๊ฒ์ด๋ค.

- style
.right-sideBar {
position: fixed;
top: 50%;
transform: translateY(-50%);
width: 53px;
height: 48px;
cursor: pointer;
z-index: 1100;
transition: transform 0.15s cubic-bezier(.71, 1.7, .58, .98);
}
top: 50%๋ ์ ์ฒด์ ๋ฐ์ ์ ์์นํ๊ฒ ๋ค๋ ์ด์ผ๊ธฐ์ธ๋ฐ, ์ค์ ๋ก top: 50%๋ฅผ ํด๋ณด๋ฉด ๊ฐ์ด๋ฐ์ ์์นํ์ง ์๋ ๊ฑธ ์ ์ ์๋ค. ๊ทธ ์ด์ ๊ฐ์ด๋ฐ๋ฅผ ๋ฑ ์ฐ์ผ๋ฉด, ๋ฑ ์ฐ์ ์ง์ ์ ๋ด ์์์ ์ผ์ชฝ ์ ๋ชจ์๋ฆฌ๊ฐ ๋ฟ๋๋ค. ๊ทธ๋์ ์น์ฐ์น ๋ชจ์์ผ๋ก ์กด์ฌํ๋ค. ๊ทธ๊ฑธ ๋ฐ๋ก ์ก๊ธฐ ์ํด transform: translateY(-50%)๋ฅผ ํด์ค๋ค.
[Vue.js] transform: translate๋ก ํ ์คํธ ์ค์์ ๋ฐฐ์นํ๊ธฐ.
์ฐธ๊ณ ๋ก Vue.js์ ๋ํด์ ์ ๋ชจ๋ฆ ๋๋ค.์๋ฌด๊ฑฐ๋ ๋ง ํด๋ณด๋ ์ค์ด๊ณ ์ณ์ ์ ๋ณด์ธ์ง ์ ๋ ๋ชจ๋ฆ ๋๋ค! ๋ ธ๋ ๋ฐฐ๊ฒฝ๊น์ง ๋ง๋ค์๋ค.์ด๋ฒ์ ํ ์คํธ๋ฅผ ์ค์์ ๋ฐฐ์นํด๋ณด์! 1. ์ ์ฒด์ฝ๋ MainView.vue์ ํ ์คํธ๋ฅผ ๋ง
post-this.tistory.com
- script
import RightSide from "@/components/mainview/RightSide.vue";
import LeftSide from "@/components/mainview/LeftSide.vue";
์๊น RightSide.vue์์ export ํ๋ ๊ฒ์ MainView์์ import ํ๊ฒ ๋ค. ์ด๋ ์์น๋ ํจ๊ป ์ ์ด์ค์ผํ๋ค. import ๋ค์ ๋ถ์ RightSide๋ MainView์์ "@/components/mainview/RightSide.vue"; ์ด ๊ฒฝ๋ก์ ์์นํ RightSide.vue์ ์ด๋ฆ์ ์ ์ ๊ฒ์ด๋ค. ๊ผญ vue์ ์ด๋ฆ๊ณผ ๊ฐ์ง ์์๋ ๋๋ค. (ํ์ง๋ง ๋จ๋ค์ด ๋ดค์ ๋ ์ด๋ค ํ์ผ์ธ์ง ์๊ธฐ ์ฝ๋๋ก ์ด๋ฆ์ ์ ๋ ๊ฒ์ด ์ข๋ค)
์ด ๋ค์ ์ฝ๋๋ถํฐ๋ export default ์์ ์ ์ ์ฝ๋์ด๋ค.
name: 'MainView',
components: {RightSide, LeftSide},
๋ฐฉ๊ธ ๋ฐ์์จ ์ปดํฌ๋ํธ๋ฅผ MainView์์ ์ธ ์ ์๋๋ก ๋ฑ๋กํ๋ค. ๊ทธ๋ฆฌ๊ณ MainView๋ฅผ exportํ ์ด์ ๋ (์ฌ๊ธฐ ์ฝ๋์ ์์ง๋ง export default ์์ ํด๋น ์ฝ๋๊ฐ ๋ค์ด์์) ๋ผ์ฐํฐ๋ก ๋ฐ์์ ํ๋ฉด์ ๋ณด์ฌ์ค์ผ ํ๊ธฐ ๋๋ฌธ์ ํ ๊ฒ์ด๋ค.
data() {
return {
isRightSideOpen: false,
isLeftSideOpen: false,
}
},
๋ฐ์์จ ์ปดํฌ๋ํธ์ ๊ฐ์ false๋ก ์ค์ ํ์ฌ, ํ์์๋ ๋ณด์ด์ง ์๋๋ก ๋ง๋ค์๋ค. (right-side.open์ transform: translateX(0%)์ ์ค์ ํ๊ณ true ๊ฐ์ ๋ฐ์์ผ ์ด ์ฝ๋๊ฐ ํ์ฑํ๋๋ค)
computed: {
heartRightStyle() {
if (this.isRightSideOpen === true) {
return{
right: '23vw',
transition: 'right 0.4s cubic-bezier(.71, 1.7, .58, .98)'
}
}else {
return {
right: '32px',
transition: 'right 0.4s cubic-bezier(.71, 1.7, .58, .98)'
}
}
},
* template ์ฝ๋ *
<img src="../assets/rightHeartBar.png" alt="์ค๋ฅธ์ชฝํํธ" class="right-sideBar" :class="{isRightSideOpen : isRightSideOpen}"
@click="toggleRight" :style="heartRightStyle"/>
template์์ :style์ heartRightStyle๋ก ์ ์ํ๋ค.
this.isRightSideOpen์ data์ ์ ์ isRightSideOpen์ ๊ฐ๋ฆฌํจ๋ค. this๋ฅผ ์ ์ง ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ์๋ํ๋ฉด ์ธ๋ถ,๋ด๋ถ, ํจ์ ๋ฑ ์ฌ๋ฌ ๊ณณ์ ํด๋น ๋ณ์๊ฐ ๊ฐ์ ์ด๋ฆ์ผ๋ก ์กด์ฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋์ ์ง๊ธ ์ด ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฆฌํค๋ฉฐ ๋ด๋ถ์์ ์ ๊ทผํ ๋, ํญ์ this.๋ฅผ ๋ถ์ฌ์ผํ๋ค.
this.isRightSideOpen์ด true์ด๋ฉด ์ค๋ฅธ์ชฝ์์ 23vw๋งํผ ํํธ ์์ด์ฝ์ด ์์ง์ด๋๋ก ์ค์ ํ๋ค. ๊ทธ๋ฆฌ๊ณ else(false)๋ฉด 32px์ ์์นํ๋๋ก ํ๋ค. ๊ทธ๋์ ๋ซํ์์ผ๋ฉด ์ค๋ฅธ์ชฝ์์ 32px ๋จ์ด์ง ์์น์ ํํธ ์์ด์ฝ์ด ์๋ค. ์์ง์์ ํจ๋์ ์์ง์๊ณผ ๋๊ฐ์ด ์ ์๋ค.
methods: {
toggleRight() {
this.isRightSideOpen = !this.isRightSideOpen;
},
toggleLeft() {
this.isLeftSideOpen = !this.isLeftSideOpen;
},
},
}
* template ์ฝ๋ *
<img src="../assets/rightHeartBar.png" alt="์ค๋ฅธ์ชฝํํธ" class="right-sideBar" :class="{isRightSideOpen : isRightSideOpen}"
@click="toggleRight" :style="heartRightStyle"/>
toggleRight๋ ์์ด์ฝ์ ํด๋ฆญํ์๋ ๋ฐ์ํ ๋ฉ์๋์ด๋ค. toggleRight์์ isRightSideOpen์ ๊ฐ์ ๋ฐ์ ์ํฌ ๊ฒ์ด๋ค. isRightSideOpen์ ๊ธฐ๋ณธ๊ฐ์ false์๊ณ , ํด๋ฆญํ๋ฉด false์ ๊ฐ์ด ๋ฐ์ ๋์ด true๋ก ๋ฐ๋๋ค. ๊ทธ๋ฌ๋ฉด isRightSideOpen์ ๊ฐ์ true๊ฐ ๋๋ค. ๋ค์ ํด๋ฆญ์ ํ๊ฒ ๋๋ฉด true์ ๊ฐ์ด ๋ฐ์ ๋์ด false๊ฐ ๋๋ค.
5. ํ๋ฆ
- RightSide.vue
* template *
<div class="right-side" :class="{ open: open }">
open์ด๋ ์ด๋ฆ์ผ๋ก ๊ฐ์ ๋ฐ์ ๋์ ๋ฐ์ธ๋ฉ์ ์ค ๊ฒ์ด๋ค. ์ด๋ค ์์ง์์ ์ค๊น?
* style *
.right-side.open {
transform: translateX(0%);
}
์๋์ ๊ฐ์์ x์ถ์ 0%๋ก ์ฎ๊ธด ์์ง์์ ์ค๋ค.
* script *
props: {
open: {
type: Boolean,
required: true,
}
๋ถ๋ชจ ํด๋์ค์ธ MainView.vue์๊ฒ ๊ฐ์ ๋ฐ์์ฌ ์ ์๋๋ก ์ ์ํ๋ค.
- MainView.vue
* template *
<img src="../assets/rightHeartBar.png" alt="์ค๋ฅธ์ชฝํํธ" class="right-sideBar" :class="{isRightSideOpen: isRightSideOpen}"
@click="toggleRight" :style="heartRightStyle"/>
<RightSide :open="isRightSideOpen" />
:class="{isRightSideOpen: isRightSideOpen}
: ์ด๋ค ์ํ๊ฐ์ด ๋ฐ๋๋ฉด ํ๋ฉด์ด ์๋์ ํจ๊ป ๋ฐ๋๋๊ฒ ๋์ ๋ฐ์ธ๋ฉ. ์์ด์ฝ์ด ๋๋ฆฌ๋ฉด false ๊ฐ์ด true๋ก, true ๊ฐ์ด false๋ก ๋ฐ๋๋๋ก ํ๋ค.
<RightSide :open="isRightSideOpen" />
: isRightSideOpen์ RightSide์ props์ ์๋ open์ผ๋ก ๊ฐ์ด ๊ฐ๋๋ก ์ค์ ํ๋ค.
@click="toggleRight"
: ํด๋ฆญํ๋ฉด toggleRight ๋ฉ์๋๊ฐ ์คํ๋๋ค.
:style="heartRightStyle"
: ์์ด์ฝ์ ์์น๋ฅผ ํจ๋์ ์์ง์์ ๋ง์ถฐ ๋ฐ๊พธ๊ธฐ ์ํด ์ค์ ํ๋ค.
data() {
return {
isRightSideOpen: false,
isLeftSideOpen: false,
}
},
data( )์ ์ปดํฌ๋ํธ ๊ฐ ์ค์ ํ๋ค.
* script *
methods: {
toggleRight() {
this.isRightSideOpen = !this.isRightSideOpen;
},
๋ฒํผ์ด ๋๋ฆฌ๋ฉด isRightSideOpen ๊ฐ์ด ๋ฐ์ ๋๋ค. ์ฌ๊ธฐ์ true๋ก ๊ฐ์ด ๋ณํ๋ฉด ๊ทธ ๊ฐ์ด open์๊ฒ ์ ๋ฌ๋๋ค. ๊ทธ๋ฌ๋ฉด ์๊น .open์ ์ค์ ํ๋ x์ถ์ ๋ณ๋์ด ๋ํ๋๋ค.
computed: {
heartRightStyle() {
if (this.isRightSideOpen === true) {
return{
right: '23vw',
transition: 'right 0.4s cubic-bezier(.71, 1.7, .58, .98)'
}
}else {
return {
right: '32px',
transition: 'right 0.4s cubic-bezier(.71, 1.7, .58, .98)'
}
}
},
์์ด์ฝ๋ ๊ฐ์ด ์์ง์ธ๋ค. isRightSideOpen์ด true์ ๊ฐ์ด๋ฉด 23vw๋งํผ ์์ง์ธ๋ค. ๊ทธ๋ฆฌ๊ณ false ๊ฐ์ด ๋๋ฉด 32px ์์น๋ก ๋ค์ ์์ง์ธ๋ค.