2.3.9. <slot> 태그
- 컴포넌트 template 에 slot 태그를 사용시, slot 태그를 부모가 원하는 내용으로 교체하여 채워넣을 수 있음.
- <컴포넌트명></컴포넌트명> 사이에 원하는 html 태그를 입력하면, slot 태그를 대체하게 됨
- 하나의 컴포넌트에 공통기능만 명시하고 여러군데서 커스터마이징 하여 사용할 수 있음
Vue.component('test',
{
...
template:'<div> <h2>나는 자식 컴포넌트의 제목입니다</h2> <slot> 제공된 컨텐츠가 없는 경우에만 보실 수 있습니다. </slot> </div>'
}
)
html에서
<test><p>안녕하세요</p><p>안녕하세요1</p></test>
=> <slot> 태그를 <p>안녕하세요.... 가 대체하게 됨.
=> 최종적으로, <div> <h2>나는 자식 컴포넌트의 제목입니다</h2> <p>안녕하세요</p><p>안녕하세요1</p></div>
=> <test> 태그 사이에 아무것도 없을경우 slot의 내용이 보임
2.3.9.1. <slot> 태그 name 속성
- 컴포넌트 template에 slot 태그가 여러개 있을 경우.
- 부모 html태그가 대체될 slot 위치를 지정.
- 컴포넌트 template에서 <slot name="이름"> 으로 선언
- 부모 html에서 <태그 slot="이름" ... 으로 사용
Vue.compnent('test',
{
template='
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>'
</div>
}
부모 html에서,
<test>
<p slot="header">헤더</p>
<p>안녕하세요</p>
<p>안녕하세요1</p>
<p slot="footer">가나다라</p>
</test>
결과
<div class="container">
<header>
<p>헤더</p>
</header>
<main>
<p>안녕하세요</p>
<p>안녕하세요1</p>
</main>
<footer>
<p>가나다라</p>
</footer>
</div>
2.3.9.2. <slot> 태그 scope 속성
- 컴포넌트 template slot태그에 데이터를 바인딩하여 사용시, 부모 html에서 자식 데이터를 접근하기 위해 사용함
- 부모 html에서 <template> 태그를 사용했어야 하나, 최신버전에서는 이에 상관없이 기본 태그에서도 사용 가능
- <태그명 slot-scope="원하는 이름"....> {{원하는이름.컴포넌트slot 속성명.맴버변수명 }} ... 식으로 사용 가능
- 예
Vue.component('test',
{
template:'<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<slot v-bind:todoItem="todo">
{{ todoItem.text }}
</slot>
</li>
</ul>'
data: function()
{
return todos: [ { id: 1, text: "일번"}, { id: 2, name: "이번"}, { id: 3, name: "삼번"} ]
}
})
new Vue({
el:'#instanceID',
data : { ListItem:[........] }
})
html에서
<div id="instanceID">
<test v-bind="ListItem">
<template slot-scope="Items(원하는이름)"> //template 대신 다른 일반태그 사용가능
<span v-if="Items(원하는이름).todoItem.isComplete">✓</span>
{{ Items(원하는이름).todoItem.text }}
</template>
</test>
</div>
2.3.9.2.1. 디스트럭쳐링
- html에서 slot-scope 사용을 좀 더 편리하게 사용하기 위한 방법
- 기존 : 원하는이름.컴포넌트slot 속성명.맴버변수
- 적용 : slot-scope={컴포넌트slot 속성명} 이후, 컴포넌트slot 속성명.맴버변수 로 사용
<todo-list>
<template slot-scope="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
2.3.10. 동적 컴포넌트 (내부 컴포넌트)
- <component> 태그 및 v-bind:is="" 를 이용하여, 렌더링할 컴포넌트를 동적으로 바인드
//html 코드
<component v-bind:is="currentView">
<!-- vm.currentView가 변경되면 컴포넌트가 변경됩니다! -->
</component>
//모델
var Home = {
template: '<p>Welcome home!</p>'
}
//vue 인스턴스
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})
================= 내부 컴포넌트 사용
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { '<p>Welcome home!</p>' },
posts: { '<p>Welcome post!</p>' },
archive: { '<p>Welcome archive!</p>' }
}
})
2.3.10.1. keep-alive
- <component> 태그 및 v-bind:is="" 를 이용하여 동적으로 생성한 컴포넌트를 메모리에 유지
- <keep-alive> 태그 안에 <component> 태그를 사용
2.3.11. 비동기 컴포넌트 (이해가...)
- 여러 방법이 있음....
2.3.11.1. 컴포넌트 생성시, 생성자에 function 사용 (factory 함수)
- 함수 인자값으로 resolve, reject 가 있음.
- Vue.component('컴포넌트명', function(resolve, reject) { ... })
2.3.11.1.1. resolve 콜백
- 콜백으로, 컴포넌트 가져오기 성공시 컴포넌트를 렌더링 하기 위함
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
resolve({
template: '<div>I am async!</div>'
})
},1000)
})
//settimeout은 javascript -> windows 에서 제공하는 함수https://www.w3schools.com/jsref/met_win_settimeout.asp 참조
2.3.11.1.2. reject 콜백
- 콜백으로, 컴포넌트 가져오기 실패시 컴포넌트를 렌더링 하기 위함
Vue.component('async-example', function (resolve, reject) {
reject({
template: '<div>fail</div>'
})
})
2.3.11.2. webpack과 함께 사용
- webpack과 사용시, 각 컴포넌트 들은 별도의 파일로 저장하여 존재하는것을 추천.
- import 하여 사용
Vue.component('async-webpack-example', function (resolve) {
// 이 특별한 require 구문은 Webpack이 Ajax 요청을 통해
// 로드되는 번들로 작성된 코드를 자동으로 분리하도록 지시합니다.
require(['./my-async-component'], resolve)
})
2.3.11.3. webpack2 + ES2015구문
- webpack과 사용시, 각 컴포넌트 들은 별도의 파일로 저장하여 존재하는것을 추천.
- import 하여 사용
Vue.component(
'async-webpack-example',
// `import` 함수는 `Promise`를 반환합니다.
() => import('./my-async-component')
)
//promise는 자바스크립트의 비동기에서 사용되는 객체
2.3.11.4. 고급 비동기 컴포넌트
- const 를 사용
- component: import('컴포넌트 위치..??'), 또는 new promise ((resolve, reject) => { ... })
- 로드하는 컴포넌트. 반드시 promise (자바스크립트 비동기에서 사용되는 객체) 이어야 함
- import : https://developers.google.com/web/updates/2017/11/dynamic-import
- import를 사용하려면, 각 컴포넌트들이 별도의 파일로 저장되어야 함
- loading: const 로 선언한 함수명??
- 비동기 컴포넌트가 로드되는동안 사용
- error: const 로 선언한 함수명??
- 실패했을경우 사용
- delay:숫자
- 로딩 함수?? 를 보여주기전 지연하는 정도. ms
- timeout:숫자
- 이 시간이 초과되면 error:에서 설정한 함수?? 실행됨
html 부분
<div id="app">
<async-component></async-component>
</div>
<template id="number-box">
<h1>123123</h1>
</template>
<template id="loading-component">
<h1>Loading...</h1>
</template>
<template id="error-component">
<h1>Something Wrong!!</h1>
</template>
스크립트 부분
const NumberBoxComponent = {
name: 'number-box',
template: '#number-box',
}
const LoadingComponent = {
name: 'loading-component',
template: '#loading-component'
}
const ErrorComponent = {
name: 'error-component',
template: '#error-component'
}
const AsyncComponent = () => ({
component: new Promise((resolve, reject) => {
setTimeout(() => {
resolve(NumberBoxComponent)
}, 1000)
}),
loading: LoadingComponent,
error: ErrorComponent,
delay: 1
})
new Vue({
el: '#app',
components: {
'async-component': AsyncComponent
}
})
})
2.3.12. 재귀 컴포넌트
- 컴포넌트 등록시 설정한 name을 통해 template 에서 재귀 호출을 할 수 있음.
- 전역 등록을 할 경우, Vue.component('이름입니다', { ... }) 첫번째 인자가 name임.
- 지역등록일 경우, name:'명칭' 옵션을 이용하여 이름 등록
- 무한루프 가능성이 있으므로, v-if를 통해 제어 해주어야 함
Vue.component('unique-name-of-my-component', {
...
template:'<unique-name-of-my-component></unique-name-of-my-component>....'
})
// 무한루프가 발생함. template를 아래와 같이 변경
// template: '<unique-name-of-my-component v-if="변수명 < 숫자" v-bind:변수명="변수명 + 1"></unique-name-of-my-component>....'
2.4. 이벤트 핸들링
- v-on 디렉티브 이용 (2.2.2.11. 참조)
2.4.1. 변수값 직접 변경
- v-on:click="counter += 1" 처럼 직접 변수값을 변경가능
2.4.2. 함수 호출
- v-on:click="함수명" 으로 함수 호출도 가능
2.4.3. 인자값이 있는 함수 호출 (인라인 메소드)
- 함수명이 test(message) 인 함수를 호출
- v-on:click="test('hello')" 으로 함수 호출
2.4.4. 원본 변수(?) 전달
- 함수명이 warn(message,event) 인 경우
- v-on:click="warn('hello',$event)" 으로 호출
2.4.5. 이벤트 수식어
- 2.4.4. 에서 클릭시 $event를 전달할 경우, 함수 내부에서 event에 속한 메서드 호출 등이 가능하다.
- 그러나, 해당 이벤트의 특정 상황에서만 동작을 원할 경우, 수식어를 사용할 수 있다.
- v-on:이벤트명.수식어="" 으로 사용
- 수식어는 좌측->우측으로 우선순위가 있으므로 순서를 따라야 함
- click.prevent.self : 모든 클릭 차단, clck.self.prevent : 이 엘리먼트의 클릭만 차단
- 예
<!-- 클릭 이벤트 전파가 중단됩니다 -->
<a v-on:click.stop="doThis"></a>
<!-- 제출 이벤트가 페이지를 다시 로드 하지 않습니다 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 수식어는 체이닝 가능합니다 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 단순히 수식어만 사용할 수 있습니다 -->
<form v-on:submit.prevent></form>
<!-- 이벤트 리스너를 추가할 때 캡처모드를 사용합니다 -->
<!-- 즉, 내부 엘리먼트를 대상으로 하는 이벤트가 해당 엘리먼트에서 처리되기 전에 여기서 처리합니다. -->
<div v-on:click.capture="doThis">...</div>
<!-- event.target이 엘리먼트 자체인 경우에만 트리거를 처리합니다 -->
<!-- 자식 엘리먼트에서는 안됩니다 -->
<div v-on:click.self="doThat">...</div>
// 한번만 트리거 됨
<a v-on:click.once="doThis"></a>
등등 존재하기에 추후 구글링 필요.
2.4.6. 키 수식어
- 키보드 이벤트 수신시, 키 코드 확인 필요할때 사용
- v-on:keyup.enter ="콜백함수명" => 엔터키 클릭시 동작
- 키 수식어 전체 목록
- .enter
- .tab
- .delete (delete 키와 backspace 모두 캡쳐됨)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta
2.4.6.1. 시스템 키
- ctrl, alt 등 시스템 키가 눌렸을 경우에 동작하고 싶을때 조합하여 사용
- click.ctrl : 컨트롤키가 눌린상태에서 클릭했을 경우.
- keyup.alt.enter : 알트키가 눌린상태에서 엔터키 눌렀을경우
- .ctrl, .alt, .shift, .meta (맥os의 커맨드키)
2.4.6.2. exact 수식어
- 정확한 조합을 위한 수식어
- 예
<!-- Alt 또는 Shift와 함께 눌린 경우에도 실행됩니다. -->
<button @click.ctrl="onClick">A</button>
<!-- Ctrl 키만 눌려있을 때만 실행됩니다. -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 아래 코드는 시스템 키가 눌리지 않은 상태인 경우에만 작동합니다. -->
<button @click.exact="onClick">A</button>
2.4.6.3. 마우스 버튼
- .left, .right, .middle
2.4.6.4. 커스텀 수식어
- 원하는 문자열과 매칭할 키코드를 연결하여 커스텀 수식어를 사용 할 수 있음
- 참조 : https://kr.vuejs.org/v2/api/#keyCodes
Vue.config.keyCodes = {
v: 86,
f1: 112,
// camelCase는 작동하지 않습니다.
mediaPlayPause: 179,
// 쌍따옴표로 감싸진 kebab-case를 사용하세요
"media-play-pause" : 179,
up: [38, 87]
//원하는수식어명:정확한 키코드번호
// 키코드 여러개를 연결할 경우 [] 사용
}
2.5. 폼 입력 바인딩
- v-model 사용
- 폼 입력과 양방향으로 바인딩
- v-model은 폼의 기본값 (value, checked, selected 같은)을 무시하고 Vue 인스턴스의 값을 원본으로 사용함. 따라서 초기화는 Vue 인스턴스에서 해야 함.
- 폼 입력과 양방향으로 바인딩
- <태그명 v-model="연동변수명" ...
2.5.1. input 태그
- input은 닫는 태그가 없음
- 예
<input v-model="message" placeholder="여기를 수정해보세요">
<p>메시지: {{ message }}</p>
2.5.2. textarea
- 다중 열을 가지는 텍스트 입력
- 예
<span>여러 줄을 가지는 메시지:</span>
<p style="white-space: pre-line">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="여러줄을 입력해보세요"></textarea>
2.5.3. 체크박스
- 여러개의 체크박스는 같은 배열을 바인딩 할 수 있음
- 하나의 체크박스는 bool 값과 연동됨
- 예
<div id='example-3'>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>체크한 이름: {{ checkedNames }}</span>
</div>
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
// label 의 for 어트리뷰트에 폼의 id를 넣어주면, label과 폼이 연결됨
// 이 경우, 체크했을경우 해당 연결된 라벨이 보여짐
// input의 value가 checkdNames 배열의 값이며,
// 화면에는 label에서 설정한 문자열이 보여짐 (mike....)
2.5.4. 라디오 버튼
- 선택한 항목의 value 값이 설정됨
- 예
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>선택: {{ picked }}</span>
// picked 변수에 input value인 One, Two 가 배정됨. 선택된 항목의 값이 배정됨
2.5.5. 컴보박스 (html에서는 select 라고 부름)
- option 태그에 설정된 값이 변수에 바인딩됨.
- 예
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>선택함: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: ''
}
})
// disabled 를 통해 선택이 되지 않게 함.
// value 속성을 사용치 않는경우, 태그 사이의 값이 (A or B or C) value가 됨
// selected는 기본선택이나, v-model을 쓰는경우 무시함
2.5.6. 리스트박스 (html에서는 다중 select 라고 부름)
- option 태그에 설정된 값이 변수에 바인딩됨
- 쉬프트를 누른상태에서 다중선택 됨
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
2.5.6.1. v-for를 이용한 동적 리스트 박스
- 예
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
// v-for를 이용해 동적으로 option태그를 생성.
2.5.7. 오브젝트 바인딩
- 위의 방법으로 바인딩시, 문자열 혹은 bool 값이 바인딩 됨.
- 경우에 따라선 맴버변수 등 오브젝트가 바인딩 되어야 할 때가 있음.
- 이를위해 value 에 v-bind를 사용하여 Vue 인스턴스의 맴버변수를 지정할 수 있음
- v-model 에 v-bind에서 지정한 오브젝트가 바인딩 되게 됨.
2.5.7.1. 라디오 버튼
- 예
<input type="radio" v-model="pick" v-bind:value="a">
체크시, vm(Vue Instance).pick 에 vm.a(vue instance의 a변수) 가 담긴다.
2.5.7.2. List, 컴보박스 (Select 태그)
- 예
<select v-model="selected">
<!-- inline object literal -->
<option v-bind:value="{ number: 123 }">123</option>
</select>
선택시, vm.selected 를 접근하면, object가 담겨있음.
이 경우 vm.selected.number 에 123이 들어가게 됨.
즉, selected의 맴버변수에 값을 할당한것임.
2.5.8. 수식어
- v-model.수식어 로 사용
2.5.8.1. .lazy
- change 이벤트 이후에 동기화 됨.
2.5.8.2. .number
- 입력값을 숫자로 변환
- input 폼에서 사용하며, type를 number로 지정해도 문자열 입력이므로, 이 옵션을 사용해야 숫자가 됨
2.5.8.3. .trim
- 입력 문자열에 trim 적용
2.6. 사용자 정의 이벤트
- 참조 : https://kr.vuejs.org/v2/guide/components.html#v-on%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A7%80%EC%A0%95-%EC%9D%B4%EB%B2%A4%ED%8A%B8
- html 태그의 속성에서 v-on 을 사용하여 특정이벤트 발생시 수행할 작업을 지정할 수 있음
- html에서 사용자 생성 이벤트 또한, v-on을 통해 감지 할 수 있음
- 단, 사용자 이벤트는 $on으로 감지할 수 없음
<button-counter v-on:increment="incrementTotal"></button-counter>
// button-counter 컴포넌트 템플릿 버튼 클릭시, incrementCounter 함수 호출 -> emit을 통한 이벤트 발생
// -> 위의 html에서 작성한 button-counter에서 v-on으로 사용자 정의 이벤트인 increment를 감지
Vue.component('button-counter', {
template: '<button v-on:click="incrementCounter">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
incrementCounter: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
2.6.1. ref
- html 태그를 코드에서 접근하여 사용하기 위해 reference 하는것.
- html 태그에서 ref 속성을 사용
- <태그명 ref="원하는 문자열">
- 코드에서 $refs.원하는문자열 로 접근하여 사용
<button ref="myButton" @click="clickedButton">Click Me!</button>
this.$refs.myButton.innerText = this.message;
2.6.2. on('이벤트명',콜백함수)
- 이벤트를 수신
vm.$on('test', function (msg) {
console.log(msg)
})
2.6.3. emit('이벤트명',인자값1,......)
- 이벤트 발생
this.$emit('이벤트명', 'hello')
'FrontEnd' 카테고리의 다른 글
부트스트랩 (0) | 2022.03.25 |
---|---|
vue js 내용정리 (2.7. 트랜지션 ~) (0) | 2022.03.25 |
vue js 내용정리 (1. 설치 ~ 2.3.8. 컴포넌트 - 이벤트 발생시 사용자 정의함수 호출) (0) | 2022.03.25 |
FrontEnd 개발 관련 내용정리 (0) | 2022.03.25 |
HTTPS 상에서 Front-end 페이지 테스트 (0) | 2022.03.24 |