前言:
為什麼要編寫這篇文章?一是對自己技術的磨練,二是給大家分享如何使用vue+typescript開發專案。
大佬就不要噴我的程式碼了。主要面向技術一般般的同學,沒有寫過typescript。當然我技術也是一般般。
github程式碼已經更新完成,如果覺得我廢話可以直接去gayhub地址
專案截圖
正文:
我假設你已經熟練應用過vue全家桶(vue+router+vuex+axios[‘黑人問號臉?’])
另外先泡一杯咖啡!
在這裡我也不教你如何配置環境了直接開始正題,let's go!
第一階段配置專案並啟動
當前開發版本:
vue create projectName //projectName 是指你的專案名稱
複製程式碼
這裡可以選擇預設模板和和自己配置。
這裡我選擇的是第二個,然後又讓你選擇……
這裡的選擇可以按數字鍵選擇的
- Babel =====> 1
- TyepScript ====> 2
以次類推,所以你懂我意思吧
這裡選擇我們需要的幾個東東,然後愉快的回車把,喝一會咖啡等待專案安裝完成。
安裝完成之後我們先看下檔案目錄
細心的同學肯定發現了少了 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
第二階段 封裝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寫專案。
也是查了不少的資料看了一些文章,當然我這裡也是看了大佬們的文章和程式碼加上一點點自己的理解寫的文章。
這裡列舉一下我參考的文章和資料 文章:
程式碼: