使用typescript+vue 編寫電影資訊小專案!

MartinYin發表於2018-10-14

前言:

為什麼要編寫這篇文章?一是對自己技術的磨練,二是給大家分享如何使用vue+typescript開發專案。

大佬就不要噴我的程式碼了。主要面向技術一般般的同學,沒有寫過typescript。當然我技術也是一般般。

github程式碼已經更新完成,如果覺得我廢話可以直接去gayhub地址

專案截圖

使用typescript+vue 編寫電影資訊小專案!

使用typescript+vue 編寫電影資訊小專案!

使用typescript+vue 編寫電影資訊小專案!

使用typescript+vue 編寫電影資訊小專案!

正文:

我假設你已經熟練應用過vue全家桶(vue+router+vuex+axios[‘黑人問號臉?’])

另外先泡一杯咖啡!

在這裡我也不教你如何配置環境了直接開始正題,let's go!

第一階段配置專案並啟動

當前開發版本:

使用typescript+vue 編寫電影資訊小專案!

vue create projectName  //projectName 是指你的專案名稱
複製程式碼

這裡可以選擇預設模板和和自己配置。

使用typescript+vue 編寫電影資訊小專案!

這裡我選擇的是第二個,然後又讓你選擇……

使用typescript+vue 編寫電影資訊小專案!

這裡的選擇可以按數字鍵選擇的

  • Babel =====> 1
  • TyepScript ====> 2

以次類推,所以你懂我意思吧

這裡選擇我們需要的幾個東東,然後愉快的回車把,喝一會咖啡等待專案安裝完成。

使用typescript+vue 編寫電影資訊小專案!

安裝完成之後我們先看下檔案目錄

使用typescript+vue 編寫電影資訊小專案!
細心的同學肯定發現了少了 build 和config 資料夾。那麼如果我配置webpack 怎麼辦?

新建一個 vue.config.js 不明白的同學可以點選這裡

那麼開始安裝我們需要的一些依賴!

    npm i vant -S                             // ui框架
    npm i babel-plugin-import -D              // 使用 babel-plugin-import 
    npm install --save-dev sass-loader        // sass
    npm install --save-dev node-sass          // sass-loader依賴於node-sass
    npm install --save vuex-class             // 更方便使用vuex
    npm i axios -S                            // axios
複製程式碼

最後幾步

在配置檔案babel.config.js 中加上:

      "plugins": [
      ["import", {
        "libraryName": "vant",
        "libraryDirectory": "es",
        "style": true
        }]
      ]
複製程式碼

刪除已經無用的about.vue

在components中新建Header.vue 並寫入程式碼

   <template>
     <div class="header">
       <van-nav-bar
         title="首頁"
       />
     </div>
   </template>
   <script lang="ts">
   import { Component, Prop, Vue } from 'vue-property-decorator';
   import { NavBar } from 'vant';
   @Component({
     components: {
       [NavBar.name]: NavBar,
     },
   })
   export default class Header extends Vue {
   }
   </script>
   <style scoped>
   </style>
複製程式碼

App.vue的標籤後面寫入

    <script lang="ts">
        import { Component, Vue } from 'vue-property-decorator';
        import { NavBar } from 'vant';
        import Header from '@/components/Header.vue'; 
        @Component({
          components: {
            Header
          },
        })
        export default class App extends Vue {
        }
    </script>
複製程式碼

刪除Home.vue的程式碼,寫入

    <template>
      <div class="home">
        <p>第一個vue+typescript應用</p>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    export default class Home extends Vue {}
    </script>
複製程式碼

應該是編輯器的bug,有些程式碼會提示bug,不過我們視終端和瀏覽器控制檯的報錯才是真正的報錯!

在控制檯輸入npm run serve

使用typescript+vue 編寫電影資訊小專案!


第二階段 封裝axios 和 使用vuex

在scr目錄下新建utils和store兩個資料夾

utils新建立request.ts

import * as axios from 'axios';
import store from '@/store';
import { Toast } from 'vant';
import { AxiosResponse, AxiosRequestConfig } from 'axios';

const baseURL = 'https://api.douban.com/v2/movie/';
const service = axios.default.create({
    baseURL,
    timeout: 0,
    maxContentLength: 4000,
});

service.interceptors.request.use((config: AxiosRequestConfig) => {
    return config;
}, (error: any) => {
    Promise.reject(error);
});

service.interceptors.response.use(
    (response: AxiosResponse) => {
        if (response.status !== 200) {
            Toast.fail('請求錯誤!');
        } else {
            return response.data;
        }
    },
    (error: any) => {
        return Promise.reject(error);
    });
    
export default service;
複製程式碼

新建ajax.ts

export interface AjaxResponse {
    code: number;
    data: any;
    message: string;
}
複製程式碼

axios 簡單封裝完成。

vue.config 跨域設定 vue官網webpack配置

    module.exports = {
      configureWebpack: config => {
      },
      devServer: {
        proxy: {
          '/api': {
            target: 'http://api.douban.com/v2',
            changeOrigin: true,
            ws: true,
            pathRewrite: {             //一定要加上這個!!!!不然不能跨域,親身體驗!
              '^/api': ''
            }
          }
        }
      }
    }
複製程式碼

store 介面型別為了方便複用全部寫在store/interface.ts, 每個view元件對應一個資料夾。

store/home/index.ts

import { State } from '@/store/interface';
import { Commit } from 'vuex';
import { getMovieList } from '@/api/home';

const state: State = {
    movieList: [],
};

const getters = {
    // tslint:disable-next-line:no-shadowed-variable
    movieList: (state: State) => state.movieList,
};

const mutations = {
};

const actions = {
    async movieList(context: { commit: Commit }, cate: string) {
        const res: any = await getMovieList(cate)
                            .then( (response: any ) => response)
                            // tslint:disable-next-line:no-console
                            .catch((e: string) => console.error(e));
        return res;
    },
};

export default {
    state,
    getters,
    mutations,
    actions,
};
複製程式碼

http請求程式碼則放在src/api下,同樣的每一個view元件對應一個檔案。

home.ts

import request from '@/utils/request';

// tslint:disable-next-line:only-arrow-functions
export const getMovieList = function(cate: string) {
    return request({
        url: '/api/movie/' + cate ,
        method: 'GET',
    });
};

複製程式碼

第三階段 首頁編寫

如何在vuex中使用 點選此處

home.vue

<template>
  <div class="home">
    <van-tabs v-model="active">
      <van-tab title="正在熱映">
        <div id="listMovieBox">
        <div class="item" v-for="(item, index) in movieListData"  :key = 'index'>
          <a >
            <div class="movie-cover">
              <img :src="item.images.small"  width="88" height="110">
            </div>
            <div class="movie-des">
              <p class="title">{{item.title}}</p>
              <p class="genres"><span>類別:</span><span v-if="item.genres.length === 0">未知</span><span v-else-if="item.genres">{{item.genres}}</span></p>
              <p class="cast">
                主演:<span v-for="items in item.casts" style="margin-right: 4px;">{{ items.name}}</span>
              </p>
              <p class="director">導演:<span v-if="item.casts[1]">{{ item.casts[1].name }}</span></p>
              <p class="ratings">{{item.rating.average}} <span>分</span></p>
            </div>
          </a>
        </div>
        </div>
      </van-tab>
      <van-tab title="即將上映">

      </van-tab>
      <van-tab title="Top250">
        
      </van-tab>
    </van-tabs>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
import {Action, Mutation, State} from 'vuex-class';
import { Tab, Tabs } from 'vant';

@Component({
  components: {
    [Tab.name]: Tab,
    [Tabs.name]: Tabs,
  },
})
export default class Home extends Vue {
      private cate = 'in_theaters';
      private active =  0;
      private movieListData = [];
      @Action private movieList!: (cate: string) => any;

      private created() {
        this.movieList( this.cate ).then( (res: any) => {
          this.movieListData = res.subjects;
        });
      }
}
</script>
<style lang="sass">
  #listMovieBox
    padding: 0 16px
    .item
      padding: 10px 0
      border-bottom: 1px solid #eee
      a
        position: relative
        display: flex
        .movie-cover
          width: 88px
          flex: 0
          height: 110px
          color: #000
        .movie-des
          flex: 1
          padding-left: 10px
          vertical-align: top
          .ratings
            position: absolute
            font-size: 20px
            font-weight: bold
            font-family: "Microsoft New Tai Lue"
            color: #FFB400
            right: 0px
            top: 16px
            span
              font-size: 14px
          .title
            line-height: 1.5rem
            padding-top: 4px
            font-size: 16px
          .genres
            font-size: 12px
            color: #666
            line-height: 24px
          .cast
            font-size: 12px
            width: 200px
            overflow: hidden
            white-space: nowrap
            text-overflow: ellipsis
            color: #666
            line-height: 24px
          .director
            font-size: 14px
            color: #999
            line-height: 26px
</style>
複製程式碼

首頁效果

最後說幾句

應該是8月份的時候我開始使用vue+typescript寫專案。

也是查了不少的資料看了一些文章,當然我這裡也是看了大佬們的文章和程式碼加上一點點自己的理解寫的文章。

這裡列舉一下我參考的文章和資料 文章:

TypeScript + 大型專案實戰

程式碼:

vue-ts-daily

相關文章