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

[Vue.js] Composition API ์‚ฌ์šฉํ•ด๋ณด๊ธฐ_2

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

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

  • ์˜ค๋Š˜์€ Composition API ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒ”๋กœ์›Œ ๊ฒ€์ƒ‰๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.
  • ์•„์ง Composition API ์‚ฌ์šฉ์ด ๋ฏธ์ˆ™ํ•˜์—ฌ ์ด์ „์— ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ๋“ค์„ ํ•˜๋‚˜์”ฉ ์ฐพ์•„๊ฐ€๋ฉฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผํ•˜๊ธด ํ–ˆ์ง€๋งŒ ๊ณ„์†ํ•ด์„œ ๋ง‰ํžˆ๋Š” ๋ถ€๋ถ„์„ ์‹œ๋„ํ•˜์—ฌ ์ตœ์ข…์ ์œผ๋กœ ๊ธฐ๋Šฅ์„ ์ž˜ ๋งŒ๋“ค์–ด๋ƒˆ๋‹ค.
  • ๋‚˜๋Š” match() ์™€ ์ •๊ทœ์‹์„ ์ด์šฉํ–ˆ๋Š”๋ฐ, ๊ฐ•์‚ฌ๋‹˜์€ indexOf() ๋ฅผ ์ด์šฉํ•˜์…จ๊ธฐ์— ์ฝ”๋“œ ๋ถ„์„๋„ ๊ฐ™์ด ์ง„ํ–‰ํ•ด๋ณด์•˜๋‹ค.

๐Ÿ’œ ref() ๋ง๊ณ  reactive() ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

import { ref, reactive } from 'vue'

export default {
  setup(){
    let followers = ref([]);
    let test = reactive({name : 'Seoyun'})

    return { followers }
  },
}
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” ref() ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ๋ฐฐ์› ์ง€๋งŒ reactive() ๋„ import ํ•ด์˜ค๋ฉด ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ref() ๋ฅผ ์‚ฌ์šฉํ•˜๋“  reactive() ๋ฅผ ์‚ฌ์šฉํ•˜๋“  ๋™์ผํ•œ ์—ญํ• ์„ ํ•˜๋Š”๋ฐ ref() ๋Š” ์ˆซ์ž, ๋ฌธ์ž์™€ ๊ฐ™์€ ์›์‹œ ์ž๋ฃŒํ˜•(Primitive data type) ์„, reactive() ๋Š” object, array ์™€ ๊ฐ™์€ ์ฐธ์กฐ ์ž๋ฃŒํ˜•(reference data type) ์„ ์ฃผ๋กœ ๋‹ด๋Š”๋‹ค.
    (๋‘˜ ๋‹ค ๋™์ผํ•œ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ๋ถ„ํ•˜๊ธฐ ๊ท€์ฐฎ์œผ๋ฉด ref() ๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.)

๐Ÿ’œ props ์‚ฌ์šฉํ•˜๊ธฐ

import { ref, toRefs } from 'vue'

export default {
  setup(props){
    let followers = ref([]);
    let { props์ด๋ฆ„ } = toRefs(props)  
    console.log(props์ด๋ฆ„.value)
    return { followers }
  },
}
  • Composition API ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐœ๋ฐœํ•  ๋•Œ setup() ์•ˆ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋˜๊ธด ํ•˜์ง€๋งŒ, setup() ์•ˆ์—์„œ๋Š” ๋“ฑ๋กํ•œ props ๋ฅผ this.props ์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋”ฐ๋ผ์„œ, props ๋ฅผ ๊ผญ ๊ฐ€์ ธ์™€์„œ ๋ญ”๊ฐ€ ๊ฐœ๋ฐœ์„ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
  • setup() ์•ˆ์—๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋‘ ๊ฐœ๊นŒ์ง€ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ž๋™์œผ๋กœ props ๊ฐ€ ๋˜๊ณ , ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” context ์ด๋‹ค.
  • ๋‹จ, ์ด๋ฅผ ๊ทธ๋ƒฅ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์—†๊ณ , ์‹ค์‹œ๊ฐ„ ๋ฐ˜์˜์ด ์ž˜ ๋˜๋„๋ก ์‚ฌ์šฉํ•˜๋ ค๋ฉด ref() ์•ˆ์— ๋‹ด์•„์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • props ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ์—๋Š” ref() ๊ฐ€ ์•„๋‹Œ toRefs() ๋ฅผ import ํ•ด์™€์„œ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.
    (toRefs() ๋Š” ref() ์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋˜, ref() ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.)
  • ๊ทธ๋ฆฌ๊ณ  toRefs() ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๋“ฑํ˜ธ ์™ผ์ชฝ์— { props์ด๋ฆ„1, props์ด๋ฆ„2 ... } ์ด๋Ÿฐ ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
  • props ๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด .value ๋ฅผ ๋ถ™์—ฌ์„œ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ’œ watch ์‚ฌ์šฉํ•˜๊ธฐ

import { ref, watch } from 'vue'

export default {
  setup(props){
    let followers = ref([]);
    watch( ๋ฐ์ดํ„ฐ์ด๋ฆ„, ()=>{ ๋ฐ์ดํ„ฐ์— ๋ณ€ํ™”๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ์‹คํ–‰ํ•  ์ฝ”๋“œ } )
    return { followers }
  },
}
  • Composition API ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐœ๋ฐœํ•  ๋•Œ, setup() ์•ˆ์—์„œ watch ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์‹œํ•˜๊ณ  ์‹ถ์œผ๋ฉด ์œ„์™€ ๊ฐ™์ด watch() ๋ฅผ import ํ•ด์™€์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • watch() ๋Š” props ๋„ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. 

๐Ÿ’œ computed ์‚ฌ์šฉํ•˜๊ธฐ

import { ref, computed } from 'vue'

export default {
  setup(props){
    let followers = ref([]);
    let ๋ณ€์ˆ˜์ด๋ฆ„ = computed( ()=>{ return 10 } )
    console.log(๋ณ€์ˆ˜์ด๋ฆ„.value)
    return { followers }
  },
}
  • computed ๋Š” ๋ฐ์ดํ„ฐ์˜ ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ์ž ๊น ์ €์žฅํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • computed ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ์—๋Š” computed ๋ฅผ import ํ•ด์˜จ ๋‹ค์Œ์— ์†Œ๊ด„ํ˜ธ ์•ˆ์— ํ•จ์ˆ˜ ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋ฅผ return ํ•ด์ฃผ๋Š”๋ฐ ์ด๋ฅผ ๋ณ€์ˆ˜์— ๋‹ด์•„์„œ ํ•„์š”ํ•œ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • computed ๋„ ์ผ์ข…์˜ ๋ฐ์ดํ„ฐ ์ทจ๊ธ‰์„ ๋ฐ›์œผ๋ฏ€๋กœ .value ๋ฅผ ์ ์–ด์ฃผ์–ด์•ผ ์ž˜ ์ถœ๋ ฅ๋œ๋‹ค.

๐Ÿ’œ methods ์‚ฌ์šฉํ•˜๊ธฐ

import { ref } from 'vue'

export default {
  setup(props){
    let followers = ref([]);
    
    function hello(){
    
    }
    return { followers, hello }
  },
}
  • Options API ์—์„œ๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ methods ์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ–ˆ์ง€๋งŒ, Composition API ์—์„œ๋Š” setup() ์•ˆ์ด๋ผ๋ฉด ์–ด๋Š๊ณณ์ด๋“  ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ๋‚˜์„œ return ์•ˆ์— ํ•จ์ˆ˜๋ช…์„ ์ ์œผ๋ฉด <template></template> ์—์„œ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

๐Ÿ’œ Vuex store ์‚ฌ์šฉํ•˜๊ธฐ

import { ref } from 'vue'
import { useStore } from 'vuex'

export default {
  setup(props){
    let followers = ref([]);
    let store = useStore();
    console.log(store.state.name)
    return { followers }
  },
}
  • setup() ์—์„œ $store.state.name ๊ฐ™์ด Vuex store ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ์ด ๋•Œ๋Š”, ๋จผ์ € useStore ๋ฅผ vuex ์—์„œ import ํ•ด์ค€๋‹ค.
  • useStore() ๋ผ๊ณ  ์ ์œผ๋ฉด ์ด๊ฒŒ $store ์™€ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ์ง€๋‹ˆ๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋ฅผ store ๋ผ๋Š” ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•˜๋ฉด $ ๊ธฐํ˜ธ๋งŒ ๋—€ ๊ฒƒ์ฒ˜๋Ÿผ ๊ฑฐ์˜ ์œ ์‚ฌํ•˜๊ฒŒ state ๋ฅผ ๋ฝ‘์•„๋‚ด๋“ ์ง€ commit() ์„ ํ•˜๋“ ์ง€, dispatch() ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.
  • ๋‹จ, mapState ๋Š” setup() ์•ˆ์—์„œ ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€ํ•˜๋‹ค.

๐Ÿ’œ ํŒ”๋กœ์›Œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

<input class="search" @input="search($event.target.value)" placeholder="๐Ÿ”" />

 

import { onMounted, ref } from "vue";
import axios from "axios";

export default {
  name: "MyPage",
  setup() {
    let followers = ref([]);

    onMounted(() => {
      axios.get("/followers.json").then((result) => {
        followers.value = result.data;
      });
    });

    function search(input) {
      let filtered = followers.value.filter((follower) => {
        return follower.name.match(new RegExp(input, "i"));
      });
      followers.value = [...filtered];
    }

    return { followers, search };
  }
};
  • ์ด์ „์— followers.json ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ๋งŒ ํ•ด์ฃผ์—ˆ๋Š”๋ฐ, ์ด๋ฒˆ์—๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋“ค์—์„œ input ์— ์ž…๋ ฅํ•œ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ์‚ฌ๋žŒ๋“ค์„ ๊ฒ€์ƒ‰ํ•ด์ฃผ๋Š” ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.
  • ๋จผ์ € input ์— @input ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ input ์ด ์ˆ˜์ •๋  ๋•Œ, search() ๋ผ๋Š” ํ•จ์ˆ˜์— input ์— ์ž…๋ ฅ๋œ ๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•ด์ฃผ์—ˆ๋‹ค.
  • ์ด์ œ search()๋Š” filter() ๋ฅผ ์‚ฌ์šฉํ•ด์„œ follower ๋ฐ์ดํ„ฐ ํ•˜๋‚˜ํ•˜๋‚˜๋ฅผ input ์— ์ž…๋ ฅ๋œ ๊ฐ’๊ณผ ๋น„๊ตํ•ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ์ž…๋ ฅ๋œ ๊ฐ’๊ณผ follower ๋ฅผ ๋น„๊ตํ•  ๋•Œ์—๋Š”, match() ๋ฅผ ์‚ฌ์šฉํ•ด์„œ input ์— ์ž…๋ ฅ๋œ ๊ฐ’์„ ๋Œ€์†Œ๋ฌธ์ž ์ƒ๊ด€์—†์ด follower ๊ฐ€ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฉด ํ•ด๋‹น follower ๋ฅผ return ํ•ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ์ด ๊ฐ’์„ filtered ์— ์ €์žฅํ•œ ๋‹ค์Œ, ์•ˆ์ „ํ•˜๊ฒŒ filtered ๋ฅผ ๋ณต์‚ฌํ•ด์„œ followers.value ์— ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.
  • ๊ทผ๋ฐ ์—ฌ๊ธฐ๊นŒ์ง€ํ•˜๋ฉด, ๊ฒ€์ƒ‰์„ ํ•˜๊ณ  ์ง€์šฐ๋ฉด ํŒ”๋กœ์›Œ ๋ชฉ๋ก์—์„œ ํŒ”๋กœ์›Œ๋“ค์ด ์‚ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.
  • followers ์—์„œ ํ•„ํ„ฐ๋ง์„ ํ•ด์„œ followers ์— ์žฌํ• ๋‹น์„ ํ•˜๊ณ  ๋˜ ๊ฑฐ๊ธฐ์„œ ํ•„ํ„ฐ๋ง์ด ์ง„ํ–‰๋˜๋Š” ๊ฒŒ ๋ฐ˜๋ณต๋˜๋‹ค๋ณด๋‹ˆ ๊ฒฐ๊ตญ์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋‚จ์ง€ ์•Š์€ ๊ฒƒ์ด๋‹ค.

 

import { onMounted, ref } from "vue";
import axios from "axios";

export default {
  name: "MyPage",
  setup() {
    let followersOriginal = ref([]);
    let followers = ref([]);

    onMounted(() => {
      axios.get("/followers.json").then((result) => {
        followersOriginal.value = result.data;
        followers.value = [...result.data];
      });
    });

    function search(input) {
      let filtered = followersOriginal.value.filter((follower) => {
        return follower.name.match(new RegExp(input, "i"));
      });
      followers.value = [...filtered];
    }

    return { followers, search };
  }
};
  • ๊ทธ๋ž˜์„œ ์œ„์™€ ๊ฐ™์ด followersOriginal ์ด๋ผ๋Š” followers ์™€ ๋˜‘๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด๋†“๊ณ , ๊ฒ€์ƒ‰์–ด๋ฅผ ์‚ญ์ œํ•ด์„œ followers ๋ฐ์ดํ„ฐ๋Š” ์ˆ˜์ •๋˜์–ด๋„ followersOriginal ์€ ์ˆ˜์ •๋˜์ง€ ์•Š๊ณ  ๋ณด์กด๋˜๋ฏ€๋กœ ๊ณ„์†ํ•ด์„œ ํ•„ํ„ฐ๋Š” followersOriginal ์—์„œ ์ง„ํ–‰ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ์—ˆ๋‹ค. 

 

728x90
๋ฐ˜์‘ํ˜•