Vue.js 동작원리

강정우·2023년 3월 29일
0

vue.js

목록 보기
8/72
post-thumbnail
post-custom-banner

1. vue 동작원리

  • data props에서 가장 중요한 것은 data에서 정의한 내용을 Vue가 지속적으로 추적한다는 것이다.
    이전에 설명했듯 Vue는 이 data 객체의 모든 프로퍼티를 전역 프로퍼티와 합쳐서 내부에서 관리하는 하나의 객체로 만든다.
    이때 methods도 해당 객체에 합쳐진다. 바로 이런 작업이 Vue의 내부에서 이루어진다.

  • data에 대해 Vue가 하는 작업 중 가장 핵심적인 일은 프로퍼티를 JavaScript의 기능인 프록시로 래핑해서 data 객체를 반응형 data 객체로 바꾸는 일이다.

내장된 reactive 기능 동작 순서

  1. JavaScript에는 내장 기능인 프록시가 있다. Vue가 내부에서 이를 활용하여 data 프로퍼티를 래핑한다.
  2. data내부 값이 바뀔 때마다 알리는 작업을 한다.
  3. 이렇게 proxy를 통하여 Vue가 이를 인식하면 Vue는 제어하는 HTML 코드를 스캔하고 변경 사항이 있는 프로퍼티가 있음을 확인한다.
  4. 변경 사항이 있다는 것을 인식하면 사용자가 보는 화면이 될 렌더링된 페이지에서 해당 동적 콘텐츠가 표시되는 올바른 위치를 찾은 다음 변경 사항에 따라 화면에 나오는 페이지를 업데이트한다.

2. Proxy

  • 참고로 Proxy는 모던 JavaScript에 내장된 생성자 함수이기 때문에 이 코드를 테스팅할 때는 Chrome과 같은 모던 브라우저에서 작업해야한다.

문법

// traps
const handler = {
  set(target, key, value){
    console.log(target)
    console.log(key)
    console.log(value)
  }
}

const proxy = new Proxy(래핑할객체, traps(래핑할객체에 대한 핸들러를 담고있는 객체))

예제

  • 우선 proxy는 앞서 언급했듯 vue의 기능이 아니라 JS의 기능이다.
    다음 예제 코드를 보자.
let message = "hello"

let longMessages = message + "world"

console.log(longMessages) // hello world

message = "hola~"

console.log(monMessages) // hello world
  • 보면 중간에 message에 대한 값을 바꿔도 인식되지 않는다. 왜냐하면 JS는 기본적으로 reactive하지 않기 때문이다.

  • 그러다면 이제 proxy를 이용해보자.

const data = {
  message : "hello"
}

const handler = {
  set(target, key, value){
    console.log(target)
    console.log(key)
    console.log(value)
  }
}

const proxy = new Proxy (data, handler)

proxy.message = "Hola~"

// {message : hello}
// {message}
// {Hola~}
  • 위 코드가 가능한 이유는 data 객체를 첫 번째 인수로서 래핑하였다. 따라서 proxy를 통해서 message에 액세스할 수 있는 것이다.

  • 또한 set함수에서 setter 함수를 정의하는데 이 함수는 proxy에 새로운 프로퍼티가 설정될 때마다 트리거된다는 것을 알 수 있다. 그리고 이를 통해 새 값이 설정된 프로퍼티가 무엇이며 설정된 새 값은 무엇이고 래핑된 원본 객체가 무엇인지 알 수 있다.

const data = {
  message : "hello"
  longMessages : "hello World"
}

const handler = {
  set(target, key, value){
    if(key === "message"){
      target.longMEssages = value + "World"
    }
	target.message = value
  }
}

const proxy = new Proxy (data, handler)

proxy.message = "Hola~"

console.log(proxy.longMessages)  // Hola~ World
  • 이처럼 proxy를 이용하여 reactive한 코드를 작성하였다. 이것이 바로 vue가 작동하는 방식이다.

3. creatApp

  • Vue.createApp은 여러개를 만들 수 있으며 각각 독립적인 앱으로 간주된다.
    따라서 서로 데이터의 교환은 안 되기 때문에 한개의 element를 다룰 땐 한가지의 vue.app을 사용해야한다.

4. template

  • 템플렛은 vue가 제어하는 html 코드부분을 뜻한다.

  • 또 앱 구성 객체로서 template 속성을 사용할 수 있다.

index.html

<section id="app"><section/>
const app = Vue.creatApp({
  template:`
	<p>my favorite meal is {{favortieMeal}}</p>
  `
  data(){
    return {
      favoriteMeal : "Pizza"
    }
  }
});

app.mount("#app")
  • 물론 위와같이 template을 직접 지정하여 사용하는 일을 거의 없을 것이다.

5. ref

  • react에 있는 개념과 굉장히 유사하다. react에선 ref를 굉장히 다양한 용도로 쓴다. input값을 가져올 때도 사용하고
    style을 바꾸거나 지정할 때도 사용한다.

  • 그리고 vue도 마찬가지로 input값을 key가 눌릴때마다 가져올 필요가 없는 경우에 사용한다.
    또 html 코드가 아니라서 브라우저는 이해를 못 하지만 vue는 이해할 수 있다.

  • 또 p, header, section 등 어느곳에서 ref 속성값을 넣을 수 있다.

  • Vue는 ref를 감지하고 내부에 이를 저장한다.

사용법

index.html

<input type="text" ref="userText">
<button @click="setText">Set Text</button>

app.js

...
	methods:{
      setText() {
        // this.message = this.currentUserInput;
        this.message = this.$refs.userText.value
        console.dir(this.$refs.userText);
      },
...
  • 내장 프로퍼티임을 표시하기 위해서 Vue가 지원하는 모든 프로퍼티는 $로 시작한다.

  • $ref는 2가지의 속성을 갖는데, 이는 키-쌍 값으로 이루어진 객체로 이때 키는 템플릿에 설정한 ref 식별자가 된다.

  • 이렇게 하면 해당 input 요소의 DOM 객체를 가리키는 것이 되고 DOM 요소에 액세스할 때 순수 JavaScript에서도 사용할 수 있는 JavaScript 객체가 된다.
    즉, 이렇게 전체 input 요소에 대한 액세스를 얻을 수 있다는 것이다.

  • 그래서 console.log가 아닌 console.dir을 찍어보면 해당 Input 요소에 있는 모든 프로퍼티를 JavaScript 객체로 표현한 것을 볼 수 있는데 그중 value 속성값이 있는 것을 확인할 수 있다.

  • 그리고 그것을 button을 클릭했을 때만 동작하게 만들어서 최종 값만 가져오는 식으로 만들었다. 이는 react 동작 방식과 같다.

6. render dom

  • 우선 vue는 vue app(vue instance)와 dom이 있다. 이때 html content는 브라우저에 의해 렌더링 된다.

  • 브라우저 DOM은 Vue가 제어하는 템플릿을 DOM에 렌더링 한다. 해당 템플릿의 콘텐츠가 DOM에 렌더링되는 것이다.

  • Vue가 제어하는 렌더링 프로세스 중에 동적 부분과 interpolation, 그리고 바인딩이 제거되며 실제 값이 삽입된다.

  • 그리고 Vue에 대한 지시 사항은 템플릿이 DOM에 렌더링되고 나면 Vue에 의해 삭제되기 때문에 브라우저에서 렌더링되는 실제 DOM에서는 확인할 수 없다.

  • 그리고 vue는 예전 dom과 최신 dom을 비교하여 차이가 있는 부분만 다시 렌더링 한다. 하지만 이때 모든 dom을 읽어들이는 것은 아니다. 왜냐하면 이렇게 읽어 들이는 것도 "expensive"한 작업이기 때문이다. 그래서 vue는 virtual dom을 사용한다.

  • virtual dom이란 실제 DOM의 가상 복사본인데 전적으로 JavaScript가 관리하므로 JS 기반 DOM이고 메모리에 위치한다.

  • 그리고 이는 비교하고 가상 DOM에 업데이트하는 작업을 전적으로 메모리에서 수행하기 때문에 화면 렌더링으로 이어지는 실제 DOM에서 해당 작업을 하는 것보다 훨씬 효율적이다.

profile
智(지)! 德(덕)! 體(체)!
post-custom-banner

0개의 댓글