Vue大操練
技術棧:pug + typescript
專案前景:在前幾天看到別人家的專案使用了pug + ts,總共程式碼行數加起來簡直少的可憐,心癢癢便自己動手試了一試
解決的問題:檢視層的文字資訊完全和頁面解耦,不用擔心找一個欄位/莫名其妙標點的文字錯誤啦,加上ts以後報錯資訊也更多了呢(編譯不通過你丫咋執行!)
-
語法介紹
-
pug
使用縮排進行分組,無標籤化
.p(v-mode="myModel")
==><div class="p" v-mode="myModel"></div>
.p Hello world!
==><div class="p">Hello world!</div>
-
Typescript
使用class語法進行編寫,比js更加嚴謹
-
-
專案搭建
vue-cli3
選擇manually 複製程式碼
選擇對應的專案需要 (空格選擇)
- Ts
- Router
- Vuex
- CSS Pre-pro
複製程式碼
- 新增pug-loader
yarn add pug pug-loader
- 新增sass-loader
yarn add sass-loader node-sass style-loader
- 目錄結構
- _constants
存放一些常量
- _models
用來存放頁面的文字資訊、和後臺互動的表單欄位(bean)的封裝類
- _helpers
用來存放一些幫助類
- _services
編寫獲取頁面資料/呼叫後臺api的封裝類
- assets
資原始檔
- view
檢視層
- _constants
- App.vue
Component裝飾器為元件新增了生命週期等
<template lang="pug">
#app
NavComponent(:json="nav")
#main
router-view
</template>
<script lang='ts'>
import { Component, Prop, Vue } from 'vue-property-decorator';
import NavComponent from '@/components/Nav.vue';
import { NavService } from '@/_services';
import { Nav as NavBean } from '@/_models';
@Component({
components: {
NavComponent,
},
})
export default class App extends Vue {
public nav!: object;
public data() {
return {
nav: {},
};
}
private beforeMount(): void {
NavService.get().then((res: NavBean): void => {
this.nav = res;
});
}
}
</script>
<style lang="scss">
*{
font-family: "DIN Pro", "PingFang SC", "Microsoft Yahei", 微軟雅黑;
}
#app {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
body{
position: relative;
margin: 0 !important;
padding: 0;
height: 100vh;
}
</style>
複製程式碼
- Nav.vue
<template lang="pug">
.nav-wrapper
img(:src="json.logo")
</template>
<script lang="ts">
import { Vue, Prop, Component } from 'vue-property-decorator';
import { NavService } from '@/_services';
import { Nav as NavBean } from '@/_models';
@Component
export default class Nav extends Vue {
@Prop() public json?: NavBean;
}
</script>
<style lang="scss">
.nav-wrapper {
width: 100%;
height: 60px;
padding: 10px;
box-sizing: border-box;
img {
height: 100%;
width: 120px;
}
}
</style>
複製程式碼
- NavService
import axios from 'axios';
import { BaseService } from './base.services';
import { Ressource } from '../_helpers';
import { Nav } from '@/_models';
export class NavService extends BaseService {
public static get(): Promise<Nav> {
const ressource = new Ressource(process.env.VUE_APP_LOCALURL_ENV);
ressource.shapeUrl('/content/nav.json', []);
return axios.get<Nav>(ressource.fullUrl, this.requestOptionsGet())
.then((data: any) => {
return data.data;
});
}
}
複製程式碼
- BaseService
export class BaseService {
public static basicOptions: any = {
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer test',
'Access-Control-Allow-Origin': '*',
},
redirect: 'follow',
referrer: 'no-referrer',
crossdomain: true,
};
public static requestOptionsPost(body: any): object {
const header: any = {
...this.basicOptions,
...{
body: JSON.stringify(body),
},
};
return header;
}
public static requestOptionsGet(): object {
const header: any = {
...this.basicOptions,
...{
method: 'GET',
responseType: 'json',
},
};
return header;
}
public static requestOptionsGetAuth(): object {
return {
method: 'GET',
};
}
}
複製程式碼
- Index.tsx
_services/index.tsx
負責把所有Service匯出
/**
* suffix rule:
* 1. (xxx.services.tsx) services which means the class was build for call backend service etc
* 2. (xxx.page.tsx) page which means the class was build for the static page text
* 3. (xxx.tsx) non-suffix which means the class was build for extra service
*/
export { NavService } from './nav.page';
複製程式碼
- nav.json
public/content/nav.json
{
"id": 1,
"name": "xxx-nav",
"logo": "/img/logo.png"
}
複製程式碼
-
TS語法補充
- Watch使用
@Watch('enable') private onPropertyChanged(value: any, oldValue: any): void { if (value) { console.log('value changed!') } } 複製程式碼
- Computed使用
使用get構造器
get confirmBtnStyle() { if (this.confirmBtnDisable) { return { 'background-color': '#868d90', 'cursor': 'not-allowed', }; } else { return {}; } } 複製程式碼
- Emit使用
@Emit('show') private handleShow(): void {} 複製程式碼
?快去試一試吧!