【Typescript+Vue】01. easy
01. 声明 vue 和 window 的全局属性和方法
-
import Vue from 'vue'; declare module 'vue/types/vue' { import { Maps } from '@/maps'; import { Utils } from '@/utils'; interface Vue { $utils: Utils; query: any; $MAPS: Maps; $ROLE: string; $USER_NAME: string; $PERMISSION: string[]; $HAS_PERMISSION: (key: string | RegExp) => boolean; } } declare global { import dayjs from 'dayjs'; import { AxiosInstance } from 'axios'; interface Window { axios: AxiosInstance; ga: any; dayjs: typeof dayjs; GoogleAnalyticsObject: any; MS_PER_DAY: number; UUAP: string; } }
02. 基本 vue 组件 111
-
<!-- @file: App.vue @author: xxx @description: 根组件 --> <template> <div id="app"> <main class="main-container"> <div class="__inner"> <router-view></router-view> </div> </main> <base-aside></base-aside> <base-footer></base-footer> </div> </template> <script lang="ts"> import Vue from 'vue' import BaseFooter from '@/components/BaseFooter.vue' import BaseAside from '@/components/BaseAside.vue' export default Vue.extend({ name: 'App', components: { BaseAside, BaseFooter }, props: {}, data () { return {} }, watch: {}, computed: {}, methods: {}, created () {}, mounted () {}, destroyed () {} }) </script>
03. 单 mixin 组件使用
-
... ... <script lang="ts"> import clipboard from '@/mixins/clipboard' export default generalCRUD.extend({
name: 'VideoManage',
components: { ... ...},
data () {... ...
04. 多 mixin 组件使用
-
... ... <script lang="ts"> import clipboard from '@/mixins/clipboard' export default generalCRUD.extend(clipboard).extend({
name: 'AudioManage',
components: { ... ...},
data () {... ...
05. 计算属性【computed】必须声明返回值类型
-
......
export default generalCRUD.extend(clipboard).extend({ name: 'SandboxAudios', components: { CategorySelector }, data () { return { loading: false } }, computed: { writeAble (): boolean { return this.$HAS_PERMISSION('mango:video:sandbox:audios:w') } },
......每一个计算属性都声明类型以后,会发现解决了很多声明问题
06. 如果找不到 this 的某个 state 则需要显示声明 data 的返回值类型
07. 经常需要用到 for of 遍历对象,但是编辑器报错
-
export interface KeyValue { [key: string]: any; }
可以定义类型 继承这个 KeyValue 类解决
08. 全局常量声明
09. 类型声明
10. 在用的 .eslintrc.js 配置
- 不用 tslint,官方都倾向 eslint 了。
- 不用分号了
其实用不用分号我都行。个人倾向于使用分号。因为我发现在有些情况,不用的话 ts 会报错
-
module.exports = { root: true, env: { node: true }, extends: [ 'plugin:vue/essential', 'eslint:recommended', '@vue/typescript/recommended' ], parserOptions: { parser: '@typescript-eslint/parser', ecmaVersion: 2020 }, globals: { MS_PER_DAY: true }, rules: { 'no-console': process.env.NODE_ENV === 'production' ? 1 : 0, 'no-debugger': process.env.NODE_ENV === "production" ? 1 : 0, 'semi': [2, 'never'], 'indent': [2, 2], 'quotes': [2, 'single'], 'no-empty': 0, 'prefer-const': 0, 'comma-dangle': [2, 'never'], 'prettier/prettier': 0, 'space-before-function-paren': [0, 'always'], '@typescript-eslint/space-before-function-paren': [ 2, { asyncArrow: 'always', anonymous: 'always', named: 'always' } ], '@typescript-eslint/no-unused-vars': 0, '@typescript-eslint/no-empty-function': 0, '@typescript-eslint/no-var-requires': 0, '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/camelcase': 0, '@typescript-eslint/semi': [2, 'never'] } }
11. Vuex 全局状态管理 Store
- 一个全局 store + 若干模块化 store
- 每个 store 都分为四个文件
- 一个全局store
index.ts
-
import Vue from 'vue' import Vuex, { StoreOptions } from 'vuex' import getters from './getters' import actions from './actions' import mutations from './mutations' import sMenu from './module/sMenu' import { RootState, RootStore } from '@/entities/store' Vue.use(Vuex) const state: RootState = { userInfo: {} } export default new Vuex.Store({ state, getters, actions, mutations, modules: { sMenu } } as StoreOptions<RootStore>)
getter.ts
-
import { GetterTree } from 'vuex' import { RootState } from '@/entities/store' export default {} as GetterTree<RootState, RootState>
actions.ts
-
import { ActionContext, ActionTree } from 'vuex' import { RootMutation, RootState } from '@/entities/store' import userApi from '@/api/user' import { AxiosError, AxiosResponse } from 'axios' export default { async getUserInfo (actionContext: ActionContext<RootState, RootState>) { return new Promise((resolve, reject) => { userApi .getUserInfo() .then((res: AxiosResponse) => { actionContext.commit(RootMutation.setUserInfo, res) resolve(res) }) .catch((e: AxiosError) => { reject(e) }) }) }, } as ActionTree<RootState, RootState>
mutations.ts
-
import { MutationTree } from 'vuex' import { RootMutation, RootState } from '@/entities/store' export default { [RootMutation.setUserInfo] (state: RootState, payload) { state.userInfo = payload } } as MutationTree<RootState>
- 其中一个 模块化 store
index.ts
-
import { Module } from 'vuex' import actions from './actions' import mutations from './mutations' import getters from './getters' import { RootState } from '@/entities/store' import { MenuState } from '@/entities/store/sMenu' const state: MenuState = { menuId: localStorage.getItem('menuId') || '', menuList: [] } export default { state, actions, mutations, getters } as Module<MenuState, RootState>
getters.ts
-
import { GetterTree } from 'vuex' import { RootState } from '@/entities/store' import { MenuState } from '@/entities/store/sMenu' export default {} as GetterTree<MenuState, RootState>
actioins.ts
-
import { ActionContext, ActionTree } from 'vuex' import api from '@/api/menu' import maps from '@/maps' import { KeyValue } from '@/entities' import { RootState } from '@/entities/store' import { MenuMutation, MenuState } from '@/entities/store/sMenu' export default { getMenuList ({ commit }, { pkg }) { return new Promise((resolve) => { api.requestMenuList({ pkg }) .then((res: KeyValue) => { commit('setMenuList', res) const menuIdToName: KeyValue = {} res.forEach((v: KeyValue) => { menuIdToName[v.id] = v.name }) maps.menu.menuIdToName = menuIdToName resolve(res) }) .catch(() => { commit('setMenuList', []) resolve([]) }) }) }, setMenu (actionContext: ActionContext<MenuState, RootState>, { menuId }) { actionContext.commit(MenuMutation.setMenu, menuId) } } as ActionTree<MenuState, RootState>
mutations.ts
-
import { MutationTree } from 'vuex' import { MenuMutation, MenuState } from '@/entities/store/sMenu' export default { [MenuMutation.setMenuList] (state: MenuState, payload) { state.menuList = payload }, [MenuMutation.setMenu] (state: MenuState, menuId) { state.menuId = menuId localStorage.setItem('menuId', menuId) } } as MutationTree<MenuState>
所有的 mutation 都应该只在 action 中调用,对 state 进行集中操作
12. ing
13. ing
--------小尾巴
________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...