Vue + TypeScript 项目起手式

在此前我使用的前端框架是 Angular,使用过 TypeScript 后你就会讨厌 JS 了,我学习 Vue 时的最新版本是 2.5,相信大部分同学都不会认为 Vue 那样又细又长的代码很美观吧,简单看了一些网络博客后,我毅然决然引入了 TypeScript 进行开发,本文仅整理记录我自己遇到的一些坑。

使用 Cli

脚手架是一个比较方便的工具,这里需要注意的是@vue/clivue-cli是不一样的,推荐使用npm i -g @vue/cli安装。

安装完成后,可以直接使用vue create your-app创建项目,你可以选择使用默认配置亦或是自己手动选择配置,按提示一步一步向下走即可,它会根据你的选择自己创建比如tsconfig.json等等配置文件。这里推荐使用less开发样式,sass老是在安装的过程中出问题。

当然你也可以使vue ui命令启动一个本地服务,它是一个 Vue 项目管理器,提供了一个可视化的页面供你管理自己的项目,它的样子如下图所示,还是比较清新的。

图片说明

使用 vue-property-decorator

Vue 官方维护了 vue-class-component 装饰器,vue-property-decorator 则是在vue-class-component基础上增强了更多结合Vue特性的装饰器,它可以让 Vue 组件语法在结合了 TypeScript 语法后变得更加扁平化。

截止本文时间,vue-property-decorator共提供了 11 个装饰器和 1 个Mixins方法,下面用@Prop举个例子,是不是看起来引起极度舒适。

import { Vue, Component, Prop } from 'vue-property-decorator'

@Component

export default class YourComponent extends Vue {

    @Prop(Number) readonly propA: number | undefined

    @Prop({ default: 'default value' }) readonly propB!: string

    @Prop([String, Boolean]) readonly propC: string | boolean | undefined

}

// 上面的内容将会被解析成如下格式

export default {

    props: {

        propA: {

            type: Number

        },

        propB: {

            default: 'default value'

        },

        propC: {

            type: [String, Boolean]

        }

    }

}

使用 Vuex

关于怎么使用Vuex此处就不再做过多说明了,需要注意的一点是,如果你需要访问$store属性的话,那么你必须得继承Vue类,坑的地方是在某些情况下即使你没有继承Vue,它也能通过编译,只有在程序运行起来的时候才报错。

class ExampleApi extends Vue {

    public async getExampleData() {

        if (!this.$store.state.exampleData) {

            const res = await http.get('url/exampleData');

            if (res.result) {

                this.$store.commit('setExampleData', res.data);

                return res.data;

            } else {

                promptUtil.showMessage('get exampleData failed', 'warning');

            }

        } else {

            return this.$store.state.exampleData;

        }

    }

}

使用自己的配置(含代理)

vue.config.js是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它会被@vue/cli-service自动加载,它的配置项说明可以查看配置参考

我们再开发过程中都会使用代理来转发请求,代理的配置也是在这个文件中,它的官方说明在devserver-proxy中,下面是一个简单的vue.config.js文件例子。

module.exports = {

    filenameHashing: true,

    outputDir: 'dist',

    assetsDir: 'asserts',

    indexPath: 'index.html',

    productionSourceMap: false,

    transpileDependencies: [

        'vue-echarts',

        'resize-detector'

    ],

    devServer: {

        hotOnly: true,

        https: false,

        proxy: {

            "/statistics": {

            target: "http://10.7.213.186:3889",

            secure: false,

            pathRewrite: {

            "^/statistics": "",

        },

        changeOrigin: true

        },

    "/mail": {

        target: "http://10.7.213.186:8888",

        secure: false,

        changeOrigin: true

    }

    }

}

}

让 Vue 识别全局方法和变量

我们在项目中都会使用一些第三方 UI 组件,比如我自己就使用了 Element,但是在使用它的```notify等方法时就直接报错了,究其原因就是$message```等属性并没有在 Vue 实例中声明。

官方对此给出了很明确的解决方案,使用的是 TypeScript 的 模块补充特性,可以查看增强类型以配合插件使用。既然知道是因为没有声明导致的错误,那我们就给它声明一下好了,在src/shims-vue.d.ts文件中添加如下代码即可,如果没有该文件请自行创建。

看到网上也有一部分人说的是src/vue-shim.d.ts,反正不管是怎么命名这个文件的,它们的作用是一样的。

declare module 'vue/types/vue' {

    interface Vue {

        $message: any,

        $confirm: any,

        $prompt: any,

        $notify: any

    }

}

这里顺道提一下,src/shims-vue.d.ts文件中的如下代码是为了让你的 IDE 明白以.vue结尾的文件是什么玩意儿。

declare module '*.vue' {

    import Vue from 'vue';

    export default Vue;

}

路由懒加载

Vue Router 官方有关于路由懒加载的说明,但不知道为什么官方给的这个说明在我的项目里面都没有生效,但使用require.ensure()按需加载组件可以生效。

// base-view 是模块名,写了相同的模块名则代码会被组织到同一个文件中

const Home = (r: any) => require.ensure([], () => r(require('@/views/home.vue')), layzImportError, 'base-view');

// 路由加载错误时的提示函数

function layzImportError() {

    alert('路由懒加载错误');

}

上面的方式会在编译的时候把文件自动分成多个小文件,编译后的文件会以你自己命名的模块名来命名,如果代码之间有相互依赖,依赖部分代码编译后的文件会以两个模块名相连后进行命名。

但是需要注意的是,这样拆分小文件之后引入了另外一个新的问题,因为客户端会缓存这些编译后的 js 文件,如果功能 A 同时依赖了a.jsb.js两个文件,但用户在使用其它功能时已经把a.js缓存到本地了,使用功能 A 时需要请求b.js文件,这时程序就很容易报错,因为此时在客户端这两个文件不是同一个版本,所以可能导致a.js调用b.js中的方法已经被删了,进而导致客户端页面异常。

关于引入第三方包

项目在引入第三方包的时候经常会报出各种奇奇怪怪的错误,这里仅提供我目前找到的一些解决办法。

/*

引入 jquery 等库可以尝试下面这种方式

只需要把相应的 js 文件放到指定文件夹即可

**/

const $ = require('@/common/js/jquery.min.js');

const md5 = require('@/common/js/md5.js');

引入一些第三方样式文件、UI 组件等,如果引入不成功可以尝试建一个 js 文件,将导入语句都写在 js 文件中,然后再在main.ts文件中导入这个 js 文件,这个方法能解决大部分的问题。例如我先建了一个lib.js,然后在main.ts中引入lib.js就没有报错。

// src/plugins/lib.js

import Vue from 'vue';

// 树形组件

import 'vue-tree-halower/dist/halower-tree.min.css';

import {VTree} from 'vue-tree-halower';

// 饿了么组件

import Element from 'element-ui';

import 'element-ui/lib/theme-chalk/index.css';

// font-awesome 图标

import '../../node_modules/font-awesome/css/font-awesome.css';

import VueCookies from 'vue-cookies';

import VueJWT from 'vuejs-jwt';

Vue.use(VueJWT);

Vue.use(VueCookies);

Vue.use(VTree);

Vue.use(Element);

// src/main.ts

import App from '@/app.vue';

import Vue from 'vue';

import router from './router';

import store from './store';

import './registerServiceWorker';

import './plugins/lib';

Vue.config.productionTip = false;

new Vue({

router,

store,

render: (h) => h(App),

}).$mount('#app');

因为第三方包写的各有特点,在引入不成功的时候基本也只能是见招拆招,当然如果你的功底比较深厚,你也可以自己写一个index.d.ts文件,实在不行的话,那个特殊的组件不使用 TypeScript 来写也能解决,我目前还没有找一个可以完全解决第三方包引入错误的方法,如果您已经有相关的方法了,希望能与你一起探讨交流。

#学习路径#

注意!此信息未认证,请谨慎判断信息的真实性!

全部评论
空

相关内容推荐

头像 头像
点赞 评论 收藏
转发
头像 头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
2022-12-22 16:38
江苏大学_2023
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像 头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像 头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
点赞 1 评论
分享

全站热榜

正在热议