Vue - 인스턴스!

vue 인스턴스 옵션

vue 인스턴스 에서 여러가지 옵션객체, 옵션메서드를 제공하는데
데이터 바인딩, 이벤트 핸들링 등에서 필수로 알아야할 옵션을 알아본다.

new Vue ({
    // 옵션 객체
    data: { name: "Editor" },
    // 옵션 메서드
    computed: {
        merge_name: function() {
            return "Lee Joong-Min"
        }
    },
    watch: {
        name: function (new_value, old_value) {
            // TODO data changed
        }
    }
});

vue 인스턴스 옵션을 통해 vue 템플릿 에 데이터 바인딩할 뿐 아니라
이벤트 핸들링, 라이프사이클에 따른 후킹작업등을 수행하는데

이런 작업을 총망라해서 부트스트래핑(Bootstrapping) 이라 한다.

el

vue 인스턴스 가 동작할 DOM 요소를 지정할 때 사용

CSS 선택자 를 사용하며 최대한 작은 범위를 선택하는 것을 권장한다.


<div id="test">
  {{name}}
</div>
<script>
  var vinstance = new Vue({
    el: "#test",
    data: { name: "홍길동" }
  })
</script>

DOM 요소vue 인스턴스 연결을 el 객체로 연결하였는데 다중 연결은 지원하지 않는다,
CSS 선택자를 통해 검색된 첫번째 요소에만 연결처리된다.

실행 도중 동적으로 DOM 요소vue 인스턴스 연결은 가능하나 이미 연결된 관계를 변경할 수는 없다.

data

vue 컴포넌트상태값이라 부르기도 하며 데이터 바인딩시 사용


<div id="test">
  {{name}}
</div>
<script>
  var vinstance = new Vue({
    el: "#test",
    data: { name: "홍길동" }
  })
</script>

#simple 아이디값을 가진 DOM 객체에서 div 태그 사이에 홍길동이 출력된다.

스크립트 내부에서 name에 접근하는 방법들을 알아보자.

vinstance.name
vinstance.$data.name

vue인스턴스data옵션객체 사이에 프록시($data)를 두어 처리,
data옵션객체를 변경사항이 발생되면 즉시 감지되어 이벤트처리된다.
vinstance.namevinstance.$data.name의 차이점을 보면 프록시객체에 접근방법도 알 수 있다, 앞에 $를 붙이면 된다.

template

html markup 을 바인딩할 때 사용

다음과 같이 template 에 html 마크업을 지정하면
자식 요소를 template 의 html 마크업으로 교체한다.


var vm = new Vue({
    el: "div#markup",
    template: "<h2>{{ markup }}</h2>",
    data: { markup: "새로운 마크업" }
});

template 으로 사용할 markup 이 복잡하다면 별도의 script 태그로 분리해서 사용할 수 있다.


<script type="text/x-template" id="markup_tmplp">
    <p>Hello, {{ name }}</p>
</script>

<script>
    var vm = new Vue({
        data: { name: "Hanbit" },
        template: "#markup_tmpl"
    });
</script>

parent

상위 vue 컴포넌트 를 설정할 때 사용
잘 사용하지 않고 단순 독립 컴포넌트 형태로 사용하는 경우가 많음

var parent_vm = new Vue({ });
var child_vm = new Vue({ parent: parent_vm });

parent_vm$children 배열에 child_vm 가 포함되며
child_vm$parent 속성에 parent_vm 가 할당된다.

mixin

mixin 옵션을 사용해 객체를 사용해 vue 컴포넌트들의 옵션을 표현할 수 있다.
vue 컴포넌트 를 여러개에 동일한 옵션들을 삽입해야할 때 사용한다.

mixin 의 옵션들은 기존 vue 컴포넌트 에서 정의한 옵션들과 겹칠 수 있다.
또한 mixin 은 옵션배열로 mixin 객체들 사이에서 중복되는 옵션들이 정의될 수 있다.

vue 에선 우선순위를 지정하여 mixin 옵션에 우선권을 차례대로 부여하며
vue 컴포넌트 에서 정의한 옵션은 최후에 사용된다.

computed

인스턴스 템플릿 에 함수결과를 표시하려면 Mustache 표현식을 사용해도 되지만
랜더링시에 포현식이 실행되어 성능하락을 야기한다.


<div id="example">
    {{ message.split('').reverse().join('') }}
</div>

랜더링 전에 미리 계산된 속성으로 사용하는 방법을 권장한다.

computed 속성은 반드시 인자를 받지 않는 함수로 구성해야 한다.


<div id="example">
    {{ reversedMessage }}
</div>
<script>
    new Vue({
        el: '#example',
        data: { message: 'Hello Vue.JS World' }
        computed: {
            reversedMessage: function () {
                return this.message.split('').reverse().join('')
            }
        }
    });
</script>

computed 속성값을 인스턴스 내부에 저장해두는 캐싱방법을 사용하기에
캐시가 초기화 되지 않는 이상 재랜더링 되더라도 동일한 데이터가 출력된다.

캐시 초기화 조건은 data 가 업데이트 되었을 때

아래처럼 getter, setter 를 정의해서 사용하는 것도 좋은 방법
computed 의 읽기만 한다는 틀을 깨고 setter 을 통해 값을 초기화 하는 것도 가능하다.

computed: {
    fullName: {
        get: function () {
            return this.firstName + ' ' + this.lastName
        },
        set: function (newValue) {
            var names = newValue.split(' ')
            this.firstName = names[0]
            this.lastName = names[names.length - 1]
        }
    }
}

methods

watch

vue 인스턴스상태값 변경을 감시하는 옵션

vue 인스턴스 에서 변경이 일어나면 호출하는 computed의 메서드와 달리
watch 속성은 긴 시간동안 해당 데이터의 변경이 일어나는지 관찰하며 특정 메서드를 호출하여 비동기 처리에 적합하다.

또한 함수의 반환값을 지정할 필요도 없다.


<div id="example">
  x: <input type="text" v-model="x" /><br>
  y: <input type="text" v-model="y" /><br>
  덧셈결과: {{sum}}
</div>
<script>
  var vm = new Vue({
    el: "#example",
    data: { x: 0, y: 0, sum: 0 },
    // 옵션객체
    watch: {
      // function (newVal, oldVal) 이전의 데이터도 사용 가능
      x: function (v) {
        console.log("## x 변경, v:" + v);
        var result = Number(v) + Number(this.y)
        if (isNaN(result)) this.sum = 0;
        else this.sum = result;
      },
      y: function (v) {
        console.log("## y 변경, v:" + v);
        this.y = v;
        var result = Number(this.x) + Number(v)
        if (isNaN(result)) this.sum = 0;
        else this.sum = result;
      }
    }
  })
</script>

watch 옵션에 immediate, deep 속성을 추가로 정의할 수 있다.

deep: true 일 경우 내부 객체의 변화까지 감시한다.
immediate: true 일 경우 초기화와 동시에 watch 의 핸들러 함수가 호출된다.

watch: {
    b: {
        handler: function (val, oldVal) {
            console.log(val); // 4
            console.log(oldVal); // undefiend
        },
        deep: true, //default false
        immediate: true // default false
    }
}

deep 을 사용하지 않고 객체 속성의 변화까지 추적하고 싶다면 아래와 같이 속성명을 사용

watch: {
    'a.b': function (new_val, old_val) {
        console.log(new_val);
        console.log(old_val);
    },
}

computed, methods, watch 차이

값을 연산해 반환하는 메서드를 호출하고 computed 혹은 methods 속성을 사용한다.


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

사용방법만 놓고 보면 둘의 차이점은 매우 미비하나 내부 동작방식의 차이점이 있다.

computed의 경우 data값의 변경 여부에 따라
캐싱된 값return 할지, 메서드를 호출해 연산값을 return 할지 결정한다.

methods의 경우 항상 메서드 연산을 통해 값을 return 한다.

코드상에선 두 속성을 2번씩 호출하지만 computed 의 경우 그중 한번은 캐시값을 반환함으로 console에 한번만 출력된다.

computed, watch 모두 vue 인스턴스 내부의 연관된 data 가 변경되면 호출된다.

만약 아래와 같이 연관된 data 값이 없을경우 computed 메서드는 한번도 호출되지 않는다.

computed: {
    sumCompute: function () {
        console.log("sumCompute:" + Date.now());
    }
},
watch: {
    sumWatch: {
        console.log("sumWatch:" + Date.now());
    }
},

computedwatch 사용방법은 여러가지 차이가 있다
computed 의 경우 연관 data 를 한 메서드에서 다중 설정 가능하지만 watch 는 하나의 변수만 감시할 수 있다.

사용 방법또만 computed 에 정의된 메서드를 호출하려면 콧수염 방식으로 호출해야 하는 반면 watch 의 경우 콜백형식으로 호출된다.

vue 필터

데이터 바인딩하여 랜더링 하기 전
전후처리를 통해 데이터를 변경해야 할 때 필터를 사용하면 좋다.

전역필터컴포넌트 한정필터 가 존재하며
vue 인스턴스 선택자에 따라 지정하면 된다.

필터의 첫번째 매개변수는 파이프라인으로부터 넘어온 값이 사용되며
매개변수를 아래처럼 별도로 지정 가능하다.

파이프를 이어 여러번 필터를 거치게 할 수 있다.


<div id="app">
    <span>{{ i | multiply_number1 }}</span><!-- 10 출력 -->
    <span v-text="i | multiply_number2(3)"></span><!-- 15 출력 -->
</div>
<script>
    /* 전역필터 */
    Vue.filter('multiply_number1', function (value) {
        return value * 2;
    });
    var app = new Vue({
        el: '#app',
        data: { i: 5 }
        /* 컴포넌트 한정필터 */
        filters: {
            multiply_number2: function (value, number) {
                return value * number;
            }
        }
    });
</script>

아래와 같은 필터를 자주 사용한다.

var app = new Vue({
    filters: {
        /* 첫문자 대문자 */
        capitalize: function (text) {
            return text[0].toUpperCase() + text.slice(1)
        },
        uppercase: function (text) {
            return text.toUpperCase()
        },
        lowercase: function (text) {
            return text.toLowerCase()
        }
    }
});

vue 인스턴스 속성

이미 생성된 vue 인스턴스의 옵션을 참조하고 싶다면 아래와 같이 $... 키워드를 통해 접근 가능하다.
vue 인스턴스가 각 옵션에 접근전에 한 단계의 관문(프록시) 를 생성했기 때문

  • vm.$data: data 옵션 참조
  • vm.$props: data옵션
  • vm.$el: data옵션
  • vm.$options: data옵션
  • vm.$root: data옵션
  • vm.$parents: data옵션
  • vm.$children: data옵션
  • vm.$slots: data옵션
  • vm.$scopedSlots: data옵션
  • vm.$refs: data옵션
  • vm.$isServer: data옵션

카테고리:

업데이트: