에오니아 5와 Vue 입문

89463 단어 apivueionicandroid
이 프로젝트의 코드를 알고 싶으면 이 GitHub repo- Movie Vue 을 클릭하십시오
응용 프로그램 다운로드 - Download

소개하다.


자바스크립트는 과거에는 웹 페이지를 더욱 동적으로 만드는 방법일 뿐이었다. 지금은 서버 코드를 작성하고 데스크톱과 모바일 응용 프로그램까지 만들 수 있지만, 지금은 자바스크립트가 크게 발전했다.후자는 우리가 오늘 탐색할 내용으로 Ionic Vue.js 을 사용한다.
본 강좌에서 우리는 Ionic을 어떻게 사용하는지 중점적으로 배우고 당신이 Vue 개념의 기본 지식을 가지고 있다고 가정할 것입니다.만약 당신이 Vue을 배우고 싶다면 이 강좌를 읽으세요. Getting started with Vue and the GitHub API , 여기서 저는 Vue의 모든 기본 개념을 복습했습니다.

무엇이 이온입니까?


에오니아 팀:

Ionic is an open source mobile UI toolkit for building high quality, cross-platform native and web app experiences.


에오니아는 모바일 플랫폼에서 집처럼 보이는 UI 구성 요소를 제공할 것이며, 그 기능은 거의 모든 본체 응용 프로그램과 다를 것이 없다.
Ionic을 사용하면 Angular, React, Vue 또는 vanilla JavaScript 중에서 선택할 수 있습니다.그러나 모든 구성 요소가 모든 프레임에 적용되는 것은 아니므로 시작하기 전에 사용하고자 하는 모든 구성 요소를 보고 프레임에 적용되는지 확인하십시오.
Ionic을 사용하면 카메라에 접근하거나 모바일 서비스의 위치를 사용할 수 있습니다. 그러나 이 서비스는 기업판의 일부분입니다.

우리는 무엇을 짓고 있습니까?


현재 방영 중인 영화, 인기 영화, 최고급 영화, 곧 발매될 새 영화의 목록을 볼 수 있는 모바일 앱을 개발할 것이다.
애플리케이션 기능:
  • 의 슬라이드 메뉴로 방영 중인 영화, 핫한 영화, 개봉 예정인 영화나 가장 인기 있는 영화 목록을 볼 수 있다.
  • 각 영화는 배경 이미지, 제목, 영화의 평균 평점과 묘사가 있을 것이다.
  • 은 페이지 끝에 도달하면 새 컨텐트가 자동으로 로드됩니다.
  • 은 모든 페이지에서 아래로 미끄러져 새로 고침됩니다.
  • 지역별 영화 상영
  • 저희 영화를 얻으려면 TMDb api 을 사용하고, 저희 위치를 얻으려면 ip-api 을 사용하겠습니다.
    시작하기 전에 TMDb api의 API 키가 필요하므로 이 키를 가져와야 합니다.

    최종 결과



    설치 프로그램


    ionic cli 설치


    npm install -g @ionic/cli
    

    ionic 응용 프로그램 시작


    측면 메뉴를 사용하여 프로그램을 시작하고 선택한 프레임을 Vue로 설정합니다.
    ionic start MovieVue sidemenu --type vue
    

    현장 급유


    이 명령을 실행하면 코드를 작성할 때 변경 사항을 실시간으로 볼 수 있는 실시간 서버를 시작합니다.
    ionic serve
    
    페이지를 볼 때, 브라우저의 개발 도구를 사용하여 장치를 모바일 장치로 설정하면 실제 휴대전화의 외관을 더욱 진실하게 이해할 수 있습니다.

    비밀 번호


    서비스를 할 때, 당신의 응용 프로그램은 이렇게

    대부분의 코드 변경 사항은 ./src 폴더에 저장됩니다.강좌가 한 단계에서 다음 단계로 넘어가면, 나는 전체 코드를 보여주고, 이전에 변경된 줄에 주석을 추가할 것이다.그래서 만약 네가 순서대로 점진적이라면, 너는 이 노선들을 바꿀 수 있다

    반찬 정리


    우리가 해야 할 첫 번째 일은 반찬을 정리하는 것이다.우리는 사이드 메뉴의 네 부분만 있으면 모든 라벨을 제거할 수 있다../src/App.vue을 변경해야 합니다.
    템플릿과 스크립트만 수정하면 스타일이 변하지 않습니다.
    표시할 내용과 일치하도록 탭을 다시 명명해야 합니다.아이콘도 좀 안 맞아서 고치면서 하자.
    거푸집
    <template>
      <IonApp>
        <IonSplitPane content-id="main-content">
          <ion-menu content-id="main-content" type="overlay">
            <ion-content>
              <ion-list id="inbox-list">
                <!-- Change name to something more appropriate -->
                <ion-list-header>Movie Vue</ion-list-header>
                <ion-note>Discover movies</ion-note>
    
                <ion-menu-toggle auto-hide="false" v-for="(p, i) in appPages" :key="i">
                  <ion-item @click="selectedIndex = i" router-direction="root" 
                  :router-link="p.url" lines="none" detail="false" class="hydrated" 
                  :class="{ selected: selectedIndex === i }">
                    <ion-icon slot="start" :ios="p.iosIcon" :md="p.mdIcon"></ion-icon>
                    <ion-label>{{ p.title }}</ion-label>
                  </ion-item>
                </ion-menu-toggle>
              </ion-list>
              <!-- Remove Labels -->
            </ion-content>
          </ion-menu>
          <ion-router-outlet id="main-content"></ion-router-outlet>
        </IonSplitPane>
      </IonApp>
    </template>
    
    각본
    import { IonApp, IonContent, IonIcon, IonItem, IonLabel, IonList, IonListHeader, 
    IonMenu, IonMenuToggle, IonNote, IonRouterOutlet, IonSplitPane } from '@ionic/vue';
    import { defineComponent, ref } from 'vue';
    import { useRoute } from 'vue-router';
    // Update the icons
    import {  heartOutline, heartSharp, flashOutline, flashSharp, 
    diamondOutline, diamondSharp, rocketOutline, rocketSharp } from 'ionicons/icons';
    
    export default defineComponent({
      name: 'App',
      components: {
        IonApp, 
        IonContent, 
        IonIcon, 
        IonItem, 
        IonLabel, 
        IonList, 
        IonListHeader, 
        IonMenu, 
        IonMenuToggle, 
        IonNote, 
        IonRouterOutlet, 
        IonSplitPane,
      },
      setup() {
        const selectedIndex = ref(0);
        // Rename the tabs and update the icons
        const appPages = [
          {
            title: 'Now Playing',
            url: '/folder/Now Playing',
            iosIcon: flashOutline,
            mdIcon: flashSharp
          },
          {
            title: 'Popular',
            url: '/folder/Popular',
            iosIcon: heartOutline,
            mdIcon: heartSharp
          },
          {
            title: 'Top Rated',
            url: '/folder/Top Rated',
            iosIcon: diamondOutline,
            mdIcon: diamondSharp
          },
          {
            title: 'Upcoming',
            url: '/folder/Upcoming',
            iosIcon: rocketOutline,
            mdIcon: rocketSharp
          }
        ];
        // Remove Labels
    
        const path = window.location.pathname.split('folder/')[1];
        if (path !== undefined) {
          selectedIndex.value = appPages
          .findIndex(page => page.title.toLowerCase() === path.toLowerCase());
        }
    
        const route = useRoute();
    
        return { 
          selectedIndex,
          appPages,
          // Update the icons
          heartOutline,
          heartSharp,
          flashOutline,
          flashSharp,
          diamondOutline,
          diamondSharp,
          rocketOutline,
          rocketSharp,
          isSelected: (url: string) => url === route.path ? 'selected' : ''
        }
      }
    });
    
    기본 경로를 변경하려면 .src/router/index.ts의 스크립트를 업데이트해야 합니다.이것은 시작할 때 우리가 원하는 페이지를 열 수 있도록 합니다.
    import { createRouter, createWebHistory } from '@ionic/vue-router';
    import { RouteRecordRaw } from 'vue-router';
    
    const routes: Array<RouteRecordRaw> = [
      {
        path: '',
        // Change the default route
        redirect: '/folder/Now Playing'
      },
      {
        path: '/folder/:id',
        component: () => import ('../views/Folder.vue')
      }
    ]
    
    const router = createRouter({
      history: createWebHistory(process.env.BASE_URL),
      routes
    })
    
    export default router
    
    
    이런 변화 이후에는 마땅히 이와 같아야 한다

    기본 사용자 인터페이스


    Google 메인 사용자 인터페이스에서 모든 영화 정보를 포함하는 카드 구성 요소를 사용할 것입니다.
    새 파일 생성 ./src/MovieCard.vue
    <template>
        <ion-card>
            <!-- Movie poster at the top of the card -->
            <img :src="url" />
            <ion-card-header>
                <!-- Show the movie title, Average votes and description -->
                <ion-card-title>{{ movie.title }}</ion-card-title>
                <ion-card-subtitle
                    >Rating: {{ movie.vote_average }}
                    <ion-icon :icon="star"></ion-icon
                ></ion-card-subtitle>
            </ion-card-header>
    
            <ion-card-content>
                {{ movie.overview }}
            </ion-card-content>
        </ion-card>
    </template>
    
    <script>
    // Remove typescript
    import {
        IonCard,
        IonCardContent,
        IonCardSubtitle,
        IonCardTitle,
        IonIcon,
    } from "@ionic/vue";
    import { star } from "ionicons/icons";
    import { defineComponent } from "vue";
    
    export default defineComponent({
        components: {
            IonCard,
            IonCardContent,
            IonCardSubtitle,
            IonCardTitle,
            IonIcon,
        },
        // Movie props from the parent component
        props: ["movie"],
        setup() {
            return { star };
        },
        data() {
            return {
                // Use a placeholder in case there is no poster
                url:
                    this.movie.backdrop_path != null
                        ? "https://image.tmdb.org/t/p/original/" +
                          this.movie.backdrop_path
                        : "./assets/placeholder.jpg",
            };
        },
    });
    </script>
    

    영화 카드를 전시하다


    이제 각 탭의 영화 목록을 보려면 TMDb API를 조회해야 합니다.우리는 이 일을 완성하기 위해 axios가 필요하기 때문에, 우리는 계속하기 전에 그것을 설치할 것이다.
    npm i axios
    
    이 부분에서 모든 스타일을 삭제할 수 있습니다.그 밖에 우리는 여기서 typescript를 사용하지 않을 것이다. 왜냐하면 나는 그것을 무한 스크롤과 함께 일할 수 없기 때문이다. 우리는 이 강좌의 뒤에서 연구할 것이다../src/Folder.vue
    <template>
      <ion-page>
        <ion-header :translucent="true">
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-menu-button color="primary"></ion-menu-button>
            </ion-buttons>
            <ion-title>{{ $route.params.id }}</ion-title>
          </ion-toolbar>
        </ion-header>
    
        <ion-content :fullscreen="true">
          <ion-header collapse="condense">
            <ion-toolbar>
              <ion-title size="large">{{ $route.params.id }}</ion-title>
            </ion-toolbar>
          </ion-header>
    
          <div id="container">
            <!-- Loop over each movie -->
            <div v-for="movie in movies" :key="movie.id">
              <MovieCard v-bind:movie="movie"></MovieCard>
            </div>
          </div>
        </ion-content>
      </ion-page>
    </template>
    
    <script>
    // Remove typescript
    import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, 
    IonTitle, IonToolbar } from '@ionic/vue';
    
    import { ref } from "vue";
    // Install Axios and import the Movie card component we just made
    import MovieCard from "./MovieCard.vue";
    import axios from "axios";
    
    export default {
      name: 'Folder',
      components: {
        IonButtons,
        IonContent,
        IonHeader,
        IonMenuButton,
        IonPage,
        IonTitle,
        IonToolbar,
        // Add the MovieCard component
        MovieCard
      },
      data() {
        return {
          movies: ref([]),
          // Page to fetch
          pageNumber: 1,
          // Total number of pages present
          maxPages: 1,
          // Get the endpoint from the route parameter
          endpoint: this.$route.params.id
                    .toLowerCase()
                    .split(" ")
                    .join("_"),
          // Which Country the user is in
          country: "",
        };
      },
      methods: {
        async fetch(pageNumber) {
          // Get Movies corresponding to which tab is open, Now playing, Upcoming, etc
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          // Populate movie list
          this.movies = movies.data.results;
          // Increase page counter by 1
          this.pageNumber = movies.data.page + 1;
          // Get total number of pages in response
          this.maxPages = movies.data.total_pages;
        }
      },
      mounted() {
        // Fetch movies when mounted
        this.fetch(this.pageNumber);
      },
      watch: {
        $route(to, from) {
          // Trigger when the route changes. i.e. when user switches tabs
          this.endpoint = this.$route.params.id
              .toLowerCase()
              .split(" ")
              .join("_");
          this.pageNumber = 1;
          this.maxPages = 1;
    
          // Fetch movies when route changes
          this.fetch(this.pageNumber);
        }
      }
    }
    </script>
    
    <style scoped>
    /* Remove styles */
    </style>
    
    이러한 변경을 수행한 후에는 다음을 수행해야 합니다.

    무한 스크롤


    현재 우리는 이미 기본적인 사용자 인터페이스를 구축했기 때문에 우리는 생활의 질 개선에 전념할 수 있다.TMDb api를 조회하면, 모든 종류의 영화 총수의 서브집합을 얻을 수 있습니다.그것은 단지 한 페이지이기 때문이다.영화 목록은 몇 페이지로 나뉘는데, 이것은 우리에게 매우 좋다. 왜냐하면 한 번에 이렇게 많은 데이터를 불러오는 데 시간이 오래 걸리기 때문이다.
    그러나 사용자는 영화 목록에 다른 내용이 없을 때까지 점차적으로 더 많은 내용을 볼 수 있는 방법이 있어야 한다.이를 위해 무한 스크롤을 설정합니다.
    기본적으로 사용자가 지금까지 로드한 컨텐트의 끝에 도달하면 다음 페이지의 요청을 API에 전송하여 목록에 추가합니다.
    다행히도, 에오니아 회사에는 이 목적을 위한 부품이 하나 있다../src/Folder.vue년.
    <template>
      <ion-page>
        <ion-header :translucent="true">
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-menu-button color="primary"></ion-menu-button>
            </ion-buttons>
            <ion-title>{{ $route.params.id }}</ion-title>
          </ion-toolbar>
        </ion-header>
    
        <ion-content :fullscreen="true">
          <ion-header collapse="condense">
            <ion-toolbar>
              <ion-title size="large">{{ $route.params.id }}</ion-title>
            </ion-toolbar>
          </ion-header>
    
          <div id="container">
            <div v-for="movie in movies" :key="movie.id">
              <MovieCard v-bind:movie="movie"></MovieCard>
            </div>
          </div>
          <!-- Add the infinite scroll component and call loadData -->
          <ion-infinite-scroll
              @ionInfinite="loadData($event)"
              threshold="100px"
              id="infinite-scroll"
              :disabled="isDisabled">
              <ion-infinite-scroll-content
                  loading-spinner="bubbles"
                  loading-text="Loading more movies...">
              </ion-infinite-scroll-content>
          </ion-infinite-scroll>
        </ion-content>
      </ion-page>
    </template>
    
    <script>
    // Import the components
    import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, IonTitle, IonToolbar, 
    IonInfiniteScroll, IonInfiniteScrollContent, } from '@ionic/vue';
    
    import { ref } from "vue";
    import MovieCard from "./MovieCard.vue";
    import axios from "axios";
    
    export default {
      name: 'Folder',
      components: {
        IonButtons,
        IonContent,
        IonHeader,
        IonMenuButton,
        IonPage,
        IonTitle,
        IonToolbar,
        MovieCard,
        // Add the infinite scroll components
        IonInfiniteScroll,
        IonInfiniteScrollContent,
      },
      data() {
        return {
          movies: ref([]),
          pageNumber: 1,
          maxPages: 1,
          endpoint: this.$route.params.id
                    .toLowerCase()
                    .split(" ")
                    .join("_"),
          country: "",
        };
      },
      methods: {
        async fetch(pageNumber) {
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          this.movies = movies.data.results;
          this.pageNumber = movies.data.page + 1;
          this.maxPages = movies.data.total_pages;
        },
        async pushData(pageNumber) {
          // Get the next page
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          // Add movies to current list
          this.movies = this.movies.concat(movies.data.results);
          this.pageNumber = movies.data.page + 1;
          this.maxPages = movies.data.total_pages;
        },
        async loadData(ev) {
          // Load the new data once we reach the end of the page
          const res = await this.pushData(this.pageNumber);
          console.log("Loaded data");
          console.log(res);
          ev.target.complete();
    
          // Once the last page has been fetched, we'll disable infinite loading
          if (this.pageNumber >= this.maxPages) {
              ev.target.disabled = true;
          }
        },
      },
      mounted() {
        this.fetch(this.pageNumber);
      },
      watch: {
        $route(to, from) {
          // Trigger when the route changes. i.e. when user switches tabs
          this.endpoint = this.$route.params.id
              .toLowerCase()
              .split(" ")
              .join("_");
          this.pageNumber = 1;
          this.maxPages = 1;
    
          // Fetch movies when route changes
          this.fetch(this.pageNumber);
        }
      }
    }
    </script>
    
    <style scoped>
    </style>
    
    네가 이런 변화를 한 후에 너는 반드시 이런 물건을 보게 될 것이다

    아래로 미끄러져 다시 불러오기


    대부분의 모바일 프로그램의 또 다른 흔한 기능은 아래로 미끄러질 때 내용을 새로 고칠 수 있다는 것이다.이것은 업데이트 내용을 얻는 간단하고 직관적인 제스처이기 때문에 매우 유용하다.
    에오니아에게도 우리가 이 문제를 해결할 수 있는 부품이 있다는 것을 몰랐단 말인가!./src/Folder.vue년.
    <template>
      <ion-page>
        <ion-header :translucent="true">
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-menu-button color="primary"></ion-menu-button>
            </ion-buttons>
            <ion-title>{{ $route.params.id }}</ion-title>
          </ion-toolbar>
        </ion-header>
    
        <ion-content :fullscreen="true">
          <!-- Add refresher component -->
          <ion-refresher slot="fixed" @ionRefresh="doRefresh($event)">
            <ion-refresher-content></ion-refresher-content>
          </ion-refresher>
          <ion-header collapse="condense">
            <ion-toolbar>
              <ion-title size="large">{{ $route.params.id }}</ion-title>
            </ion-toolbar>
          </ion-header>
    
          <div id="container">
            <div v-for="movie in movies" :key="movie.id">
              <MovieCard v-bind:movie="movie"></MovieCard>
            </div>
          </div>
          <ion-infinite-scroll
              @ionInfinite="loadData($event)"
              threshold="100px"
              id="infinite-scroll"
              :disabled="isDisabled">
              <ion-infinite-scroll-content
                  loading-spinner="bubbles"
                  loading-text="Loading more movies...">
              </ion-infinite-scroll-content>
          </ion-infinite-scroll>
        </ion-content>
      </ion-page>
    </template>
    
    <script>
    // Import the components
    import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, IonTitle, IonToolbar, 
    IonInfiniteScroll, IonInfiniteScrollContent, IonRefresher, IonRefresherContent, } from '@ionic/vue';
    
    import { ref } from "vue";
    import MovieCard from "./MovieCard.vue";
    import axios from "axios";
    
    export default {
      name: 'Folder',
      components: {
        IonButtons,
        IonContent,
        IonHeader,
        IonMenuButton,
        IonPage,
        IonTitle,
        IonToolbar,
        MovieCard,
        IonInfiniteScroll,
        IonInfiniteScrollContent,
        // Add the refresher components
        IonRefresher,
        IonRefresherContent,
      },
      data() {
        return {
          movies: ref([]),
          pageNumber: 1,
          maxPages: 1,
          endpoint: this.$route.params.id
                    .toLowerCase()
                    .split(" ")
                    .join("_"),
          country: "",
        };
      },
      methods: {
        async fetch(pageNumber) {
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          this.movies = movies.data.results;
          this.pageNumber = movies.data.page + 1;
          this.maxPages = movies.data.total_pages;
        },
        async pushData(pageNumber) {
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          this.movies = this.movies.concat(movies.data.results);
          this.pageNumber = movies.data.page + 1;
          this.maxPages = movies.data.total_pages;
        },
        async loadData(ev) {
          const res = await this.pushData(this.pageNumber);
          console.log("Loaded data");
          console.log(res);
          console.log(this.pageNumber);
          ev.target.complete();
          if (this.pageNumber >= this.maxPages) {
              ev.target.disabled = true;
          }
        },
        async doRefresh(event) {
          // Get the movies from the first page again
          const res = await this.fetch(1);
          console.log(res);
          event.target.complete();
        },
      },
      mounted() {
        this.fetch(this.pageNumber);
      },
      watch: {
        $route(to, from) {
          this.endpoint = this.$route.params.id
              .toLowerCase()
              .split(" ")
              .join("_");
          this.pageNumber = 1;
          this.maxPages = 1;
    
          this.fetch(this.pageNumber);
        }
      }
    }
    </script>
    
    <style scoped>
    </style>
    
    네가 위에서 아래로 당길 때, 너는 아래의 그림을 볼 수 있을 것이다.게시할 때 페이지의 내용이 새로 고쳐져야 합니다.

    탭 변경 시 맨 위로 스크롤


    만약 당신이 지금 응용 프로그램과 상호작용을 하고 있다면, 아마도 이미 뭔가를 알아차렸을 것이다.예를 들어 Popular을 아래로 스크롤한 다음 다른 탭으로 전환합니다. 예를 들어 Upcoming을 스크롤 바가 같은 위치에 있습니다.이것은 이상한 사용자 체험을 가져올 것이다. 이상적인 상황에서 우리는 옵션카드를 전환할 때 자동으로 맨 위로 굴러가기를 바란다. 그러면 우리는 페이지의 무작위 위치가 아니라 처음부터 영화 목록을 볼 수 있기를 바란다../src/Folder.vue년.
    <template>
      <ion-page>
        <ion-header :translucent="true">
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-menu-button color="primary"></ion-menu-button>
            </ion-buttons>
            <ion-title>{{ $route.params.id }}</ion-title>
          </ion-toolbar>
        </ion-header>
    
        <!-- Enable scroll events and create a ref -->
        <ion-content :fullscreen="true" scrollEvents ref="content">
          <ion-refresher slot="fixed" @ionRefresh="doRefresh($event)">
            <ion-refresher-content></ion-refresher-content>
          </ion-refresher>
          <ion-header collapse="condense">
            <ion-toolbar>
              <ion-title size="large">{{ $route.params.id }}</ion-title>
            </ion-toolbar>
          </ion-header>
    
          <div id="container">
            <div v-for="movie in movies" :key="movie.id">
              <MovieCard v-bind:movie="movie"></MovieCard>
            </div>
          </div>
          <ion-infinite-scroll
              @ionInfinite="loadData($event)"
              threshold="100px"
              id="infinite-scroll"
              :disabled="isDisabled">
              <ion-infinite-scroll-content
                  loading-spinner="bubbles"
                  loading-text="Loading more movies...">
              </ion-infinite-scroll-content>
          </ion-infinite-scroll>
        </ion-content>
      </ion-page>
    </template>
    
    <script>
    import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, IonTitle, IonToolbar, 
    IonInfiniteScroll, IonInfiniteScrollContent, IonRefresher, IonRefresherContent, } from '@ionic/vue';
    
    import { ref } from "vue";
    import MovieCard from "./MovieCard.vue";
    import axios from "axios";
    
    export default {
      name: 'Folder',
      components: {
        IonButtons,
        IonContent,
        IonHeader,
        IonMenuButton,
        IonPage,
        IonTitle,
        IonToolbar,
        MovieCard,
        IonInfiniteScroll,
        IonInfiniteScrollContent,
        IonRefresher,
        IonRefresherContent,
      },
      data() {
        return {
          movies: ref([]),
          pageNumber: 1,
          maxPages: 1,
          endpoint: this.$route.params.id
                    .toLowerCase()
                    .split(" ")
                    .join("_"),
          country: "",
        };
      },
      methods: {
        async fetch(pageNumber) {
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          this.movies = movies.data.results;
          this.pageNumber = movies.data.page + 1;
          this.maxPages = movies.data.total_pages;
        },
        async pushData(pageNumber) {
          const movies = await axios.get(
              "https://api.themoviedb.org/3/movie/" +
                  this.endpoint +
                  "?api_key=<Your API KEY here>&language=en-US&page=" +
                  pageNumber +
                  "&region=" +
                  this.country
          );
          this.movies = this.movies.concat(movies.data.results);
          this.pageNumber = movies.data.page + 1;
          this.maxPages = movies.data.total_pages;
        },
        async loadData(ev) {
          const res = await this.pushData(this.pageNumber);
          console.log("Loaded data");
          console.log(res);
          console.log(this.pageNumber);
          ev.target.complete();
          if (this.pageNumber >= this.maxPages) {
              ev.target.disabled = true;
          }
        },
        async doRefresh(event) {
          const res = await this.fetch(1);
          console.log(res);
          event.target.complete();
        },
      },
      mounted() {
        this.fetch(this.pageNumber);
      },
      watch: {
        $route(to, from) {
          this.endpoint = this.$route.params.id
              .toLowerCase()
              .split(" ")
              .join("_");
          this.pageNumber = 1;
          this.maxPages = 1;
    
          this.fetch(this.pageNumber);
          // Scroll to top when the tab changes
          this.scrollToTop();
        }
      },
        setup() {
          // Get ref to content
          const content = ref();
    
          // Add function to scroll to top
          return {
            content,
            scrollToTop: () => content.value.$el.scrollToTop(),
          };
        },
    }
    </script>
    
    <style scoped>
    </style>
    

    결론


    만약 지금까지 당신이 계속 관심을 가지고 있다면, 축하합니다. 당신은 이미 성공적으로 Ionic 응용 프로그램을 만들었습니다."그런데 잠깐만, 이거 Android에서 운행해야 되는 거 아니야?",나는 네가 말하는 것을 들었다.네가 옳다. 우리는 이미 우리의 인터넷 브라우저에서 휴대전화를 위한 앱을 실행했다. 이 앱을 진정한 안드로이드 휴대전화에 설치하려면 몇 가지 절차가 필요하다.
    이 절차는 이 자습서 Building and deploying Ionic apps 의 다음 섹션에서 설명합니다.
    이 강좌의 전체 코드를 원하시면 여기를 클릭하십시오: MovieVue

    좋은 웹페이지 즐겨찾기