12. keyboard events and modifiers

์ฃผ์ œ

์ด์ „ ๊ฐ•์˜์—์„œ Vue์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ฐ•์˜์—์„œ๋Š” ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ๋‹ค๋ฃน๋‹ˆ๋‹ค. Vue๋Š” ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ ์ง€์›์— ์žˆ์–ด ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ํŠน์ • ํ‚ค ๋˜๋Š” ํ‚ค ์„ธํŠธ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ค‘๊ฐ„ ์ด๋ฆ„์„ ์œ„ํ•œ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ƒํ™ฉ์„ ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์— 'Middle Name'์ด๋ผ๋Š” ์ƒˆ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ , ์ดˆ๊ธฐ๊ฐ’์„ ๋นˆ ๋ฌธ์ž์—ด๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด์–ด์„œ ์ค‘๊ฐ„ ์ด๋ฆ„์„ ํฌํ•จํ•˜๋„๋ก 'full name' ํ•จ์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ ๋‚ด์—์„œ ์ฒซ ๋ฒˆ์งธ์™€ ๋งˆ์ง€๋ง‰ ์ด๋ฆ„ ํ•„๋“œ ์‚ฌ์ด์— ์ƒˆ ์ž…๋ ฅ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ž…๋ ฅ ์‹œ๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ์˜ ์—”ํ„ฐ ํ‚ค๋ฅผ ๋ˆ„๋ฅผ ๋•Œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. 'keyup' ์ด๋ฒคํŠธ๋ฅผ ๋ฆฌ์Šค๋‹ํ•˜๊ณ  'updateMiddleName' ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

'keyup' ์ด๋ฒคํŠธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ฅผ ๋ˆ„๋ฅด๊ณ  ๋†“์„ ๋•Œ๋งˆ๋‹ค ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ํŠน์ • ํ‚ค๋ฅผ ์ œํ•œํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์—”ํ„ฐ ํ‚ค๋งŒ์„ ๊ฐ์ง€ํ•˜๋„๋ก ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ‚ค๋ณด๋“œ ์ˆ˜์ •์ž๋Š” ์ด๋ฒคํŠธ ์ˆ˜์ •์ž์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ, ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ‚ค๋ณด๋“œ ์ˆ˜์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ํ‚ค๋ฅผ ๋ฆฌ์Šค๋‹ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ผ๋ถ€ ํ‚ค์— ๋Œ€ํ•œ ๋ณ„์นญ๋„ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—”ํ„ฐ ํ‚ค์— ๋Œ€ํ•œ ๋ณ„์นญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์—์„œ๋งŒ 'decrement' ํ•จ์ˆ˜๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ์˜ˆ๋ฅผ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” 'control'์ด๋ผ๋Š” ์‹œ์Šคํ…œ ์ˆ˜์ •์ž๋ฅผ ํด๋ฆญ ์ด๋ฒคํŠธ์— ์ ์šฉํ•จ์œผ๋กœ์จ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ…Œ์ŠคํŠธํ•ด๋ณด๋ฉด, ์ปจํŠธ๋กค ํ‚ค๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์—์„œ๋งŒ 'decrement' ๋ฒ„ํŠผ์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์š”์•ฝํ•˜์ž๋ฉด, Vue์—์„œ๋Š” ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ์—๋„ ์ˆ˜์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ๋” ๊น”๋”ํ•˜๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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>Middle Name</label>
    <input type="text" @keyup.enter="updateMiddleName">

    <br />
    <br />

    <label>Last Name</label>
    <input type="text" :value="lastName" @input.prevent="updateLastName('Last name event triggered!', $event)">

    <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>