Basic type 資料型態
- string
- number
- Array
- tuple
let x : [string, number]
x = ['a', 1] // ok x = [1, 'a'] // error
5. enum
// enum 預設從 0 開始
enum Color { Red,
Green,
Blue}
let c : Color = Color.Red
6. void
7. object
先安裝 vue-property-decorator
npm i vue-property-decorator
class-based-component
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component({ name: 'PageComponent'
}) export default class PageComponent extends Vue { }</script>
等同於
<script> export default {
name: 'PageComponent' }</script>
Import the other component
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import PageComponent from '@/components/PageComponent.vue'
@Component({ name: 'PageComponent', components: { PageComponent
}
}) export default class PageComponent extends Vue { }</script>
等同於
<script>
import PageComponent from '@/components/PageComponent.vue'export default {
name: 'PageComponent',
components: { PageComponent
}}</script>
Vuex
npm install vuex-module-decorators
npm install vuex-class
/store/index.js
// store/index.ts
import { Store } from 'vuex'export const store = new Store({})
// store/atuh.tsimport { VuexModule, Action, Mutation, Module } from 'vuex-module-decorators'import { store } from '@/store' // 引入上面的 store@Module({ name: 'auth', stateFactory: true, namespaced: true, // namespaced dynamic: true, // 自動加載 store,})export default class AuthModule extends VuexModule {
// 顯示 action 的 error @Action({ rawError: true }) async postLogin(payload: IPostLogin): Promise<void> { $cookies.set('auth', payload.access_token) // context 有基本的 commit dispatch 等等 this.context.dispatch('me/setMeData', null, { root: true }) } @Action({ rawError: true }) nuxtClientInit() { if ($cookies.getOriginal('auth')) { this.postLogin({ access_token: $cookies.getOriginal('auth') }) } }}
在 component 使用 vuex
import { Component, Vue, namespace } from 'nuxt-property-decorator'const auth = namespace('auth')@Componentexport default class LoginPage extends Vue { @auth.Action('postLogin') private postLogin!: (payload: IPostLogin) => void
@auth.Getter('getMe') private getMe!: IUser}
Component data
<script lang="ts">import { Component, Vue, namespace } from 'nuxt-property-decorator'@Component({layout: 'auth',})
export default class Page extends Vue { private authForm: AuthForm = { account: '', password: '', }}</script>
等同於
<script>export default { name: 'Page', data() {
return {
account: '', password: '',
} }}</script>
Component Props
import { Component, Vue, Prop } from 'nuxt-property-decorator'
export default class Page extends Vue { @Prop({ required: true, type: Array, default: [] })
readonly breadcrumbs!: Breadcrumbs[]}
等同於
export default { name: 'Page', props: {
breadcrumbs: { type: Array, default: () => [],
}
}
}
computed
get isMenus(): boolean { return this.menu.menus.length > 0}
等同於
computed: { isMenus() { ///
}
}
methods
toggleOpen(): void { this.open = !this.open}
等同於
methods: { toggleOpen() { this.open = !this.open
}
}
watcher — 監聽某個變數的變化
import { Vue, Component, Watch } from 'vue-property-decorator'@Watch('child')
onChildChanged(val: string, oldVal: string) {}
等同於
watch: { child(newValue, oldValue): { }}
watch 監聽深層的物件
import { Vue, Component, Watch } from 'vue-property-decorator'@Watch('child', { deep: false,
immediate: false
})
onChildChanged(val: string, oldVal: string) {}
等同於
watch: { child: { deep: false, immediate: false, handler(value: string, oldValue: string) {}
}}
倘若 axios 有 async awit
import { AxiosResponse } from 'axios'
import { ICompanyAttr } from '@/interface/company'async created() { const {data: company } : AxiosResponse<ICompanyAttr> = await apiGetData()
}
宣告 generic function
function hello<T>(params: T): T {
}
這樣做的話 hello 的 params 參數即可接受任何型別的資料
TypeScript plugin
import Cookies from 'js-cookie'
import Vue from 'vue'// 定義 nuxt pluginimport { Plugin } from '@nuxt/types'
import { ICookiesMethod } from '@/interface/cookie'// 定義 cookie method 的 interface
interface ICookiesMethod {
set: Function
get: Function
getOriginal: Function
remove: Function
removeAll: Function
removeCrossDomain: Function
}// 將 $cookies 定義在 Vue interface 裡
// 這樣才能使用 this.$cookies
// 否則會編輯器會警告有錯
declare module 'vue/types/vue' {
interface Vue {
$cookies: ICookiesMethod
}interface Context {
$cookies: ICookiesMethod
}
}// 定義 cookies plugin
const cookies: Plugin = (context, inject) => {
const cookiesObj: ICookiesMethod = {
set: (name: string, value = {}, expires = { expires: 365 }) => {
Cookies.set(name, value, expires)
},
get: (name: string) => {
const val = Cookies.get(name)
try {
return JSON.parse(val)
} catch (err) {
return undefined
}
},
getOriginal: (name: string) => {
try {
return Cookies.get(name)
} catch (err) {
return undefined
}
},
remove: (name: string) => {
Cookies.remove(name)
},
removeCrossDomain: (name: string, attributes = { path: '/', domain: process.env.COOKIES_DOMAIN }) => {
Cookies.remove(name, attributes)
},
removeAll: () => {
const NodeList = Object.keys(Cookies.get())
NodeList.forEach(el => Cookies.remove(el))
window.location.replace('/')
},
}inject('cookies', cookiesObj)
}export default cookies
middleware 定義
/**
Middleware ==> data type
Context => context 的型別
**/
import { Middleware, Context } from '@nuxt/types'// 以下例子為 ssr, 倘若是 spa 則不會有 server side 的問題// 定義驗證的 middlware
const authenticate: Middleware = async (context: Context) => {
if (!context.app.$cookiz.get('auth')) {
context.redirect('/login')
} else {
try {
await context.store.dispatch('me/setMeData')
} catch (e) {
context.redirect('/login')
}
}
}export default authenticate
有些 plugin 會將資料掛載在 vue instance
// 例如
// vue-notification 套件// 在 template 使用如下this.$notify()// 但是 typescript 除了引入 plugin 外// 在 tsconfig.json 要特別在 types: 設定
// 否則 this 吃不到 notify// 以配下配供參考
{
"compilerOptions": {
"forceConsistentCasingInFileNames": false,
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "Node",
"lib": ["ESNext", "ESNext.AsyncIterable", "DOM"],
"esModuleInterop": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"noEmit": true,
"experimentalDecorators": true, // 使其可以使用 decorator
"baseUrl": ".",
"paths": { // path 轉換
"~/*": ["./*"],
"@/*": ["./*"]
},
// 設定在 instance, 這樣 this 才吃得到
"types": ["@nuxt/types", "@types/node", "@nuxtjs/axios", "vue-notification", "js-cookie"]
},
"exclude": ["node_modules", ".nuxt", "dist"]
}
額外補充
倘若使用 typescript 的話, 許多套件需安裝 @types 開頭的套件, 例如 lodash
// typescript 倘若只安裝以下套件
// 在 template 引用則會出錯
npm install --save lodash// typescript 需安裝
npm install --save @types/lodash
例外也可以照以下的文件使用 vuex
https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs