基本使用
// page頁(yè)面======================================================================
import { Component, Vue } from 'vue-property-decorator'
import NavBar from '@/components/NavBar.vue'
// 使用組件
@Component({
components: {
NavBar
}
})
// 創(chuàng)建頁(yè)面組件
export default class App extends Vue {
}
// 接口interface 文件=============================================================
export interface MainButtonType {
id: number;
icon: string | any;
name: string
}
// 組件===========================================================================
<template>
<div class="home">
<swiper :options="swiperOption" class="swiper-wrap">
<swiper-slide v-for="(slide, index) in swiperData" :key="index">
<img :src="slide.imgUrl" />
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
<div class="button-wrap">
<main-button :ButtonData="ButtonData" @buttonClick="handleButtonClick"/>
</div>
<div class="exp">
<filter-component/>
</div>
</div>
</template>
import 'swiper/dist/css/swiper.css'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import { Component, Prop, Vue } from 'vue-property-decorator'
import MainButton from '@/components/MainButton.vue'
import FilterComponent from '@/components/FilterComponent.vue'
import { MainButtonType } from '@/types'
@Component({
components: {
swiper,
swiperSlide,
MainButton,
FilterComponent
}
})
export default class Home extends Vue {
// 定義data數(shù)據(jù)
private swiperData: any[] = [
{
id: 0,
imgUrl: require('../assets/banner.png')
}
]
private swiperOption: object = {}
// 使用interface接口定義類(lèi)型 => MainButtonType
private ButtonData: MainButtonType[] = [
{
id: 0,
icon: require('../assets/travel_application.png'),
name: '出差申請(qǐng)'
},
{
id: 1,
icon: require('../assets/flight.png'),
name: '機(jī)票'
}
]
// 接口子組件的emit的函數(shù)
private handleButtonClick(id: number): void {
console.log('id:', id)
}
}
// MainButton 組件中(子組件)===============================================================
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator'
import { MainButtonType } from '@/types'
@Component
export default class MainButton extends Vue {
// props
@Prop({default: []}) ButtonData!: MainButtonType[]
// 生命周期
created(): void {
console.log('created')
}
// watch
@Watch('ButtonData', {deep: true, immediate: true})
ButtonDataWatch(val: MainButtonType[]):void {
console.log(123, val)
}
// emit
@Emit('buttonClick')
private handleItemClick(id: number): void {
// 函數(shù)的參數(shù)值即是emit的payload
}
}
// filterComponent組件:filters和computed示例 (子組件)==================================================================
<template>
<div class="filter-wrap">
<div>filters示例:{{exp | formatNum}}</div>
<br/>
<div>computed示例:{{computedNum}}</div>
</div>
</template>
import { Component, Vue } from 'vue-property-decorator'
@Component({
// filters
filters: {
formatNum(val: number): string {
if (!val && val !== 0) return ''
return val.toFixed(2)
}
}
})
export default class FilterComponent extends Vue {
private exp: number = 12.346546754
// computed
get computedNum(): number {
return this.exp * 1000
}
}
在vuex中使用
- 注: typescript目前對(duì)vuex的支持還不完善庐船,需要引入 vuex-class 包來(lái)支持
-
vuex-class
提供了State, Getter, Action, Mutation, nam-espace
這幾個(gè)裝飾器
- 示例
// vuex中蔓彩, 以state為例
// 1. 定義接口
export interface USERINFO {
userId: number;
userName: string;
avatar: string
}
export default interface STATE {
userInfo: USERINFO;
}
// 2. state.js使用接口
import STATE from './stateType.js';
const state: STATE = {
userInfo: {
userId: 0,
userName: '',
avatar: '',
}
};
export default state;
// 組件中使用
import Vue from 'vue'
import Component from 'vue-class-component'
import {
State,
Getter,
Action,
Mutation,
namespace
} from 'vuex-class'
const someModule = namespace('path/to/module')
@Component
export class MyComp extends Vue {
@State('foo') stateFoo
@State(state => state.bar) stateBar
@Getter('foo') getterFoo
@Action('foo') actionFoo
@Mutation('foo') mutationFoo
@someModule.Getter('foo') moduleGetterFoo
@State foo
@Getter bar
@Action baz
@Mutation qux
created () {
this.stateFoo // -> store.state.foo
this.stateBar // -> store.state.bar
this.getterFoo // -> store.getters.foo
this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true })
this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true })
this.moduleGetterFoo // -> store.getters['path/to/module/foo']
}
}
注意事項(xiàng)
-
vue-property-decorator
和 vue-class-component
的區(qū)別
-
vue-class-component
是 vue 官方出的
-
vue-property-decorator
是社區(qū)出的
- 其中
vue-class-component
提供了 vue component
等等
-
vue-property-decorator
深度依賴了 vue-class-component
拓展出了很多操作符@Prop @Emit @Inject
等等 可以說(shuō)是vue-class-component
的一個(gè)超集
- 正常開(kāi)發(fā)的時(shí)候 你只需要使用
vue-property-decorator
中提供的操作符即可 不用再?gòu)?code>vue-class-componen引入vue component
- 引入第三方包報(bào)錯(cuò)
- 現(xiàn)象:
Could not find a declaration file for module 'vue-awesome-swiper'
e7e1f5f462d88e9d304441f1e1cb962.png
- 原因: 插件文件可能不是.ts文件而是.js文件
- 解決方案一: 安裝對(duì)應(yīng)的ts模塊
- 解決方案二: 配置
shims-vue-d.ts
文件(推薦)
import Vue from "vue"
import VueRouter, { Route } from "vue-router"
declare module '*.vue' {
export default Vue
}
declare module "vue/types/vue" {
interface Vue {
$router: VueRouter; // 這表示this下有這個(gè)東西
$route: Route;
$https: any;
$urls: any;
$Message: any;
$Modal: any;
}
}
// 以swiper為例,在此添加聲明
declare module 'vue-awesome-swiper'
- 解決方案三: 配置
tsconfig.json
文件
{
"compilerOptions": {
...
"noImplicitAny": false, // 忽略引入類(lèi)型檢查
......
}
}
- 聲明全局變量
- 添加shime-global.d.ts文件闲询,與main.ts同級(jí)
// 聲明全局的 window 涤浇,不然使用 window.XX 時(shí)會(huì)報(bào)錯(cuò)
// declare var window: Window;
declare var document: Document;
declare var THREE: any;
// interface THREE extends Window {}
// element-ui
declare module "element-ui/lib/transitions/collapse-transition";
declare module "element-ui";