본문 바로가기

배워서 따라하는 포플/영화 검색 사이트

영화 포스트 로드 이벤트, 예외처리, Nav 경로 일치 및 활성화

이미지 로드 이벤트(Vue 플러그인)

MovieItem.vue의 template과 script 추가부분입니다.

영화 검색했을 때 포스터가 로딩될 때까지 로드 애니메이션을 사용할 겁니다.

 

methods를 플러그인 방식으로 관리할 겁니다.

export default {
  install(app) {
    app.config.globalProperties.$loadImage = (src) => {
      return new Promise((resolve) => {
        const img = document.createElement('img')
        img.src = src
        img.addEventListener('load', () => {
          // 완료
          resolve()
        })
      })
    }
  }
}

src폴더 안에 plugins폴더를 만들고 안에 loadImage.js의 내용입니다.

main.js에 loadImage 플러그인을 등록합니다.

 

methods: {
  async init() {
    await this.$loadImage(this.movie.Poster)
    this.imageLoading = false
  }
}

MovieItems.vue의 methods부분을 플러그인을 적용합니다.

 

단일 영화의 포스터를 loading할때도 애니매이션을 적용할 예정입니다.

<div 
  :style="{backgroundImage:`url(${requiestDiffSizeImage(theMovie.Poster)})`}"
  class="poster">
  <Loader
    v-if="imageLoading"
    absolute />
</div>

Movie.vue의 poster부분에 loader추가합니다.

Movie.vue의 script부분에 data를 명시해주고 methods를 수정합니다.

여기서 await를 사용하면 loading애니메이션이 끝나야 poster 나타납니다.

이런 경우를 방지하기 위해 then()메소드를 사용합니다.

 

영화 포스터가 없는 경우 예외 처리

methods: {
  async init() {
    const poster = this.movie.Poster
    if(!poster || poster === 'N/A') {
      this.imageLoading = false
    }else{
      await this.$loadImage(poster)
      this.imageLoading = false
    }
  }
}

MovieItems.vue의 methods부분을 수정했습니다.

만약에 poster이 없거나 N/A가 반환된 경우, loading 애니메이션 즉시 중지 시킵니다.

 

methods: {
  requiestDiffSizeImage(url, size = 700) {
    if(!url || url === 'N/A') {
      this.imageLoading = false
      return ''
    }
    const src = url.replace('SX300', `SX${size}`)
    this
      .$loadImage(src)
      .then(() => {
        this.imageLoading = false
      })
    return src
  }
}

Movie.vue의 methods부분도 같이 수정합니다.

만약에 url이 없거나 N/A가 반환된 경우, loading이 false를 해서 애니매이션을 중지 시키고 빈 문자열을 반환해줍니다.

 

Nav 경로 일치 및 활성화

MovieItem.vue파일에 movie클래스를 기존에 div였는데 RouterLink로 변경해서 a태그처럼 사용할 것입니다.

to로 바인딩해서 지정된 id인 페이지로 이동합니다.

 

Header.vue의 data중 movie부분 path를 추가했습니다. /movie 포함한 모든 path입니다.

 

methods부분에 isMatch메소드를 만듭니다.

만약에 path에 /movie포함되어 있지 않으면 false를 반환하고, 포함되면 fullPath를 반환합니다.

여기서 fullPath는 API에서 제공하고 있는 /movie/imdbID입니다.

 

Header.vue의 template부분 RouterLink부분입니다.

isMatch메소드의 반환값으로 해당 요소의 active값이 추가여부를 결정합니다.