티스토리 뷰

Vue

Vue 인스턴스

인삼추출물 2021. 1. 29. 09:16

(공부 책 : Vue.js Quick Start )

1. el, data, computed 옵션

var vm = new Vue({
	el: '#example',
	data: model,
	computed: {
		test : function() {
			...
		}
	}
})

el 옵션은 Vue 인스턴스에 연결할 HTML DOM 요소를 지정합니다.

주의할 점은 el옵션에 여러 개 요소를 지정할 수 없다는 점입니다.

data 옵션에 주어진 모든 속성들은 Vue 인스턴스 내부에서 직접 이용되지 않고 Vue 인스턴스와 Data 옵션에 주어진 객체 사이에 프록시를 두어 처리합니다.

computed 옵션에 지정한 값은 함수였지만 Vue 인스턴스는 프록시 처리하여 마치 속성처럼 취급합니다.

test는 분명 함수입니다만 console 창에서 vm.test로 접근해도 정상 실행되는 것을 볼 수 있습니다. 이러한 이유로 계산형 속성이라 부르는 것 입니다.

계산형 속성은 자바, C언어에서 다루는 getter/setter 메서드와 같은 작업도 가능합니다.

<body>
    <div id="example">
        금액 : <span>{{amount}}원</span>
    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#example",
            data: {
                amt: 1234567
            },
            computed: {
                amount: {
                    get: function() {
                        var s = new String("" + this.amt);
                        var result = "";
                        var num = 0;
                        for (var i = s.length - 1; i >= 0; i--) {
                            result = s[i] + result;
                            if (num % 3 == 2 && i !== 0)
                                result = "," + result;
                            num++;
                        }
                        return result;
                    },
                    set: function(amt) {
                        if (typeof(amt) === "string") {
                            var result = parseInt(amt.replace(/,/g, ""))
                            if (isNaN(result)) this.amt = 0;
                            else this.amt = result;
                        } else if (typeof(amt) === "number")
                            this.amt = amt;
                    }
                }
            }
        });
    </script>
</body>

get 함수는 amt 값을 3자리마다 쉼표를 넣어서 리턴하도록 하는 함수입니다.

set 함수는 입력받은 문자열에서 쉼표를 제거하고 amt에 할당하는 함수입니다. 

 

2. 메서드

Vue 인스턴스에서 사용할 함수를 등록하는 옵션입니다.

<body>
    <div id="example">
        <input type="text" v-model="num" /><br /> 1부터 입력된 수까지의 합 : <span>{{sum1()}}</span>
    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#example",
            data: {
                num: 0,
                i: 0
            },
            methods: {
                sum1: function() {
                    console.log(Date.now());
                    var n = Number(this.num);
                    if (Number.isNaN(n) || n < 1) return 0;
                    return ((1 + n) * n) / 2;
                }
            },
            computed: {
                sum2: function() {
                    console.log(Date.now());
                    var n = Number(this.num);
                    if (Number.isNaN(n) || n < 1) return 0;
                    return ((1 + n) * n) / 2;
                }
            }
        });
    </script>

예제 코드만 봐선 메서드가 계산형 속성과 무슨 차이가 있는지 확인하기 어렵습니다.

( 콧수혐 표현식에서 계산형 속성을 불러올땐 위 함수()방식이 아닌 {{sum2}}로 코딩해야 호출됩니다. )

메서드나 계산형 속성을 사용했을 때 최종적인 결과물은 같지만 계산형 속성은 결과값이 캐싱된다는 내부작동 방식에서 차이가 납니다.

콘솔창에서 알 수 있듯 메소드 sum1의 경우 실행할 때마다 함수를 매번 실행하지만

계산형 속성 sum2는 한번 실행 후 캐싱된 값을 출력하고 있습니다.

결론적으로 메서드와 계산형 속성 중 어떤 것을 사용할지 결정할 때 캐싱 여부를 고려하면 됩니다.

!! 메서드 사용 시 주의할 점으로 ES6에서 제공하는 람다식(화살표 함수)을 메서드에서 사용해서는 안됩니다.

람다식 내부에서는 this가 Vue 인스턴스를 가리키지 않고, 전역 객체를 가리키기 때문입니다. 

일반적으로 메서드 내부에선 데이터 속성들을 이용하기 때문에 this가 바뀌게 되면 Vue 인스턴스 내부 데이터에 접근할 수 없게 됩니다.

 

3. 관찰 속성

관찰 속성은 주로 긴 처리 시간이 필요한 비동기 처리에 적합한 특징을 가지고 있습니다.

관찰형 속성의 단점은 대상 값이 바뀔때마다 함수를 호출한다는 점인데

값이 빈번하게 바뀌는 객체는 기존 계산형 속성을 이용하는 것이 훨씬 효율적입니다.

그렇다면 긴 시간이 필요한 비동기 처리 예로 무엇이 있을까요?

비동기 처리의 대표적인 예가 외부 서버와의 통신 기능입니다.

방법으로 jQuery의 Ajax, promise 기반 fetch, vue.js에서 제공되는 vue-resource 등 여러개가 있습니다만

저희는 fetch()를 이용해보겠습니다.

※ 책 제작자(원형섭님)의 open api가 활용되는 점을 감안해 코드일부를 제거하여 표기될 예정입니다.

<body>
    <div id="example">
        <p>
            이름 : <input type="text" v-model="name" placeholder="두글자 이상을 입력하세요" />
        </p>
        <table id="list">
            <thead>
                <tr>
                    <th>번호</th>
                    <th>이름</th>
                    <th>전화번호</th>
                    <th>주소</th>
                </tr>
            </thead>
            <tbody id="contacts">
                <tr v-for="contact in contactlist">
                    <td>{{contact.no}}</td>
                    <td>{{contact.name}}</td>
                    <td>{{contact.tel}}</td>
                    <td>{{contact.address}}</td>
                </tr>
            </tbody>
        </table>
        <div v-show="isProcessing === true">조회중</div>
    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#example',
            data: {
                name: "",
                isProcessing: false,
                contactlist: []
            },
            watch: {
                name: function(val) {
                    if (val.length >= 2) {
                        this.fetchContacts();
                    } else {
                        this.contactlist = [];
                    }
                }
            },
            methods: {
                fetchContacts: _.debounce(function() {
                    this.contactlist = [];
                    this.isProcessing = true;
                    var url = "생략" + this.name;
                    var vm = this;
                    fetch(url)
                        .then(function(response) {
                            return response.json()
                        }).then(function(json) {
                            vm.contactlist = json;
                            vm.isProcessing = false;
                        }).catch(function(ex) {
                            console.log('parsing failed', ex);
                            vm.contactlist = [];
                            vm.isProcessing = false;
                        })

                }, 300)
            }
        })
    </script>
</body>

 

watch 내 name 속성의 변화를 감지하여 길이가 2이상일 경우 fetchContacts()함수를 호출합니다.

함수 내부에 _.debounce() 함수는 lodash 라이브러리에서 제공하는 함수로 짧은 시간 많은 API요청이 일어나는 걸 방지합니다.

300ms(0.3초) 동안 타이핑이 일어나지 않으면 API 요청이 수행되므로 불필요한 트레픽을 줄일 수 있습니다.

fetch()는 앞서 설명했듯 비동기 처리에 쓰이는 함수로 return 값으로 promise 객체를 반환합니다.

fetch() 함수 호출 후 응답이 오면 then에 결과값을 전달하고 결과값을 contactlist에 넣으면 화면에 표기되는 방식입니다.

이 예제에선 계산형 속성을 사용할 수 없습니다. 계산형 속성은 값을 직접 리턴해야하기 때문에 동기적 처리에서만 쓰일 수 있기 때문입니다.

 

4. v-cloak 디렉티브

프로그램 실행시 템플릿 문자열이 잠깐 나타났다 사라지는 현상이 있는데 이를 제거하기 위한 방법으로 v-cloak 디렉티브가 있습니다.

<style>
	[v-clock] { display: none; }
</style>

<div id="example" v-clock>
....
</div>

위와 같이 v-clock을 추가하면 위에서 언급한 현상이 사라지는걸 확인할 수 있습니다.

 

5. Vue 인스턴스 라이프 사이클

개발하다보면 라이프 사이클에 맞게 Vue 컴포넌트를 만들고 관리해야할 때가 있습니다.

블로그 트러블슈팅 탭에 보시면 created, mounted 라이프 사이클 차이로 일어난 문제를 확인할 수 있습니다.

그러므로 라이프 사이클 훅이 중요하지 않다 여기더라도 공식 문헌에서 한번 참조하시길 바랍니다.

 

공식 홈페이지 참고 문헌 : kr.vuejs.org/v2/guide/instance.html

'Vue' 카테고리의 다른 글

Vue.js 스타일  (0) 2021.03.25
Vue.js 이벤트 처리  (0) 2021.02.25
Vue.js 기타 디렉티브와 계산형 속성  (0) 2021.01.22
Vue.js 반복 렌더링 디렉티브  (0) 2021.01.12
Vue.js 기본 디렉티브  (0) 2021.01.04
댓글
공지사항