참조 사이트 : https://kr.vuejs.org/v2/guide/installation.html
https://joshua1988.github.io/web-development/vuejs/vuejs-tutorial-for-beginner/
1. 설치
1.1. 호환성 정보
- IE8 이하버전 지원불가
- ECMAScript 5 지원 브라우저 사용가능
- https://caniuse.com/#feat=es5
1.2. 설치 - NPM 부터는 무슨말인지 이해가....
- 브라우저에 Vue Devtools 설치
- 참조사이트에서 다운로드 받은 vue.js를 <script> 태그를 이용하여 추가
- 개발용, 배포용이 있음
- vue는 전역 변수로 등록됨
- 스크립트 태그에 https://unpkg.com/vue 이나 https://unpkg.com/vue/를 입력하여 자동으로 다운로드 및 적용
- 단, 최신버전이 아닐 수 있음
* 스크립트 태그는 body의 최 하단부에 선언해야 상단부 html태그에서 사용 가능
- 예 :
<div id="app">
{{ message }}
</div>
<script src="https://unpkg.com/vue@2.3.3"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
// html에 정의하여 vue 인스턴스를 하나 생성하여 만든 간단한 vue app
1.3. Vue Devtools(크롬) 사용법
- 마우스 우클릭 -> 확장프로그램 관리 -> 하단부 파일 url에 대한 엑세스 허용 켬
- vue가 포함한 html 페이지 -> f12 -> 상단 element, console .... 에서 >> 클릭 -> vue 선택
- 클릭을 통한 값 변경 가능
- 하단부 콘솔을 통해서도 접근 및 값 변경 가능
- $vm0.$.........
2. Vue.js
- MVVM 패턴 중 ViewModel 에 해당
- 데이터 바인딩 제공
- html이 동적으로 동작함
- 기존에는 html 태그 내용이 로딩된 후에는 변동되지 않음. 새로고침 해야함
- 바인딩을 통해 html을 작성할 경우, 변수명을 호출하므로, 변수값이 동적으로 변한다면, 페이지 로딩을 다시하지 않아도 동적으로 동작함
- 예 : <p>hello</p> => hello만 보여짐
<p>{{message}}</p> => message 변수값이 변경될 때마다 동적으로 보여짐
2.1. Vue Instance 생성
- var vm = new Vue( { 옵션 } )
- 생성 후 html 태그와 연결하면, 맴버변수를 {{}} 를 이용하여 바로 쓸 수 있다. (vm.변수명 이 아님)
- 하나의 인스턴스는 하나의 태그와 연결되야 한다.
2.1.1. 옵션
- $를 사용하여 옵션에 바로 접근 가능
- vm.$data.xxx 이런식으로 접근 가능
- vm.xxx 와도 같음
- 참조 : https://kadamon.tistory.com/13
2.1.1.1. data
- 맴버변수 선언 및 초기값 할당
- data {} 안에 선언한 맴버변수들을 html에서도 사용가능
- {{ 맴버변수명 }} 으로 사용가능
- (중요) Vue 생성시 data에서 맴버변수:값을 바로 설정해도 되나 이렇게 하지 않는것이 좋다
- 인스턴스는 html 태그와 1:1 매칭이기 때문에, 공통으로 사용하는 맴버변수값을 2군데 이상 html 태그에서 사용시
값의 연동이 되지 않는다.
- 올바른 사용법
<script>
//mvvm의 모델에 해당 즉, class 선언
var model = {
number : []
};
// mvvm의 vm에 해당. 즉, 모델에서 선언한 클래스를 활용하여 로직 작성
var test1 = new Vue({
el: '#app',
data: model
})
var test2 = new Vue({
el: '#app2',
data: model
})
</script>//이렇게 해야 각기 다른 html태그에서 number를 참조시 동일한 객체를 활용할 수 있다.
// A 태그에서 test1을 연결, number 값 출력, B 태그에서 test2를 연결, number 값 변경시 A 태그에도 B에서 변경한 값이 바로 반영된다.
// 이렇게 하지 않고 각 test1, test2 의 data에 맴버변수 선언 및 값 설정시, A 태그에는 B태그에서 변경한 내용이 반영되지 않는다.
2.1.1.2. el
- element의 약자
- html과 연결하는 연결고리로, 한 태그에 하나만 지정
- '#배정할문자열값' 으로 설정
- html 태그에서는 id 어트리뷰트 = "#값" 으로 연결 (class 연결과 비슷)
2.1.1.3. computed
- 읽기전용. 이미 계산된 속성
- 캐싱된 결과값을 바로 리턴
computed : {
multi : function() {
var a = Number(this.num);
if ( Number.isNaN(n)|| n<1) return 0;
return num*10;
}
}
- 호출 : vue인스턴스 변수명.multi 로 호출시 결과값이 나옴
2.1.1.4. methods
- computed와 비슷하나, 매번 계산한다는 차이가 있음
methods : {
multi : function() {
var a = Number(this.num);
if ( Number.isNaN(n)|| n<1) return 0;
return num*10;
}
}
- 호출 : vue인스턴스 변수명.multi 로 호출시 결과값이 나옴
2.1.1.5. watch
- 비동기처리 혹은 시간이 많이 소요되는 작업에 사용
- 추후 내용 추가
2.2. 바인딩 및 디렉티브
- html이 동적으로 동작한다. 맴버변수 값을 변경시, 바로 적용되는 반응형 웹이 된다.
- 디렉티브는 v- 로 시작
2.2.1. 데이터 바인딩
- {{ 맴버변수명 }} 을 통해 데이터를 바인딩 한다.
2.2.2. 디렉티브
- 일반적으로 읽기만 가능한 단방향임. v-model은 양방향
- html 태그의 어트리뷰트에 사용한다.
- 참조 : https://kadamon.tistory.com/12?category=801517
2.2.2.1. v-bind
- 엘리먼트 속성에 사용할 항목을 바인딩하여, 동적으로 동작한다.
- 예 : <img v-bind:src="맴버변수명" /> == <img :src="맴버변수명"/> (v-bind 생략가능)
2.2.2.2. v-html
- 맴버변수 값에 있는 태그를 태그로 인식하여 html 페이지에 반영한다.
- tempItem ="<h1>hello</h1>" 이고, {{ tempItem }}으로 호출하게되면, h1 태그가 동작한다.
- 보안문제로 사용치 않는것을 권장
2.2.2.3. v-text
- 맴버변수 값을 텍스트로 표시. 위의 2.2.2.2. 예제의 tempItem의 태그를 텍스트로 취급
2.2.2.4. v-model (양방향)
- 양방향으로 Vue 인스턴스 맴버변수 값을 활용. 읽기, 쓰기 모두 가능.
- 쓰기의 경우, 이벤트를 통해 쓰기 명령을 내림
<h1>{{message}}</h1>
<input v-model="message">
- 실제 렌더링 되는 html은 다음과 같음
<input v-model="something"> 의 경우
<input
v-bind:value="something"
v-on:input="something = $event.target.value">
// v-bind를 통해 value에 맴버변수를 연결
// v-on 을 통해 입력된 새로운 값($event.target.value)이 맴버변수에 배정
// 즉, 실제로는 이벤트를 통하여 값을 변경하는 것임.
2.2.2.5. v-show, v-if
- 조건문. v-show는 일단 렌더링을 하고, 조건에 부합하지 않을경우, 보여주지 않고, v-if는 아예 렌더링을 안함.
즉, v-if를 사용할것.
- v-else-if , v-else
<img v-if="number < 1000" v-bind:src="imagePath" >
// number 맴버변수 값이 1000 미만일때 이미지 출력
2.2.2.6. v-for
- 반복문
- 형태는 다양하나 객체항목을 반복하는것이 좋을듯.
- (반복변수명, index) in 딕셔너리맴버변수명 처럼 () 안에 다음의 값을 받을 수 있음
- key 값
- value 값
- index 값
- 오브젝트 그 자체
- v-for="반복변수명 in 딕셔너리맴버변수명"
- 맴버변수는 key:value 형태의 배열을 사용하는것이 편함
<div id="app"> //app 은 vue 인스턴스의 el 값
<div v-for="team in teams">
<div>랭크 : {{team.rank}}</div>
<div>팀명 : {{team.name}}</div>
<div>홈구장 : {{team.homeground}}</div>
<br>
</div>
</div>
var model = {
teams: [
{ rank: 1, name: "리버풀", homeground: "안필드"},
{ rank: 2, name: "맨유", homeground: "올드트래포트"},
{ rank: 3, name: "바르샤", homeground: "?"}
]
};
new Vue({
el: '#app',
data: model
})
//vue 의 data는 model을 배정하여 다른 html 태그에서도 동일한 오브젝트를 참조하도록 한다.
2.2.2.6.1. range v-for
- v-for="n in 10" 으로 사용
2.2.2.6.2. v-for template
- 2.2.5. 템플릿 참조
- template를 이용하여 여러 태그를 template 태그로 묶어 한번에 렌더링 가능
2.2.2.6.3. v-for 과 컴포넌트
-
2.2.2.6.4. v-for 의 key (중요)
- 각각의 노드를 구별하기 위한 id로, 렌더링 되지 않음
- 전역이 아닌 형제 노드끼리만 고유하면 됨
- 렌더링 최적화, 효율성 증대를 위해 v-for를 사용할때에 사용
- 반복문에 사용되는 클래스의 맴버변수로 설정하며, 해당 맴버변수는 고유값을 가져야 함
- 사용 전, 후 예
- 1, 2, 3, 4 의 text를 가진 배열을 렌더링 하고 있고, 1번항목을 지우고 2,3,4 만 렌더링 하려고 할경우.
- 사용 전 : 1 -> 2로 수정, 2->3 으로 수정, 3->4 로 수정, 4 -> 5로 수정, 5 삭제
- 사용 후 : 1 항목 삭제
- v-for="item in items" :key="고유한값을가진 맴버변수"
<ul>
<li v-for="item in myItems" :key="number">
{{ item.number }}
{{ item.name }}
</li>
</ul>
2.2.2.7. 배열 컨트롤 함수
2.2.2.7.1. 원본 항목 변경
- push() : 끝에 삽입.
- items.push({message:'aaa'})
- pop() : 마지막 항목을 꺼내고 원본에서 삭제
- shift() : 처음 항목을 꺼내고 원본에서 삭제
- unshift() : 배열 앞에 항목 추가
- splice(pos, length) : pos 위치부터 length 만큼 추출
- sort() : 정렬
- reverse() : 역순 정렬
2.2.2.7.2. 원본 항목을 변경치 않는 함수
- 항상 새 배열을 리턴
- filter()
- concat()
- slice()
2.2.2.7.3. filter
- 항상 새 배열을 리턴
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
2.2.2.7.4. 주의 사항
- 참조 : https://kr.vuejs.org/v2/guide/list.html
- items[index] = newvalue 같은 경우, 인지 하지 못함.
=>Vue.set(items,index,newvalue) 를 사용 하여야 함
- items.length 또한 인지하지 못함
=> items.splice() 를 통해 제어
- 이미 선언한 클래스에 맴버변수를 추가 하는 법
- Vue.set()을 사용하여 추가
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
Vue.set(vm.userProfile, 'age', 27)
2.2.2.8. v-pre
- {{message}} 를 할경우, message 변수에 담긴 내용이 보이는데, {{ }}까지 보여주고 싶을때 사용
2.2.2.9. v-once
- 한번만 렌더링 할 경우에 사용
- <h3 v-once>{{message}}</h3> 로 작성 후 message 값을 변경하여도 변경되지 않음.
2.2.2.10. v-cloak
- Vue 인스턴스가 컴파일에 시간이 너무 오래 걸려, html 태그에 연결한 맴버변수가, 맴버변수의 값이 아닌 맴버변수명이 보이는것을 방지
- <h3 v-cloak>{{message}}</h3> 일 경우, 컴파일이 너무 오래걸려 message의 값이 보이지 않고, message 라고 표기되는것을 방지
2.2.2.11. v-on
- Vue 인스턴스 메서드 호출. 사용자 상호작용을 위해 사용함
<button id="app-5" v-on:click="reverseMessage">메시지 뒤집기</button>
// Vue의 reverseMessage 함수 호출
var app5 = new Vue({
el: '#app-5',
data: {
message: '안녕하세요! Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
2.2.3. 인라인 스타일 바인딩
- style 속성에 대하여 바인딩 함으로서, 동적으로 변경 가능
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
또는
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
2.2.3.1. 배열 바인딩
- 여러개의 스타일을 바인딩 할 수 있다.
<div v-bind:style="[baseStyles, overridingStyles]"></div>
2.2.4. html 클래스 바인딩 (음.......이해가..)
- style 속성에 대하여 바인딩 함으로서, 동적으로 변경 가능
- v-bind:class="{....}" 으로 사용
2.2.4.1. bool 값
- 해당 클래스 바인딩을 적용할지 말지 bool로 값을 설정
<div v-bind:class="{ active: isActive }"></div>
//active 라는 클래스의 존재여부를 설정함으로서, 스타일 적용 유무가 변경
2.2.4.2. 기존 class와 혼용
- 기존 class="클래스명" 과 v-bind:class 를 혼용하여 사용가능
2.2.4.3. 객체 바인딩
- 미리 정의된 객체를 바인딩 하여 일괄 적용
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
2.2.4.4. computed를 이용한 속성 바인딩 (일반적으로 많이 쓰임)
- 특정 계산식을 통해 결과값을 바인딩
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
2.2.4.5. 배열을 통한 다중 속성 바인딩
- 배열을 통해 여러개의 속성을 바인딩 할 수 있음
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
2.2.4.6. 삼항 연산자 사용 바인딩
- a ? b : c 의 삼항 연산자를 통해 바인딩 가능
2.2.5. 템플릿
- <template> 태그를 이용하여 여러개의 태그를 묶어 한번에 렌더링
- <template> 태그의 경우, 사용하지 않는한 렌더링 되지 않는다.
-
2.3. 컴포넌트
- 작은 기능을 하는 컴포넌트 생성 -> 재사용
- 기본 html 태그를 확장하여 재사용
- 경우에 따라 is 를 사용하여 html 태그 확장
- Vue 컴포넌트는 Vue 인스턴스 이기도 하므로, 모든 옵션을 사용할 수 있음
- 컴포넌트 등록은 new Vue를 통한 루트 Vue 인스턴스 생성전에 해야함
2.3.1. 컴포넌트 등록 (전역)
- Vue.component('태그명', 옵션) 사용
- 옵션은 2.1.1. 참조
// todo-item 이름을 가진 컴포넌트를 정의합니다
Vue.component('todo-item', {
template: '<li>할일 항목 하나입니다.</li>'
})
2.3.2. 컴포넌트 등록 (지역)
- components 인스턴스 옵션 내부에 선언
- 다른 인스턴스 혹은 컴포넌트 범위에서만 사용가능
var Child = {
template: '<div>사용자 정의 컴포넌트 입니다!</div>'
}
new Vue({
// ...
components: {
// <my-component> 는 상위 템플릿에서만 사용할 수 있습니다.
'my-component': Child
}
})
2.3.3. 컴포넌트 사용
- 등록된 컴포넌트 이름을 사용
<ol>
<!-- todo-item 컴포넌트의 인스턴스 만들기 -->
<todo-item></todo-item>
</ol>
// 이경우 똑같은 항목을 렌더링 하게 됨.
2.3.4. 제약사항
- <ul>, <ol>, <table>, <select> 의 경우, 다음에 올 하위 태그가 정해져 있으므로, 컴포넌트 사용시 오류가 발생함.
- 해결하기 위해서 is 속성을 사용
<table>
<tr is="my-row"></tr>
</table>
- data는 반드시 함수 여야 함
- data:{ } 형태가 아닌, data: function() { } 형태로 정의해야 함
<div id="example-2">
<simple-counter></simple-counter>
<simple-counter></simple-counter>
<simple-counter></simple-counter>
</div>
Vue.component('simple-counter', {
template: '<button v-on:click="counter += 1">{{ counter }}</button>',
// 데이터는 기술적으로 함수이므로 Vue는 따지지 않지만
// 각 컴포넌트 인스턴스에 대해 같은 객체 참조를 반환합니다.
data: function () {
return { counter:0 }
}
})
new Vue({
el: '#example-2'
})
//data는 맴버변수 선언 및 초기화를 담당하며, html에서 맴버변수 접근하여 사용가능하다.
2.3.5. 컴포넌트 부모 관계
- 컴포넌트는 부모 자식관계에서 가장 일반적으로 사용함.
- parent 가 child에게 데이터를 전달할때 : props 사용
- child가 parent에게 메세지를 보냄 : event 사용
2.3.5.1. Props 옵션
- 참조 : https://beomy.tistory.com/56
- 오브젝트를 하위 자식에게 전달하기 위해 사용하는 옵션
- data 에 변수 선언하는것처럼, props 옵션을 사용하면, 변수를 선언하는것임. 즉, data 에서 변수선언 하면 안됨 (중복오류)
- v-model을 이용하여 양방향 바인딩은 html태그의 id와 연결된 Vue instance에서 data: 로 선언한 변수와 연동하는것임.
- 컴포넌트 변수와 양방향 연동을 위해서는 props를 사용해야함
Vue.component('child', {
// props 정의
props: ['message'],
// 데이터와 마찬가지로 prop은 템플릿 내부에서 사용할 수 있으며
// vm의 this.message로 사용할 수 있습니다.
template: '<span>{{ message }}</span>'
})
<child message="안녕하세요!"></child>
//컴포넌트 명이 child 이며, html의 child 태그에서 props로 정의한 message 변수 값을 변동함
2.3.5.1.1. 선언
- props:['변수명', '변수명'...],
- 변수들은 string이 된다.
- props: { 변수명:String, 변수명:Number, 변수명:Boolean, 변수명:Array, 변수명:Object...},
- 특정 자료형을 갖는 변수들 생성
- props 변수값이 변경될 때 검증이 가능하며, 자료형과 맞지않으면 경고 발생
- 예 : bool 변수에 문자열을 넣는 등
- 초기값을 설정하기 위해 default: 를 선언부에 사용한다.
- 필수입력을 위해 required:를 선언부에 사용한다.
Vue.component('example', {
props: {
// 기본 타입 확인 (`null` 은 어떤 타입이든 가능하다는 뜻입니다)
propA: Number,
// 여러개의 가능한 타입
propB: [String, Number],
// 문자열이며 꼭 필요합니다
propC: {
type: String,
required: true
},
// 숫자이며 기본 값을 가집니다
propD: {
type: Number,
default: 100
},
// 객체/배열의 기본값은 팩토리 함수에서 반환 되어야 합니다.
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 사용자 정의 유효성 검사 가능
propF: {
validator: function (value) {
return value > 10
}
}
}
})
2.3.5.1.2. Props case
- javascript 에서 카멜케이스 (두번째 문자열이 대문자) 사용 하여 변수 선언시, html에서 케밥케이스인 -을 사용해야함
Vue.component('child', {
// JavaScript는 camelCase
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
<!-- HTML는 kebab-case -->
<child my-message="안녕하세요!"></child>
2.3.5.1.3. 동적 Props
- Vue instance 의 data 에 선언한 변수를 props 변수에 bind 하여 동적으로 값이 바뀌도록 할 수 있다.
- v-bind:props선언변수="Vue Instance의 data에 선언한 변수"
<div id="test">
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
Vue.component(
{
props:['myMessage'],
.....
}
)
new Vue({
el:"#test",
data: { parentMsg:'' }
})
//v-bind
2.3.5.1.4. 동적 Props - 오브젝트 할당
- String, Number 등 값을 할당하는것이 아닌, Vue Instance의 data: 에서 클래스 형식으로 선언한 변수를 배정
- props 변수명.맴버변수 로 데이터 접근이 가능
<div id="app-7">
<ol>
<!--
이제 각 todo-item 에 todo 객체를 제공합니다.
화면에 나오므로, 각 항목의 컨텐츠는 동적으로 바뀔 수 있습니다.
또한 각 구성 요소에 "키"를 제공해야합니다 (나중에 설명 됨).
-->
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id">
</todo-item>
</ol>
</div>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
})
2.3.5.1.5. html 속성 병합 및 대체
- 컴포넌트 내부 template 에 커스텀 속성 및 클래스가 있을경우, 기본 속성과 병합됨
- class 속성과 style 속성은 병합되나, 그외 속성들은 컴포넌트에 정의된 속성으로 대체됨.
<input type="date" class="form-control">
//컴포넌트 template에 아래와 같이 정의되어 있을경우
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
type="text"
></bootstrap-date-input>
//class는 form-control date-picker-theme-dark 로 병합됨
// 속성인 data-date-picker 속성은 추가되어 type 처럼 사용됨
// type는 date가 아닌 text로 대체됨
2.3.5.1.6. html 속성 병합 하지 않기
- 컴포넌트에 inheritAttrs:false 선언을 해주면, html의 속성을 병합하지 않고 무시한다.
<base-input type="text" ...></base-input>
Vue.component('base-input', {
inheritAttrs: false,
template: '<input />'
})
//이 경우, 최종 생성되는 태그는 <input /> 이다
2.3.6. 사용자 이벤트
- 2.5. 사용자 정의 이벤트 참조
// 컴포넌트 템플릿에 정의한 v-on:click 에 의해 클릭시 incrementCounter 함수 (컴포넌트에 정의한 함수) 실행
// -> emit을 통해 increment 이벤트 실행 -> 버튼의 v-on:increment 에서 이벤트 수신 -> incrementTotal 함수 (Vue 인스턴스에서 정의) 호출
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
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.3.7. 사용자 이벤트를 통한 컴포넌트 간 통신
- 2.5. 사용자 정의 이벤트 참조
- 부모, 자식 관계가 아닌 컴포넌트 간 통신
- 비어있는 Vue instance를 이용
- 각 컴포넌트에서 공통으로 접근 가능
- emit, on 을 통해 이벤트 함수 사용을 위해 생성
var bus = new Vue()
// 컴포넌트 A의 메소드
bus.$emit('id-selected', 1)
// 컴포넌트 B의 created 훅
bus.$on('id-selected', function (id) {
// ...
})
2.3.8. 이벤트 발생시 사용자 정의 함수 호출
- 2.5. 사용자 정의 이벤트 참조
- v-bind:value="preps변수", v-on:input="사용자 정의 함수($event.target.value)" 를 통해 사용자 정의 함수 접근
- 사용자 정의 함수에서 계산 후 preps변수에 값을 할당
- 기존 input 이벤트로 다시 변경된 값을 전달하기 위해 이벤트 발생
html : <currency-input v-model="price"></currency-input>
Vue.component('currency-input', {
template: '\
<span>\
$\
<input\
ref="inputTag"\ //다른곳에서 이 태그를 참조하기 위해 ref 속성을 이용해 값을 넣어줌
v-bind:value="propsValue"\ //input 태그의 value 에 props변수를 연결
v-on:input="updateValue($event.target.value)">\ //input 이벤트 발생시 사용자 정의 함수 호출. 원본 이벤트의 값을 인자값으로 넘겨줌
</span>\
',
props: ['propsValue'],
methods: {
// 값을 직접 업데이트하는 대신 이 메소드를 사용하여
// 입력 값에 대한 서식을 지정하고 배치 할 수 있습니다
updateValue: function (value) {
var formattedValue = value
// 공백을 제거합니다.
.trim()
// 소수 자릿수 2자리로 줄입니다
.slice(
0,
value.indexOf('.') === -1
? value.length
: value.indexOf('.') + 3
)
// 값이 아직 정규화 되지 않은 경우
// 이를 수동으로 재정의하여 조건을 충족시킵니다.
if (formattedValue !== value) {
this.$refs.inputTag.value = formattedValue
}
// 입력 이벤트를 통해 숫자 값을 내보냅니다.
this.$emit('input', Number(formattedValue))
}
}
})
new Vue({
el: '#app',
data: {
price: 0
},
'FrontEnd' 카테고리의 다른 글
vue js 내용정리 (2.7. 트랜지션 ~) (0) | 2022.03.25 |
---|---|
vue js 내용정리 (2.3.9 컴포넌트-slot태그 ~ 2.6. 사용자 정의 이벤트) (0) | 2022.03.25 |
FrontEnd 개발 관련 내용정리 (0) | 2022.03.25 |
HTTPS 상에서 Front-end 페이지 테스트 (0) | 2022.03.24 |
AWS with JavaScript (0) | 2022.03.24 |