[Vue] Script Setup

chaewonยท2024๋…„ 7์›” 30์ผ
0
post-thumbnail
post-custom-banner

๐Ÿ’ป < script setup >

<script setup>์€ Single-File-Component ๋‚ด์—์„œ Composition API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ syntactic-sugar(๋ฌธ๋ฒ•์  ์„คํƒ•) ์ž…๋‹ˆ๋‹ค. SFC์™€ CompositionAPI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ <script setup>์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค. ์™œ๋ƒ๋ฉด ์ผ๋ฐ˜ <script> ๊ตฌ๋ฌธ๋ณด๋‹ค ๋งŽ์€ ์žฅ์ ์„ ์ œ๊ณตํ•ด์ค€๋‹ค.

  • ๊ฐ„๊ฒฐํ•œ ๋ฌธ๋ฒ•์œผ๋กœ ์‚ฌ์šฉ๊ตฌ(boilerplate)๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ props์™€ emits ์„ ์–ธ ๊ฐ€๋Šฅ
  • ๋Ÿฐํƒ€์ž„ ์„ฑ๋Šฅ์˜ ํ–ฅ์ƒ(ํ…œํ”Œ๋ฆฟ์ด setup ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฐ™์€ ์Šค์ฝ”ํ”„(scope)์— ์žˆ๋Š” render ํ•จ์ˆ˜๋กœ ์ปดํŒŒ์ผ๋˜๋ฏ€๋กœ ํ”„๋ก์‹œ๊ฐ€ ํ•„์š”์—†์Œ)
  • ๋” ๋›ฐ์–ด๋‚œ IDE ํƒ€์ž… ์ถ”๋ก  ์„ฑ๋Šฅ (language ์„œ๋ฒ„๊ฐ€ ์ฝ”๋“œ๋กœ๋ถ€ํ„ฐ ํƒ€์ž…์„ ์ถ”๋ก ํ•ด๋‚ด๋Š”๋ฐ ๋น„์šฉ์ด ๋œ ๋“ ๋‹ค)

๐Ÿ“Œ syntactic-sugar๋Š” ๊ธฐ๋Šฅ์€ ๊ทธ๋Œ€๋กœ์ธ๋ฐ ์ฝ๋Š” ์‚ฌ๋žŒ์„ ์œ„ํ•ด ์ง๊ด€์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

<script setup>
  import { ref } from "vue";
  
  // script์— setup์„ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค.
  console.log('Hi!');
  
  //๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ ๋˜ํ•œ ์ž˜ ์ž‘๋™ํ•œ๋‹ค.
  const message = ref("");
  
  //๋”ฐ๋กœ return์„ ํ•˜์ง€ ์•Š๋”๋ผ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. (์ƒ์šฉ๊ตฌ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค)
  const msg = 'hi';
</script>


<script>
  //์œ„์˜ setup์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ปดํŒŒ์ผ๋œ๋‹ค.
  export default {
  	import { ref } from "vue";
  
  	setup() {
  		console.log('Hi!');
  				
  		const message = ref("");
  
  		const msg = 'hi';
  		return{ msg, message };
  	},
  }
</script>

1-1 defineProps() & defineEmits()

defineProps()์™€ defineEmits() API๋ฅผ <script setup>๋‚ด์— ์„ ์–ธํ•˜์—ฌ props์™€ emits์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<script setup>
  const props = defineProps({
  	foo: String
  })
  
  const emit = defineEmits(['change', 'delete'])
</script>
  • defineProps์™€ defineEmits๋Š” <script setup> ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ๋งคํฌ๋กœ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— importํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉด <script setup>์ด ์ฒ˜๋ฆฌ๋  ๋•Œ ์ปดํŒŒ์ผ ๋œ๋‹ค.
  • defineProps๋Š” props์˜ต์…˜๊ณผ ๋™์ผํ•œ ๊ฐ’์„ ํ—ˆ์šฉํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  defineEmits๋Š” emits ์˜ต์…˜๊ณผ ๋™์ผํ•œ ๊ฐ’์„ ํ—ˆ์šฉํ•œ๋‹ค.
  • defineProps์™€ defineEmits๋Š” ์ „๋‹ฌ๋œ ์˜ต์…˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํƒ€์ž… ์ถ”๋ก ์„ ์ œ๊ณตํ•œ๋‹ค.
  • defineProps์™€ defineEmits์— ์ „๋‹ฌ๋œ ์˜ต์…˜์€ setup()์—์„œ ๋ชจ๋“ˆ ์˜์—ญ(module scope)์œผ๋กœ ํ˜ธ์ŠคํŒ…๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์˜ต์…˜์€ setup() ์˜์—ญ์— ์„ ์–ธ๋œ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค. ๋งŒ์•ฝ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ํ•˜์ง€๋งŒ import๋œ ์˜ต์…˜์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์™œ๋ƒ๋ฉด import๋„ ๋ชจ๋“ˆ ์˜์—ญ์œผ๋กœ ํ˜ธ์ŠคํŠธ๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

1-2 defineExpose()

<script setup>์„ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Template Refs๋‚˜ $parent์™€ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ๊ฐ„ ํ†ต์‹ ์ด ๋‹ซํ˜€ ์žˆ๋‹ค. <script setup>์„ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋…ธ์ถœํ•˜๋ ค๋ฉด defineExpose()์ปดํŒŒ์ผ๋Ÿฌ ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<script setup>
  import { ref } from 'vue';
  
  const a = 1
  const b = ref(2)
  
  defineExpose({
  	a,
  	b
  })
</script>

expose๋Š” ์ผ๋ฐ˜ < script >์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<script>
  export default{
  	setup(props, context){
  	//Expose public properties (Function)
  	console.log(context.expose)
  	}
  }
</script>

1-3 useSlots() & useAttrs()

slots๊ณผ attrs๋Š” <template> ๋‚ด๋ถ€์—์„œ $slots๊ณผ $attrs๋กœ ์ง์ ‘ ์ ‘๊ทผํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ <script setup> ๋‚ด๋ถ€์—์„œ slots๊ณผ attrs๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ๊ฐ useSlots(), useAttrs() helper ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<script setup>
  import { useSlots, useAttrs } from 'vue'
  
  const slots = useSlots()
  const attrs = useAttrs() // fallthrough ์†์„ฑ ์ ‘๊ทผ
</script>

slots๊ณผ attrs๋Š” ์ผ๋ฐ˜ <script>์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<script>
  export default{
  	setup(props, context){
  		//Attributes (Non-reactive object, equivalent to $attrs)
  		console.log(context.attrs)
  
  		//Slots (Non-reactive object, equivalent to $slots)
  		console.log(context.slots)
  	}
  }
</script>
  

1-4 < script >์™€ < script setup>ํ•จ๊ป˜ ์‚ฌ์šฉ

<script setup>์€ nomal <script>์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— nomal <script>๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์˜ˆ๋ฅผ ๋“ค์–ด <script setup>์—์„œ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋Š” inheritAttrs์˜ต์…˜์ด๋‚˜ Plugin์„ ํ†ตํ•ด ํ™œ์„ฑํ™”๋œ Custom ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ• ๋•Œ nomal <script>๋ฅผ ํ•จ๊ป˜ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
  • named export๋ฅผ ์„ ์–ธ ํ–ˆ์„ ๋•Œ(์˜ˆ: export const data)
  • ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๋กœ์ง์ด ์žˆ์„ ๋•Œ
<script>
  //์ผ๋ฐ˜ ์Šคํฌ๋ฆฝํŠธ, ๋ชจ๋“ˆ ๋ฒ”์œ„์—์„œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰
  runSideEffectOnce()
  
  //์˜ต์…˜ ์„ ์–ธ
  export default {
  	inheritAttrs : false,
  	customOptions: {}
  }
</script>

<script setup>
  //๊ฐ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์‹œ setup() ๋ฒ”์œ„์—์„œ ์‹คํ–‰
</script>

1-5 Top-level await

<script setup>๋‚ด์˜ Top-level์—์„œ await์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ๋Š” async setup()์ด๋ ‡๊ฒŒ ์ปดํŒŒ์ผ ๋œ๋‹ค.

<script setup>
  const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>
profile
์˜๋ฌธ์€ '์‚ถ์˜ ์ˆ˜์ค€'์„ ๊ฒฐ์ •ํ•˜๊ณ , ์งˆ๋ฌธ์€ '์‚ถ ์ž์ฒด'๋ฅผ ๋ฐ”๊พผ๋‹ค.
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€