之所以写下这篇文章,是因为最近的项目需求,使用Vue,TypeScript实现项目,对我而言,是一个全新的挑战,因此,是零基础,不过各语言之间都是相通的,学起来也没有那么难。只是在真正实现项目的过程中,踩过了好多坑。
一,该链接中讲到Vue对typescript的支持:https://cn.vuejs.org/v2/guide/typescript.html
二,typescript是什么?
(1)TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准。
(2)TypeScript 由微软开发的自由和开源的编程语言。
(3)TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。
三,JavaScript 与 TypeScript 的区别
TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。
TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。
四,TS语法糖
官方文档:https://github.com/kaorun343/vue-property-decorator
单页面组件中,在 @Component({})
里面写 props
、data
等调用起来极其不方便,而 vue-property-decorator
里面包含了 8 个装饰符则解决了此类问题,他们分别为
@Emit
指定事件 emit,可以使用此修饰符,也可以直接使用 this.$emit()
@Inject
指定依赖注入)@Mixins
mixin 注入@Model
指定 model@Prop
指定 Prop@Provide
指定 Provide@Watch
指定 Watch@Component
export from vue-class-component
import { Component, Emit, Inject, Model, Prop, Provide, Vue, Watch } from 'vue-property-decorator'
@Component
export class MyComponent extends Vue {
@Prop()
propA: number = 1
@Prop({ default: 'default value' })
propB: string
@Prop([String, Boolean])
propC: string | boolean
@Prop({ type: null })
propD: any
@Watch('child')
onChildChanged(val: string, oldVal: string) { }
}
上面的代码相当于:
export default {
props: {
checked: Boolean,
propA: Number,
propB: {
type: String,
default: 'default value'
},
propC: [String, Boolean],
propD: { type: null }
}
methods: {
onChildChanged(val, oldVal) { }
},
watch: {
'child': {
handler: 'onChildChanged',
immediate: false,
deep: false
}
}
}
vuex-class 是一个基于 Vue、Vuex、vue-class-component 的库,和 vue-property-decorator
一样,它也提供了4 个修饰符以及 namespace,解决了 vuex 在 .vue 文件中使用上的不便的问题。
组件引用,mixins,filters 等放在 @Component 里面
链接:https://juejin.im/post/5b54886ce51d45198f5c75d7
五,Vue+TypeScript项目搭建?
main.ts
import Vue from 'vue'
import App from './App.vue'
import router from '@/router/index'
import store from './store'
import './plugins/axios'
import './plugins/element.ts'
import 'font-awesome/css/font-awesome.min.css'
import moment from 'moment'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
}).$mount('#app')
App.vue
store.ts
在使用vuex实现状态管理的过程中,忽略了该全局文件的存在,导致this.$store一直获取不到自己封装的action,mutation。
import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from '../src/vuex/getters'
import modules from '../src/vuex/modules'
Vue.use(Vuex)
export default new Vuex.Store({
getters,
modules,
strict: process.env.NODE_ENV !== 'production'
})
vuex文件:getters.ts
export const currentUser = (state: any) => state.user.user
export const accessToken = (state: any) => state.user.token
vuex文件:users.ts
import * as types from '../mutation-types'
import { login } from '@/api/staff'
import { ActionTree } from 'vuex'
import { RootStateTypes } from '../mutation-types'
const state = {
user: null,
token: null
}
const mutations = {
[types.UPDATE_STAFF] (state: any, user: any) {
state.user = user
},
[types.UPDATE_TOKEN] (state: any, token: any) {
state.token = token
}
}
const actions: ActionTree = {
// 登录
STAFF_LOGIN ({ commit }, userInfo: any) {
const username = userInfo.username.trim()
const password = userInfo.password.trim()
const code = userInfo.code
return new Promise((resolve, reject) => {
login({username, password, code}).then(response => {
const data = response.data
commit(types.UPDATE_STAFF, data.staffUser)
commit(types.UPDATE_TOKEN, data.token)
resolve(response)
}).catch(error => {
reject(error)
})
})
}
}
export default {
state,
mutations,
actions
}
vuex文件:mutation-types.ts
export interface RootStateTypes {
STAFF_LOGIN: 'STAFF_LOGIN'
}
views文件:Login.vue
{{appTitle}}
请登录
{{ message }}
登录
该帖子值得借鉴:https://segmentfault.com/a/1190000011864013