Animated Rainbow Nyan Cat

์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ์›น ํŽ˜์ด์ง€์˜ ๊ตฌ์„ฑ๊ณผ ๊ณ„์ธต๊ตฌ์กฐ

์ถœ์ฒ˜ : https://dahye-jeong.gitbook.io/vue-js/vuejs/2019-10-15-component

pinia ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•œ๋‹ค.

 

ref ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋Š” ๋ณ€์ˆ˜๋ช….value ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค. reactive๋Š” ๊ฐ์ฒด์˜ ์†์„ฑ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

๋ถ€๋ชจ์—์„œ๋Š” ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ๋ฏธ๋ฆฌ ๊ตฌํ˜„ํ•ด๋†จ๋‹ค๊ฐ€ emit์ด๋ผ๋Š” ํ•จ์ˆ˜์— ์˜ํ•ด์„œ ์‹ค์ œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹คํ• ๋•Œ ์ž์‹์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Vue 3์˜ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ํ†ต์‹  ๋ฐฉ๋ฒ• : (1) props ๋ถ€๋ชจ์—์„œ ์ž์‹์œผ๋กœ (2) emit ์ž์‹์ด ๋ถ€๋ชจ์—๊ฒŒ (3) v-model (4) slots (5) provide/inject (6) pinia

 

toRefs : ๋ฐ˜์‘์„ฑ์€ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ๊ฐ€๊ณ  ์‹ถ์„ ๋•Œ.. ๋ฐ˜์‘์„ฑ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด ์ฒ˜๋ฆฌํ•˜๊ฒ ๋‹ค ๋ผ๋Š” ๋œป..

 

 

์ž์‹ ์ปดํฌ๋„ŒํŠธ.

<template>
  <button type="button" @click="childFunc" ref="btn">์ž์‹๋ฒ„ํŠผ</button>
</template>
<script setup>
const childFunc = function () {
  window.alert('์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฒ„ํŠผํƒœ๊ทธ์—์„œ ๋ฐœ์ƒ๋œ ํด๋ฆญ์ด๋ฒคํŠธ!!');
}
</script>

๋ถ€๋ชจ ์ปดํผ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ์ง์ ‘ ์•ก์„ธ์Šคํ•˜๊ฒ ๋‹คํ•  ๋•Œ $refs๋ฅผ ์“ด๋‹ค. $๊ฐ€ ๋ถ™์–ด์žˆ์œผ๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด.

$refs.child1์ด๋ผ๊ณ  ์ ‘๊ทผํ•œ๋‹ค. ์•„๋ž˜๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ.

<template>
  <button @mouseover="sendMessage">๋ถ€๋ชจ๋ฒ„ํŠผ</button>
  <child-component ref="child1" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  components: { ChildComponent },
  methods: {
    sendMessage: function () {
      alert("child1์ด๋ผ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฒ„ํŠผ์— ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.");
      this.$refs.child1.$refs.btn.click();  // ์ž์‹ DOM ๊ฐ์ฒด์— ์ด๋ฒคํŠธ ๋ฐœ์ƒ      
    }
  }
};

this.$refs.child1.$refs.btn.click(); ์ด ์ฝ”๋“œ๋Š” child-component์—์„œ ref๊ฐ€ child1์ด๋ฏ€๋กœ this.$refs.child1์ด๋Ÿฐ์‹์œผ๋กœ ์ ‘๊ทผํ•œ ํ›„์— child1์ด๋ผ๋Š” ์ž์‹๊ฐ์ฒด์˜ ref์˜ btn์ด ํด๋ฆญ๋˜๋„๋กํ•˜๋Š” ์ฝ”๋“œ๋‹ค. ํ•ด๋‹น ํƒœ๊ทธ์—๋Š” ๋ฐ˜๋“œ์‹œ ref๊ฐ€ ์žˆ์–ด์•ผ ์ฐพ์•„๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

 

<template>
  <child-component2  ref="child2">
    ์ด๊ฑด slot ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ์šฉ ์ปจํ…ํŠธ~~
  </child-component2>
</template>

์ด๋Ÿฐ์‹์œผ๋กœ ์ž์‹ ๊ฐ์ฒด๋กœ ๋„˜๊ฒจ์ค„์ˆ˜ ์žˆ๋‹ค. ์œ„ ์ฝ”๋“œ๋Š” ๋ถ€๋ชจ ์ปจํฌ๋„ŒํŠธ์—์„œ ์“ฐ์ธ๊ฑฐ

<template>
  <h3>์ž์‹์ปดํฌ๋„ŒํŠธ</h3>
  <slot></slot>
</template>

์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋Ÿฐ์‹์œผ๋กœ ๋„ฃ๊ณ  ์‹ถ์€ ์ž๋ฆฌ์— slot์„ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์Šฌ๋กฏ์€ ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ์„ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•˜๊ณ  ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์ฒด ํ…œํ”Œ๋ฆฟ ๋‚ด์—์„œ ์ „๋‹ฌ๋œ ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ์„ ๋ Œ๋”๋งํ•˜๋„๋ก ํ•˜๋Š” ๊ธฐ๋Šฅ.

 

์ถœ์ฒ˜ : https://vuejs.org/guide/components/slots.html

 

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ

mounted() {
    this.$refs.child2.callFromParent();
  }

์ด๋Ÿฐ์‹์œผ๋กœ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ •์˜๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

 

<script>
export default {
  data() {
    return {
      msg: 'Option API๋ฅผ ์‚ฌ์šฉํ•œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ณด๋‚ด๋Š” ๋ฉ”์‹œ์ง€'
    };
  },
  mounted() {
    this.$emit('send-message', this.msg)
  }
}
</script>

์ด๋Ÿฐ์‹์œผ๋กœ Option API ๋ฐฉ์‹์œผ๋กœ ๋ฉ”์„ธ์ง€๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž‘์„ฑํ•˜๊ณ  ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๋ฐœ์ƒํ•  ์ด๋ฒคํŠธ ์ด๋ฆ„, ์ „๋‹ฌํ•  ๋ฉ”์„ธ์ง€๋ฅผ ์•„๊ทœ๋จผํŠธ๋กœ ์ฃผ๋ฉด ๋œ๋‹ค. 

<child-component-option @send-message="sendMessage" />

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ…œํ”Œ๋ฆฟ์— ์ด๋Ÿฐ์‹์œผ๋กœ ์ž‘์„ฑํ•œ ํ›„์—(send-message๋ผ๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด sendMessage๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ํ•œ๋‹ค๋ผ๋Š” ๋œป. ์—ฌ๊ธฐ์„œ child-component-option์€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„..)

methods: {
    sendMessage(data) {
      console.log("@@ : " + data);
    }
  }

์Šคํฌ๋ฆฝํŠธ ๋ถ€๋ถ„์—์„œ ์ด๋Ÿฐ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ „๋‹ฌ๋œ ๋ฉ”์„ธ์ง€๊ฐ€ ์ฝ˜์†”์ฐฝ์—์„œ ๋ณด์ด๊ฒŒ ๋œ๋‹ค.

 

Composition API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํฌ๋ฆฝํŠธ ๋ถ€๋ถ„์—์„œ

import { onMounted } from 'vue'
export default {
  emits: ['send-message'],
  setup(props, context) {
    const msg = 'Composition API๋ฅผ ์‚ฌ์šฉํ•œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ณด๋‚ด๋Š” ๋ฉ”์‹œ์ง€';
    const { emit } = context;
    onMounted(() => {
      emit('send-message', msg)
    })
  }
}

๋ฐ˜๋“œ์‹œ emits ๋ผ๋Š” ์†์„ฑ์— ๋„ฃ์–ด์ฃผ๊ณ , emit์ด๋ผ๋Š” ํ•จ์ˆ˜๋กœ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค. $emit์€ ํ”„๋ก์‹œ์— ๋‹ด๊ธด ๊ฑธ ๋‹ค์ด๋ ‰ํŠธ๋กœ ์“ฐ๋Š” ๋ฐฉ๋ฒ•์ด์—ˆ๋‹ค. 

 

script๋’ค์— setup์†์„ฑ์„ ์ค˜์„œ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด

<script setup>
import { onMounted, defineEmits } from 'vue';
const emit = defineEmits(["send-message"]);
const msg = 'Composition Setup API๋ฅผ ์‚ฌ์šฉํ•œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ณด๋‚ด๋Š” ๋ฉ”์‹œ์ง€';
onMounted(() => {
  emit('send-message', msg)
})
</script>

defineEmitsํ•˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•ด์ค€๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” emit์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ฐ›์•˜๋‹ค. 

 

provide์™€ inject

์ถœ์ฒ˜ : https://vuejs.org/guide/components/provide-inject.html

 

 

'๐Ÿ’ผ Full-Stack Study โ‘ก (feat. KOSA)' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Docker  (1) 2023.11.29
Vue.js (Pinia, Spring Security JWT)  (0) 2023.11.13
Vue.js (3)  (0) 2023.11.09
Vue.js (watch)  (0) 2023.11.08
Vue.js  (0) 2023.11.06