基本使用
// page页面======================================================================
import { Component, Vue } from 'vue-property-decorator'
import NavBar from '@/components/NavBar.vue'
// 使用组件
@Component({
components: {
NavBar
}
})
// 创建页面组件
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数据
private swiperData: any[] = [
{
id: 0,
imgUrl: require('../assets/banner.png')
}
]
private swiperOption: object = {}
// 使用interface接口定义类型 => MainButtonType
private ButtonData: MainButtonType[] = [
{
id: 0,
icon: require('../assets/travel_application.png'),
name: '出差申请'
},
{
id: 1,
icon: require('../assets/flight.png'),
name: '机票'
}
]
// 接口子组件的emit的函数
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 {
// 函数的参数值即是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目前对vuex的支持还不完善,需要引入 vuex-class 包来支持
-
vuex-class
提供了State, Getter, Action, Mutation, nam-espace
这几个装饰器
- 示例
// 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']
}
}
注意事项
-
vue-property-decorator
和 vue-class-component
的区别
-
vue-class-component
是 vue 官方出的
-
vue-property-decorator
是社区出的
- 其中
vue-class-component
提供了 vue component
等等
-
vue-property-decorator
深度依赖了 vue-class-component
拓展出了很多操作符@Prop @Emit @Inject
等等 可以说是vue-class-component
的一个超集
- 正常开发的时候 你只需要使用
vue-property-decorator
中提供的操作符即可 不用再从vue-class-componen
引入vue component
- 引入第三方包报错
- 现象:
Could not find a declaration file for module 'vue-awesome-swiper'
e7e1f5f462d88e9d304441f1e1cb962.png
- 原因: 插件文件可能不是.ts文件而是.js文件
- 解决方案一: 安装对应的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下有这个东西
$route: Route;
$https: any;
$urls: any;
$Message: any;
$Modal: any;
}
}
// 以swiper为例,在此添加声明
declare module 'vue-awesome-swiper'
- 解决方案三: 配置
tsconfig.json
文件
{
"compilerOptions": {
...
"noImplicitAny": false, // 忽略引入类型检查
......
}
}
- 声明全局变量
- 添加shime-global.d.ts文件,与main.ts同级
// 声明全局的 window ,不然使用 window.XX 时会报错
// 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";