๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
[๊ฐœ๋ฐœ] Practice/Vue.js

[Vue.js] Vue ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ํ™œ์šฉํ•˜๊ธฐ

by Connecting-the-dots 2022. 4. 4.
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ’ก ์‹ค์Šต ํฌ์ธํŠธ!

๐Ÿ’œ ๊ณผ์ œ 1. ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ ‘์†ํ•˜๋ฉด ๋งค 1์ดˆ๋งˆ๋‹ค ํ• ์ธ ๋ฐฐ๋„ˆ์˜ ํผ์„ผํŠธ๋ฅผ 1%์”ฉ ๊ฐ์†Œ์‹œํ‚ค๊ธฐ

  • 30์ดˆ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์„ GIF ๋กœ ์บก์ฒ˜ํ•˜๊ธฐ์—” ๋ฌด๋ฆฌ๊ฐ€ ์žˆ์–ด์„œ 5์ดˆ๋งŒ ์นด์šดํŠธํ•˜๋Š” ๊ฑธ๋กœ ์ˆ˜์ •ํ–ˆ๋‹ค.

๐Ÿ’œ ๊ณผ์ œ 2. ๋ชจ๋‹ฌ์ฐฝ์˜ input ์— 2๋ฅผ ๊ธฐ์ž…ํ•˜๋ฉด ์•Œ๋ฆผ์ฐฝ ๋„์šฐ๊ณ  ๊ฐ•์ œ๋กœ input ๊ณต๋ž€ ๋งŒ๋“ค๊ธฐ

  • 1์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ๋Š” ์ •์ƒ์ ์œผ๋กœ ์ด ๊ธˆ์•ก๊ณผ ํ•จ๊ป˜ ์ถœ๋ ฅ๋˜์ง€๋งŒ, 2๋ฅผ ์ž…๋ ฅํ•˜๋ฉด input ์ฐฝ์€ ๊ณต๋ž€์œผ๋กœ ๋‚˜์˜ค๊ณ , ์•Œ๋ฆผ์ฐฝ์ด ๋œจ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’œ Vue ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ์•Œ์•„๋ณด๊ธฐ

  • Vue ๊ณต์‹๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด, ์œ„์™€ ๊ฐ™์ด Component ์˜ ์ƒ์„ฑ, ์†Œ๋ฉธ ํ˜น์€ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๊ณผ์ •์„ step ๋ณ„๋กœ ๊ทธ๋ ค์„œ Lifecycle ์„ ์„ค๋ช…ํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ , ์œ„์˜ ๊ณผ์ •์„ ์ดํ•ดํ•˜๋ฉด ์ด์ œ Lifecycle hook ์ด๋ผ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

  • ๋จผ์ € Component ๋Š” create -> mount ์˜ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์„œ ์ƒ์„ฑ์ด ๋œ๋‹ค.
    (create ๋Š” Component ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ, mount ๋Š” index.html ํŒŒ์ผ์— Component ๋ฅผ ์žฅ์ฐฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.)
  • ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ์–ด์„œ Component ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋  ๋•Œ์—๋Š” update ์˜ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นœ๋‹ค.
  • ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™์„ ํ•˜๋Š” ๋“ฑ์˜ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜์—ฌ Component ๊ฐ€ ์‚ญ์ œ๋˜๋ฉด unmount ๋ผ๋Š” ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นœ๋‹ค.

 

beforeCreate()
created()
beforeMount()
mounted()
beforeUpdate()
updated()
beforeUnmount()
unmounted()
  • create, mount, update, unmount ๋“ฑ์˜ ๋‹จ๊ณ„๋“ค ์ค‘๊ฐ„์ค‘๊ฐ„์— ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ๋•Œ ์œ„์™€ ๊ฐ™์€ Lifecycle hook ์„ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๊ณจ๋ผ์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

data(){
  return {
  }
},
mounted(){
  // ์—ฌ๊ธฐ์— mount ๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•  ์ฝ”๋“œ ์ž‘์„ฑ!
}
  • Lifecycle hook ์€ <script></script> ์•ˆ์— data ์™€ ๋‚˜๋ž€ํžˆ ์ž‘์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • ํŠนํžˆ, ์„œ๋ฒ„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ, ์ด ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฝ”๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ mounted() ํ˜น์€ created() ์— ์ž‘์„ฑํ•œ๋‹ค.

๐Ÿ’œ ๊ณผ์ œ 1. ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ ‘์†ํ•˜๋ฉด ๋งค 1์ดˆ๋งˆ๋‹ค ํ• ์ธ ๋ฐฐ๋„ˆ์˜ ํผ์„ผํŠธ๋ฅผ 1%์”ฉ ๊ฐ์†Œ์‹œํ‚ค๊ธฐ

๐Ÿค ๊ณผ์ œ ํ™•์ธํ•˜๊ธฐ

  • ํ• ์ธ ๋ฐฐ๋„ˆ์—๋Š” ํ˜„์žฌ ๊ธฐ๋ณธ์ ์œผ๋กœ "์ง€๊ธˆ ๊ฒฐ์ œํ•˜๋ฉด 30% ํ• ์ธ" ์ด๋ผ๊ณ  ์ ํ˜€ ์žˆ๋‹ค.
  • ์œ„ ํ• ์ธ ๋ฐฐ๋„ˆ ๋ฌธ๊ตฌ๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€์— ์ ‘์†ํ•œ ํ›„ 1์ดˆ๊ฐ€ ์ง€๋‚  ๋•Œ๋งˆ๋‹ค 1%์”ฉ ๊ฐ์†Œํ•ด์•ผ ํ•œ๋‹ค.
  • ํผ์„ผํŠธ ๋ถ€๋ถ„์˜ ์ˆซ์ž๊ฐ€ 0 ๋ฐ‘์œผ๋กœ ๋–จ์–ด์ง€๋ฉด ์•ˆ๋œ๋‹ค. (์ฆ‰, -1%, -2%.. ์ด๋Ÿฐ ์‹์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉด ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ!)

๐Ÿค ๊ณผ์ œ ์ƒ๊ฐํ•ด๋ณด๊ธฐ

  • ์œ„ ๊ณผ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ํผ์„ผํŠธ๊ฐ€ 0% ์ธ ์ƒํ™ฉ์—์„œ ํ• ์ธ ๋ฐฐ๋„ˆ๊ฐ€ ๋ณด์ด๋Š” ๊ฒƒ๋„ ์ด์ƒํ•˜๋‹ค ์‹ถ์–ด์„œ, ์ถ”๊ฐ€๋กœ 0% ๊ฐ€ ๋˜๋ฉด ํ• ์ธ ๋ฐฐ๋„ˆ๋ฅผ ์•ˆ ๋ณด์ด๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ฃผ์—ˆ๋‹ค.
  • ํ• ์ธ ๋ฐฐ๋„ˆ๋ฅผ App.vue ์—์„œ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  Discount.vue ํŒŒ์ผ๋กœ Component ๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด๋†“์•„์„œ ์กฐ๊ธˆ ํ—ท๊ฐˆ๋ ธ์ง€๋งŒ ๊ธˆ๋ฐฉ ํ•ด๋‚ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
  • ์ผ๋‹จ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    • ํ• ์ธ ๋ฐฐ๋„ˆ์˜ 30 ์ด๋ผ๋Š” ์ˆซ์ž๋Š” ๊ณ„์† ๋ณ€๊ฒฝ๋˜์–ด ์ €์žฅ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ data ๋ณด๊ด€ํ•จ์— ์ €์žฅ์ด ํ•„์š”ํ•˜๋‹ค.
    • App Component ๊ฐ€ Discount Component ๋ณด๋‹ค ์ƒ์œ„ Component ์ด๋ฏ€๋กœ mounted() ์™€ data ๋Š” App Component ์—์„œ ์ €์žฅ ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.
    • ๋”ฐ๋ผ์„œ, data ๋ฅผ ํ•˜์œ„ Component ์ธ Discount Component ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” App Component ์—์„œ Discount Component ์— props ๋กœ ์ „๋‹ฌํ•˜์—ฌ Discount Component ์—์„œ props ๋กœ ๋ฐ›์•„ ๋“ฑ๋ก ํ›„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
    • mounted() ์—๋Š” setInterval() ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆซ์ž๊ฐ€ 1๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ์—๋Š” -1 ์„ ํ•ด์ฃผ๊ณ , ์ˆซ์ž๊ฐ€ 1 ์ด ๋˜๋ฉด ํ• ์ธ ๋ฐฐ๋„ˆ๋ฅผ ์•ˆ๋ณด์ด๊ฒŒ ํ•œ ํ›„ clearInterval() ์„ ํ†ตํ•ด ์ธํ„ฐ๋ฒŒ ํƒ€์ด๋จธ๋ฅผ ์‚ญ์ œํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๐Ÿค ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

// App.vue ์ „์ฒด ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ „์ฒด ์ฝ”๋“œ์˜ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

<template>
	<Discount v-if="showDiscount == true" :decreaseDiscount="decreaseDiscount"/>
</template>


<script>
export default {
	name: "App",
	
	data(){
		return {
			showDiscount : true,
			decreaseDiscount : 30,
		}
	},

	mounted(){
		setInterval(() => {
			if (this.decreaseDiscount > 1){
				this.decreaseDiscount--;
			} else if (this.decreaseDiscount == 1){
				this.showDiscount = false;
				clearInterval();
			}
		}, 1000);
	},
};
</script>
  • ๋จผ์ € <Discount /> ๊ฐ€ ๋ณด์ด๋Š”์ง€์˜ ์—ฌ๋ถ€๋ฅผ true / false ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก data ๋ณด๊ด€ํ•จ์— showDiscount ๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ €์žฅํ•ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  <Discount/> ์— v-if ๋ฌธ์„ ํ†ตํ•ด showDiscount ๊ฐ€ true ์ผ ๋•Œ๋งŒ <Discount/> ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค.
  • ๊ทธ ํ›„ mounted() ์— setInterval() ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.
    (์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ• ์ง€ ์œ„์—์„œ ์ด์•ผ๊ธฐํ–ˆ๊ณ , ๊ทธ๋Œ€๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ƒ๋žตํ•œ๋‹ค.)
  • ์ด์ œ, ๊ณ„์† ๋ณ€๊ฒฝ๋˜๋Š” ํผ์„ผํŠธ๋ฅผ props ๋กœ Discount Component ๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด decreaseDiscount ์— 30์ด๋ผ๋Š” ์ˆซ์ž๋ฅผ ์ €์žฅํ•œ ํ›„ :decreaseDiscount="decreaseDiscount" ๋ผ๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ props ๋กœ ์ „์†กํ•ด์ฃผ์—ˆ๋‹ค.

 

// Discount.vue ์ „์ฒด ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ „์ฒด ์ฝ”๋“œ์˜ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

<template>
    <div class="discount">
        <p>์ง€๊ธˆ ๊ฒฐ์ œํ•˜๋ฉด {{ decreaseDiscount }}% ํ• ์ธ!</p>
    </div>
</template>


<script>
export default {
    name: 'Discount',
	props: {
		decreaseDiscount: Number,
	},
}
</script>
  • props ๋Š” ๋“ฑ๋กํ•˜๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ, <script></script> ์— decreaseDiscount : Number ๋ผ๊ณ  props ๋กœ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ ์ด๋ฆ„๊ณผ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.
  • ์ด์ œ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ, ํ• ์ธ ๋ฐฐ๋„ˆ์˜ ๋ฌธ๊ตฌ ์ค‘ ๊ฐ’์ด ๊ณ„์† ๋ณ€ํ•˜๋Š” ๋ถ€๋ถ„์— {{ decreaseDiscount }} ๋ผ๊ณ  ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์„ ํ•ด์ฃผ์—ˆ๋‹ค.

 

 


๐Ÿ’œ ๊ณผ์ œ 2. ๋ชจ๋‹ฌ์ฐฝ์˜ input ์— 2๋ฅผ ๊ธฐ์ž…ํ•˜๋ฉด ์•Œ๋ฆผ์ฐฝ ๋„์šฐ๊ณ  ๊ฐ•์ œ๋กœ input ๊ณต๋ž€ ๋งŒ๋“ค๊ธฐ

๐Ÿค ๊ณผ์ œ ํ™•์ธํ•˜๊ธฐ

  • ๋ชจ๋‹ฌ์ฐฝ ์•ˆ์— input ์ด ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์— 2๋ฅผ ๊ธฐ์ž…ํ–ˆ์„ ๋•Œ ์•Œ๋žŒ์ฐฝ์„ ๋„์›Œ์•ผ ํ•œ๋‹ค.
  • ๊ธฐ์กด์—๋Š” watcher ๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ์˜ค๋Š˜ ๊ณต๋ถ€ํ•œ Lifecycle hook ์„ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ํžŒํŠธ) ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด Component ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋˜๋Š”๋ฐ ์ด๊ฒƒ์„ ๋ผ์ดํ”„์‚ฌ์ดํด ์šฉ์–ด๋กœ update ๋ผ๊ณ  ํ•œ๋‹ค. 
  • ์‘์šฉ์œผ๋กœ 2๋ผ๋Š” ๊ฒƒ์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ, ๊ฐ•์ œ๋กœ ๊ฐ’์„ ๋ฐ”๊พธ์–ด๋ณด์ž!

๐Ÿค ๊ณผ์ œ ์ƒ๊ฐํ•ด๋ณด๊ธฐ

  • update ๊ฐ€ ๋˜๊ธฐ ์ „์— Lifecycle hook ์„ ๊ฑธ์–ด์•ผ ํ•˜๋ฏ€๋กœ beforeUpdate() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • ๊ณผ์ œ ์ž์ฒด๋Š” ์–ด๋ ต์ง€ ์•Š์•˜์ง€๋งŒ, months ์— watcher ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ค‘์—๋Š” ์ด์ƒํ•˜๊ฒŒ ๋™์ž‘์„ ํ•˜๊ธฐ์— months ์— ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” watcher ๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌํ•˜๋‹ˆ๊นŒ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๐Ÿค ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ 

// Modal.vue ์ „์ฒด ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ „์ฒด ์ฝ”๋“œ์˜ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

<script>
export default {
	beforeUpdate(){
		if (this.months === '2'){
			alert('2๊ฐœ์›”์€ ์„ ํƒ์ด ๋ถˆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.')
			this.months = '';
		}
	}   
</script>

 

728x90
๋ฐ˜์‘ํ˜•