[TIL # 26] Vue 1일차

Yejin Yang·2022년 5월 16일
0

[TIL]

목록 보기
26/69
post-thumbnail

Vue.js

Vue는 사용자 인터페이스를 만들기 위한 프로그레시브 프레임워크 이다.

시작하기

// 컴포넌트
const App = {
  // data 옵션은 함수여야한다.
  // 콜론 function 생략
  
  data() {
    return {
      // title이라는 데이터를 정의한 것
      title: '',
    };
  },
  methods: {
    //  methods에는 this키워드 써야해서 일반함수로 사용해야함, 화살표함수 (x)
  },
};
Vue.createApp(App).mount('#app');

v-bind

  • 약칭: :
<input v-bind:value="title" />
  • v-bind를 입력하면 이제 title은 글자가 아니라 데이터가된다. (위에서 정의한 Vue.js쪽 데이터 이름이 되는 것)

  • Vue.js로 정의한 데이터는 반응형 데이터라고 부르거나 반응성을 가진 데이터라고 부른다.

v-on

  • 약칭 : @
<button v-on:click="changeTitle">Click!</button>
  • 자바스크립트의 addEventListener랑 같다.
  • “” 에 실행할 함수를 써준다.
  • changeTitle은 함수다. 이 함수는 methods: 부분에 정의하면 된다.
// 컴포넌트
const App = {
  data() {
    return {
      // 타이틀이라는 데이터
      title: '',
    };
  },
  methods: {
    changeTitle() {
      this.title = 'YEJIN!'
    }
  },
};
Vue.createApp(App).mount('#app');
  • 위에 title과 아래 title이 동일하다는 것을 알려주기 위해 this 키워드 작성한다.

영화 검색 기능 구현해보기

영화 제목 가져오기

  1. 영화 제목을 input으로 받는다
  2. 버튼을 클릭하면 데이터를 받아온다.
  3. 데이터를 받아 줄 반응형데이터를 지정한다.

JS

const App = {
  data() {
    return {
      title: '',
      // 데이터를 받아 줄 반응형데이터(movies)를 지정
      movies: [],
    };
  },
  methods: {
    async searchMovies() {
      let res = await fetch(
        `https://www.omdbapi.com/?apikey=${API_KEY}=${this.title}&page=1`
      );
      res = await res.json();
      console.log(res);
      // 1. 받은 데이터를 꺼낸다.
      const { Search, totalResults } = res
      // 2. 할당해준다. movies는 빈 배열이였지만 Search라는 10개 데이터를 가진 배열이 됨 
      this.movies = Search
    },
  },
};
Vue.createApp(App).mount('#app');

HTML

화면에 출력하기 위한 코드

<div id="app">
      <input v-model="title" />
      <button v-on:click="searchMovies">Search!</button>
      <ul>
        <li v-for="movie in movies">{{ movie.Title }}</li>
      </ul>
  • 사용자가 입력한 데이터를 통해서 실제로 반응형데이터로 만드는 것을 양방향 데이터 바인딩이라고 한다.
  • 기본적으로는 단방향이지만, 특수한 경우(사용자입력값⇒ 실제데이터 갱신) 양방향을 쓰는데 그때 쓰는 대표적인게 v-model이다.
  • v-for 를 이용해서 배열데이터 movies를 화면에 출력한다.
  • in 키워드 앞에는 내가 원하는 변수명을 쓸 수 있다.
  • {{ }} 로 출력

포스터 가져오기

      <ul>
        <li v-for="movie in movies" :key="movie.id">
          <img :src="movie.poster" alt="" height="40" />
          {{ movie.Title }}
        </li>
      </ul>
  • img 태그 추가
  • v-bind를 써줘야 반응형 데이터가 된다.
    - 약어 : 사용

영화 정보 더 가져오기

HTML

<button v-on:click="searchMoviesMore">More..</button>

JS - searchMoviesMore 메소드 정의 하기

const App = {
  data() {
    return {
      title: '',
      page: 1,
      movies: [],
    };
  },
  methods: {
    // 최초 요청 최초의 10개
    async searchMovies() {
      // 최초라서 페이지를 1로 초기화해주고
      this.page = 1;
      let res = await fetch(
        `https://www.omdbapi.com/?apikey=${API_KEY}&s=${this.title}&page=${this.page}`
      );
      res = await res.json();
      console.log(res);
      const { Search, totalResults } = res;
      this.movies = Search;
      // 1에서 2로 올라간 다음 아래 코드가 실행
      this.page = 2;
    },
    // 페이지를 더 가져오는 함수
    async searchMoviesMore() {
      let res = await fetch(
        `https://www.omdbapi.com/?apikey=${API_KEY}&s=${this.title}&page=${this.page}`
      );
      res = await res.json();
      console.log(res);
      const { Search, totalResults } = res;
      // 최초배열의 뒤에 새로운 데이터를 push로 밀어넣어준다.
      // Search는 배열데이터, 전개 연산자 사용해서 내용물만 사용
      this.movies.push(...Search);
      // 페이지가 1씩 증가, 결국 3이 됨
      // 3에서 버튼을 누르면 다시 1로 초기화 하는 로직
      this.page += 1;
    },
  },
};
Vue.createApp(App).mount('#app');

[More..] 버튼 숨기기

More 버튼은 최초 검색이 일어난 이후에 나오게 해야한다.
Movies 배열이 비어져 있으면 More 버튼이 보일 필요가 없다.
배열에 item이 몇개 있는지 length 메소드를 활용한다.

<button v-if="movies.length > 0"v-on:click="searchMoviesMore">More..</button>

<!-- > 0 는 굳이 안 적어도 된다. 1이상은 전부다 truthy. 값이 없으면 어차피 0 -->

즉, length가 0보다 클 때만 렌더링 해주세요!

v-if는 디렉티브의 표현식이 true 값을 반환할 때만 렌더링된다.

엔터키로 검색 가능하게 하기

<input v-model="title" v-on:keydown.enter="searchMovies(true)" />

v-on:keydown.enter 사용


리팩토링 하기

const App = {
  data() {
    return {
      title: '',
      page: 1,
      movies: [],
    };
  },
  methods: {
    // 최초 요청 최초의 10개
    async searchMovies() {
      // 최초라서 페이지를 1로 초기화해주고
      this.page = 1;
      let res = await fetch(
        `https://www.omdbapi.com/?apikey=${API_KEY}&s=${this.title}&page=${this.page}`
      );
      res = await res.json();
      console.log(res);
      const { Search, totalResults } = res;
      this.movies = Search;
      // 1에서 2로 올라간 다음 아래 코드가 실행
      this.page = 2;
    },
    // 페이지를 더 가져오는 함수
    async searchMoviesMore() {
      let res = await fetch(
        `https://www.omdbapi.com/?apikey=${API_KEY}&s=${this.title}&page=${this.page}`
      );
      res = await res.json();
      console.log(res);
      const { Search, totalResults } = res;
      // 최초배열의 뒤에 새로운 데이터를 push로 밀어넣어준다.
      // Search는 배열데이터, 전개 연산자 사용해서 내용물만 사용
      this.movies.push(...Search);
      // 페이지가 1씩 증가, 결국 3이 됨
      // 3에서 버튼을 누르면 다시 1로 초기화 하는 로직
      this.page += 1;
    },
  },
};
Vue.createApp(App).mount('#app');

현재 searchMovies() searchMoviesMore() 해당 함수들에 로직이 같은 부분이 있다. 단일 함수로 사용하는것이 중요하다.

목표: searchMovies 함수에 합치기

<div id="app">
      <input v-model="title" />
      <button v-on:click="searchMovies(true)">Search!</button>
      <ul>
        <li v-for="movie in movies">
          <img v-bind:src="movie.Poster" alt="" height="40" />
          {{ movie.Title }}
        </li>
      </ul>
      <button v-if="movies.length" v-on:click="searchMovies()">More..</button>
    </div>
  • v-on:click에 메소드 연결하면서 실행()을 따로 걸 수 있다.
  • Search! 버튼을 클릭하는 것엔 true 넣어 주고 More 버튼을 클릭은 아무것도 넣지 않는다.

리팩토링 후

const App = {
  data() {
    return {
      title: '',
      page: 1,
      movies: [],
    };
  },
  methods: {
    // 최초 요청 최초의 10개
    // isFirst라는 매개변수를 지정 → 최초 검색인지 아닌지를 판단
    // isFirst에는 truthy가 들어와야 최초 검색이됨
    async searchMovies(isFirst) {
      if (isFirst) {
        // 최초 검색일 때 빈배열로 초기화하라
        // 최초 검색일 때 페이지를 1로 초기화하라
        this.movies = [];
        this.page = 1;
      }
      let res = await fetch(
        `https://www.omdbapi.com/?=apikey=${API_KEY}&s=${this.title}&page=${this.page}`
      );
      res = await res.json();
      console.log(res);
      const { Search, totalResults } = res;
      this.movies.push(...Search);
      this.page += 1;
    },
  },
};
Vue.createApp(App).mount('#app');

회고

오늘은 문법보다 뷰가 어떻게 동작하는지 흐름을 알기 위해 영화 검색 API를 활용해서 화면에 출력하는 것을 해봤다. 현재 영화 검색 과제를 바닐라 자바스크립트로 구현하고 있는데, 같은 것을 뷰로 구현해보니 왜 프레임워크를 쓰는지 확실히 알았고 코드가 간편해졌다! 정말 좋은 친구였어.. 쀼야 친해지자..🥹

profile
Frontend developer

0개의 댓글