9. listening to events

์ฃผ์ œ

์ด ๊ฐ•์˜์—์„œ๋Š” Vue.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ(์˜ˆ: ํด๋ฆญ, ํ‚ค ์ž…๋ ฅ, ํ˜ธ๋ฒ„ ๋“ฑ)๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ด์— ๋Œ€์‘ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ฐฐ์›๋‹ˆ๋‹ค. Vue.js์—์„œ๋Š” ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋ฆฌ์Šค๋‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € "Age"๋ผ๋Š” ์ƒˆ ๋ฐ์ดํ„ฐ ์†์„ฑ์„ ๋งŒ๋“ค๊ณ , ์ด ๊ฐ’์„ ํ…œํ”Œ๋ฆฟ ์•ˆ์—์„œ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค ๋‚˜์ด๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ฐ์†Œํ•˜๋Š” ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด v-on ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ๋‚˜์ด ์†์„ฑ์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, v-model ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ํ•„๋“œ์™€ ๋ฐ์ดํ„ฐ ์†์„ฑ ๊ฐ„์˜ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋” ๋งŽ์€ ์ œ์–ด๋ฅผ ์›ํ•  ๊ฒฝ์šฐ v-model ๋Œ€์‹  v-bind๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ํ•„๋“œ์˜ ๊ฐ’์„ ์ˆ˜๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ, Vue.js๊ฐ€ ์ดˆ๊ธฐ์— ์„ค์ •ํ•œ ๊ฐ’๋งŒ์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹ , ์ž…๋ ฅ ํ•„๋“œ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์†์„ฑ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ, Vue.js์—์„œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋‹๊ณผ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ v-model ๋””๋ ‰ํ‹ฐ๋ธŒ์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ถ”๊ฐ€์ ์ธ ์ œ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. v-model์€ ํŽธ์˜๋ฅผ ์œ„ํ•œ ๊ตฌ๋ฌธ์  ์„คํƒ•(syntactic sugar)์œผ๋กœ ์„ค๋ช…๋˜๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” ํ•„์š”์— ๋”ฐ๋ผ v-model ๋˜๋Š” ์ˆ˜๋™ ๋ฐ”์ธ๋”ฉ๊ณผ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋‹ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ v-model ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๋ฉฐ, ์ด๋Š” ์ฝ”๋“œ ์ž‘์„ฑ์„ ์ค„์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <link rel="stylesheet" href="main.css">
</head>
<body>
<div id="app" v-cloak>
    <p>{{  fullName() }}</p>
    <p><a :href="url" target="_blank">Google</a></p>
    <p>{{ raw_url }}</p>
    <p v-html="raw_url"></p>
    <p>{{ age }}</p>
    <hr />

    <label>First Name</label>
    <input type="text" v-model="firstName">

    <br />
    <br />

    <label>Last Name</label>
    <input type="text" :value="lastName" @input="updateLastName">

    <br />
    <br />

    <button type="button" @click="increment">Increment</button>
    <button type="button" @click="age--">Decrement</button>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.6/vue.global.prod.min.js"></script>
<script src="app.js"></script>
</body>
</html>