생계유지형 개발자/JS Framework

[Vue] Vue CDN으로 사용 시 this가 window를 가르킬 때

이 가을 2021. 3. 24. 16:28

Vue 프로젝트가 아닌 html에서 CDN 방식으로 사용할 때 종종 this.데이터 또는 this.메소드가 동작하지 않을 때가 있다.

this가 vue가 아닌 전역 글로벌 객체인 window를 가르킬 때 이다.

특히 자주 쓰이는 axios 비동기 호출을 한 후 콜백처리할 때 this를 사용해도 vue가 동작하지 않는 것이 대표적이다.

 

아래 샘플코드처럼 getMyList 메소드 내에서 this는 vue를 가르키지만, axios.then() 콜백함수의 this는 window를 가르킨다.

new Vue({
  el: '#container',
  data: {
    mylist: []
  },
  methods: {
    getMyList() {
      this.mylist = Array()	// this -> vue
      axios.get("/v1/api/list").then(res => {
        this.mylist = res.data	// this -> window
      })
    }
  }
})

 

Vue 인스턴스를 변수에 할당하지 않고 초기화하는 것만으로도 Vue가 적용되지만, 위와 같은 경우가 발생하기 때문에 인스턴스를 변수에 할당해서 아래처럼 사용한다.

// vi : Vue Instance

var vi = new Vue({
  el: '#container',
  data: {
    mylist: []
  },
  methods: {
    getMyList() {
      vi.mylist = Array()		// this -> vue
      axios.get("/v1/api/list").then(res => {
        vi.mylist = res.data		// Replace 'this' to 'vi'
      })
    }
  },
  mounted() {
    // 'this' is equals to vue but, not 'vi' 
    // 'vi' is undefined in this moment 
    this.getMyRooms()	
	
  }
})

 

그런데 문제가 하나 있다.

화면이 로드되고 Vue 라이프사이클 중 mounted 시점에서 getMyList()를 호출하면 이 때 vue는 undefined 이다.

모든 라이프사이클 실행이 끝나야만 Vue객체가 var vue에 할당이 되나보다.

그래서 mounted() { this.getMyRooms() } 코드를 넣으면, getMyList() 함수 내에 있는 vue.mylist 라인에서 에러가 발생한다.

대안이 있는지 모르겠지만 나는 Vue 초기화 후 메소드를 호출해주는 방식으로 했다.

var vi = new Vue({
...
})
vi.getMyList()

 

 

참고

nykim.work/73

 

[Vue] 기초 스터디

이 글은 Vue.js 시작하기 - Age of Vue.js 강의를 보고 작성한 노트 필기입니다. 뷰는 1도 모르지만 친해지고 싶은 사람이 공부를 위해 작성한 글입니다 :-9 필요할 때마다 수정/보완해 나갈 예정입니다

nykim.work