반응형
https://vuejs.org/guide/introduction.html
화면출력 디렉티브
| Directive | Vue에서 HTML 태그에 특별한 동작을 하도록 지시하는 속성 템플릿 에서 v- 로 시작 |
||
| 문자열 출력 | v-html | <p v-html="htmlContent"></p> | html태그가 처리되어 출력 보완에는 취약 |
| v-text | <p v-text="message"></p> | 텍스트만 출력, {{}} 와 유사 하지만 부분적 변경이 안됨 |
|
| 참고 : {{}} = 머스타시 문법- 수염같다 = 보간문법 = Interpolation |
v-text는 해당 태그텍스트 전체를 교체하지만 일부만 변수처리가능 |
||
| v-pre | <p v-pre>{{ name }}</p> 출력 : <p>{{ name }}</p> |
이스케이프 뷰 컴파일러가 뷰 에플리케이션 코드 컴파일 안하고 문자 그대로 출력 1. 더블 중괄호 그대로 필요할 때 사용 2. 성능상 컴파일할 필요 없는 정적인 영역을 건너뛰게 하고 싶을 때 (최적화용) |
|
| v-slot | <template> <div class="card"> <header> <slot name="header">[기본 헤더]</slot> </header> <footer> <slot name="footer">[기본 푸터]</slot> </footer> </div> </template> ------------------------------------------------- <template> <CardBox> <!-- 이름 있는 슬롯 --> <template v-slot:header> <h3>📝 커스텀 헤더</h3> </template> <!-- 또 다른 이름 있는 슬롯 --> <template v-slot:footer> <small>ⓒ 2025 Vue Inc.</small> </template> </CardBox> </template> <script> import CardBox from './components/CardBox.vue' export default { components: { CardBox } } </script> |
자식에 컴포넌트에 name과 함께 지정하여 부모에서 값을 넣음 | |
| 조건 | v-show | <p v-show="isVisible">보이는 문장</p> | 조건 안맞을때 : display: none 가벼움(빠름) 조건이 자주바뀔때 |
| v-if | <p v-if="isLoggedIn">환영합니다</p> | 조건 안맞을 때 : <!--v-if--> 무거움(느림) 조건이 자주 변하지 않을때 |
|
| v-else-if, v-else |
<p v-if="score >= 90">A</p> <p v-else-if="score >= 80">B</p> <p v-else>C</p> |
조건이 안맞을때 <!--v-if--> <!--v-else-if--> |
|
| 바인딩 | v-bind | <img :src="imgUrl" v-bind:class="black"/> <input type="text" :value="name" @input="name = $event.target.value" /> |
HTML 태그 속성(attribute)에 동적으로 연결 1. v-bind:속성명 으로 사용 2. :속성명 으로 사용 {{}} 로 값을 넣을 수 없음 |
| <template> <div> <p>진행률: {{ progress }}%</p> <progress :value="progress" max="100"></progress> </div> </template> <script setup> import { ref } from 'vue' const progress = ref(30) </script> |
프로그래스 출력 | ||
| v-model 양방향 데이터 바인딩 (Two-way Binding) |
<template> <div> <!-- 이름 입력 --> <input v-model="name" placeholder="이름을 입력하세요" /> <p>입력한 이름: {{ name }}</p> <!-- 과일 선택 (드롭다운) --> <select v-model="selected"> <option value="">선택하세요</option> <option value="apple">사과</option> <option value="banana">바나나</option> </select> <p>선택한 과일: {{ selected }}</p> <!-- 체크박스 그룹 --> <p>좋아하는 과일을 모두 선택하세요:</p> <label><input type="checkbox" value="apple" v-model="fruits" /> 사과</label> <label><input type="checkbox" value="banana" v-model="fruits" /> 바나나</label> 선택한 과일들: {{ fruits }} <!-- 라디오 버튼 그룹 --> <p>한 가지 과일만 선택하세요:</p> <label><input type="radio" name="fruits2" value="apple" v-model="fruits2" /> 사과</label> <label><input type="radio" name="fruits2" value="banana" v-model="fruits2" /> 바나나</label> <p>선택한 과일: {{ fruits2 }}</p> <!-- 단일 체크박스 --> <label> <input type="checkbox" v-model="agree" /> 이용약관에 동의합니다 </label> <p>동의 여부: {{ agree ? '동의함' : '동의 안 함' }}</p> </div> </template> <script setup> import { ref } from 'vue' // 입력 상태 const name = ref('') const selected = ref('') // 체크박스 그룹 const fruits = ref([]) // 초기 선택 없음 // const fruits = ref(['banana']) // ← 초기 선택 바나나로 하려면 이 줄 사용 // 라디오그룹 const fruits2 = ref('') // 예: 초기값 'banana' 가능 // 단일 체크박스 const agree = ref(false) </script> |
양방향 데이터 바인딩 (view ↔ model) * 얕은복사/참조 주의 input , textarea, select 처리시 사용. 셋팅값 사용자 선택값 사용. 내부적 코드 <input v-model="msg" /> <input :value="msg" @input="msg = $event.target.value" /> 내부적으로 @change 이벤트를 사용 ref('') Composition API 방식 |
|
| IME (Input Method Editor) 에서 주의 - 한글이나 한자처럼 자판에 있는 글자보다 수가 더 많은 문자를 계산&조합하여 입력해주는 소프트웨어 <template> <div> <input v-model="str" placeholder="문자열을 입력하세요" /> <p>글자 수: {{ str.length }}</p> </div> </template> <script setup> import { ref } from 'vue' const str = ref('') </script> |
영어는 실시간으로 글자수 길이 사용가능 한글 글자수 출력 불가.(조합해서 작성하는글) 별도 input 이벤트로 function 으로 분리해서 처리할 것. |
||
| 부모-자식 양방향 바인딩시 기본수식어 안됨. 컴포넌트 내부에서 처리 |
하기 수식어 참조 |
| 랜더링 | v-once | <template> <div> <p v-once>v-once 적용: {{ msg}}</p> <p>일반 렌더링: {{ msg }}</p> <button @click="changeMsg "> 메시지 변경 </button> </div> </template> <script setup> import { ref } from 'vue'; const msg = ref('처음 메시지'); function changeMsg () { msg .value = '바뀐 메시지'; } </script> |
렌더링 최적화 : 최초 렌더링 이후 다시는 업데이트하지 마라 |
| v-memo | <template> <ul> <li v-for="item in items" :key="item.id" v-memo="[item.name]" > {{ item.name }} </li> </ul> <button @click="changeOther">다른 항목 변경</button> </template> <script setup> import { ref } from 'vue' const items = ref([ { id: 1, name: 'Vue' }, { id: 2, name: 'React' }, { id: 3, name: 'Svelte' }, ]) function changeOther() { items.value[0].name = 'Vue.js' // 첫 번째 항목만 바뀜 } </script> |
조건부로 다시 렌더링 Vue 3.2 이상 v-for 와 같이 써서 일부 값이 바뀔때 데이터 재로딩 하는 로직으로 사용 * 동일 태그에 사용할것 주의 |
|
| v-for | <ul> <li v-for="(fruit, index) in fruits" :key="i"> {{ index }} {{ fruit }} </li> </ul> data() { return { fruits: ['사과', '바나나', '포도'] } } |
v-for와 v-if를 같은 요소에 함께 쓰면 **우선순위는 v-for > v-if** 분리 사용 추천 |
이벤트 v-on:event |
v-on:click | <template> <div> <button v-on:@click="sayHello($evnet)">인사하기</button> <button @click="($event) =>sayHello($evnet)">인사하기</button> <h1>{{num}} 번<h1> </div> </template> <script> export default { data(){ return { num:0, }; }, methods: { sayHello(e) { alert("안녕하세요!"); console.log(e) this.num = this.num +1; } } } </script> |
1. 정식 문법 v-on:click="sayHello" 2. 축약형 @click="sayHello" 3. 그외 이벤트 @click 클릭 이벤트 @click="함수명" @dblclick 더블 클릭 @dblclick="함수명" @mouseenter 마우스 진입 @mouseenter="onHover" @keyup 키보드 키 누름 @keyup.enter="submit" @submit 폼 제출 <form @submit.prevent="onSubmit"> 4. 이벤트 객체 @click="sayHello($evnet)" @click="($event) =>sayHello($evnet)" 성능은 위에것이 좋음, 타입안정성은 아래것이 높음 5. 반응성(Reactivity) 데이터가 바뀌면 자동으로 화면이 업데이트 되는 시스템 cf) Vue 컴포넌트스크립트 (script) 내에서 data, methods 속성접근시this로 호출 |
| v-on:input | <textarea @input="memo = $event.target.value"></textarea> | 실시간 입력 @input | |
| v-on:change | <!-- 체크박스 그룹 --><input @change="id = $event.target.value" /> <select @change="selected = $event.target.value"> <option value="">선택하세요</option> <option value="apple">사과</option> <option value="banana">바나나</option> </select> |
입력중 포커스를 잃을때 실행 @change 파일 처리도 @change로 처리 |
|
| <template> <div> <input type="file" @change="handleFileChange" /> <div v-if="file"> <p>파일명: {{ file.name }}</p> <p>파일 크기: {{ (file.size / 1024).toFixed(2) }} KB</p> <p>파일 타입: {{ file.type }}</p> </div> </div> </template> <script setup> import { ref } from 'vue' const file = ref(null) function handleFileChange(event) { const selected = event.target.files[0] file.value = selected || null } </script> |
|||
| 매서드 vs 인라인 핸들러 |
매서드핸들러 | <button @click="handleClick">Click</button> methods: { handleClick(event) { console.log(event); } } * event 는 데이터로 넘겨줌 |
|
| 인라인핸들러 | js 코드 그대로 사용, 변수, 함수 호출시 this 필요없음 <input @change="id = $event.target.value" /> <button @click="sayHello('Vue')">Say Hello</button> <button @click="isActive ? doSomething() : doSomethingElse()">Click</button> <button @click="(event) => handleClick(event)">Use Arrow Function</button> |
| 이벤트 수식어 modifier |
디렉티브에 붙는 특수한 동작 제어자 @이벤트명.수식어1.수식어2="함수" 1. 수식어 .capture 캡처링 단계에서 실행 <div @click.capture="capture">...</div> 2. 동시실행 <button @click.prevent.stop="handleClick">전파X & 이동X</button> 3. prevent, stop 은 사용후 키확인 .prevent <button @click.prevent.ctrl="handleClick">...✔</button> .stop <button @click.stop.ctrl="handleClick">...✔</button> 참고 : v-model 의 수식어는 사용자가 만들어등록 |
||
| .prevent | <a href="#" @click.prevent="go">링크</a> |
기본 동작 막음 event.preventDefault(); 동일 ex) a , form 태그 |
|
| .self | <div @click.self="selfOnly">...</div> | 자기 자신에게만 실행 - 자식요소도 막음(캡쳐링도 막음) if (event.target === event.currentTarget) { selfOnly(); // 클릭된 요소가 바로 이 div일 때만 실행 } 동일 |
|
| .stop | <div @click.stop="stopClick">...</div> | 이벤트 전파 막음 event.stopPropagation(); 동일 - 자식요소는 확성화 |
|
| .passive | <div @scroll.passive="handleScroll">...</div> 스크롤 성능에 중요한 이벤트 wheel, touchmove <div @wheel.passive="handleWheel" /> <div @touchmove.passive="handleTouchMove" /> |
handleScroll 안에서 event.preventDefault() 안 쓸게 = 스크롤 법벅임 방지 element.addEventListener('scroll', handleScroll, { passive: true }) // 스크롤 버벅임방지 cf) wheel 마우스 휠 입력 touchmove 모바일 스크롤 최적화 |
|
| .once | <button @click.once="init">...</button> | 한 번만 실행 - 일회용 | |
| 키보드 수식어 시스템 수식어 |
<button @click.ctrl="ctrlClick"> 클릭 +ctrl키</button> <button @keydown.ctrl. shift.alt ="ctrlClick">Ctrl and shift and alt 키</button> <button @keydown.ctrl="onKey" @keydown. shift ="onKey" @keydown.alt="onKey" > Ctrl or shift or alt </button> <input @keydown.enter="submitForm" /> <div @keydown.left="moveLeft" @keydown.right="moveRight"></div> <div @keydown.esc="closeModal"></div> |
1. event.key 기반 2. event.code 로 키 확인가능 3. .은 and 조건 각각 선언시 or 조건. .ctrl Ctrl 키가 눌린 상태에서 @keydown.ctrl .shift Shift 키가 눌린 상태에서 @keydown.shift .alt Alt 키가 눌린 상태에서 @keydown.alt .meta ⌘ Command (Mac), ⊞ Win (Windows) .enter Enter 키 .tab Tab 키 .delete Delete 및 Backspace 키 .esc / .escape Escape 키 .space Spacebar (스페이스) .up, .down, .left, .right 방향키 .home, .end, .pageup, .pagedown 탐색 키 .insert Insert 키 |
|
| .exact | <button @click.ctrl.exact="handle">✔ 권장</button> | *(순서주의)키보드 키가 단독으로 눌렀을때 .exact 는 키확인후 사용 |
|
| v-model |
<template> <div> <h2>부모 컴포넌트</h2> <!-- v-model:message 사용 + 수식어처럼 `.capitalize` --> <MyInput v-model:message.capitalize="text" /> <p>입력된 값: {{ text }}</p> </div> </template> <script> import MyInput from './components/MyInput.vue' export default { components: { MyInput }, data() { return { text: '' } } } </script> ------------------------------------------------------------------- <template> <div> <input :value="modelValue" @input="handleInput" /> </div> </template> <script> export default { props: { modelValue: String, modelModifiers: { type: Object, default: () => ({}) } }, emits: ['update:modelValue'], methods: { handleInput(event) { let value = event.target.value if (this.modelModifiers.capitalize) { value = value.charAt(0).toUpperCase() + value.slice(1) } this.$emit('update:modelValue', value) } } } </script> |
v-model 부모 -자식 컴포넌트 사용 시 이벤트 수식어와 다르게(해당 수식어는 자동으로 있는 것이 맵핑 되는게 아니라)새로 작성해야함 |
|
'Web' 카테고리의 다른 글
| [핵심만 골라 배우는 Vue.js by 수코딩] 5. 라이프사이클 훅 (1) | 2025.08.01 |
|---|---|
| [핵심만 골라 배우는 Vue.js by 수코딩] 4. 반응형API(Reactivity APIs)- Options API vs Composition API (3) | 2025.08.01 |
| [핵심만 골라 배우는 Vue.js by 수코딩] 2. vue Scaffold(뼈대), SFC (4) | 2025.07.31 |
| [핵심만 골라 배우는 Vue.js by 수코딩] 1. VSCode, vue 생성하기 (1) | 2025.07.31 |
| [프론트엔드 날개달기 by짐코딩] DOM, 이벤트, js 함수, 웹팩, 외 (5) | 2025.07.30 |