这篇文章主要讲解了如何实现ts+vuecli4重构项目,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

项目背景:

一个以前的项目( 刚入职实习的时候写的,用的vuecli2 ),然后这次要添加修改东西,看着代码看的头大,冲动之下就重构了( 想打死自己,写的啥玩意 ),刚好用下最近刚学的typescript,从搭建开始,一步步更新记录下,怕自己之后忘了再回过头来看看。( 顺便说一句,用起来有点别扭,不过还是挺爽的,期待vue3.0... )

一.项目搭建:

使用命令 vue create news创建项目

配置自定义,贴一下我自定义的安装依赖

ts+vuex+router这几个肯定是要的,这里的css我选择的是scss,unit测试也来一个

之后一些的选项就自己选择

3. 搭建好后目录就是这样

├── public // 静态页面├── src // 主目录 ├── assets // 静态资源 ├── components // 组件 ├── views // 页面 ├── App.vue // 页面主入口 ├── main.ts // 脚本主入口 ├── router.ts // 路由 ├── shims-tsx.d.ts // 相关 tsx 模块注入 ├── shims-vue.d.ts // Vue 模块注入 └── store.ts // vuex 配置├── tests // 测试用例├── .eslintrc.js // eslint 相关配置├── .gitignore // git 忽略文件配置├── babel.config.js // babel 配置├── postcss.config.js // postcss 配置├── package.json // 依赖└── tsconfig.json // ts 配置

想着为了以后更好的维护,就修改了一下目录结构

├── public // 静态页面├── src // 主目录 ├── api // 接口 ├── assets // 静态资源 ├── filters // 过滤 ├── store // vuex 配置 ├── styles // 样式 ├── utils // 工具方法(axios封装,全局方法等) ├── views // 页面 ├── App.vue // 页面主入口 ├── main.ts // 脚本主入口 ├── router.ts // 路由 ├── shime-global.d.ts // 相关 全局或者插件 模块注入 ├── shims-tsx.d.ts // 相关 tsx 模块注入 ├── shims-vue.d.ts // Vue 模块注入, 使 TypeScript 支持 *.vue 后缀的文件├── tests // 测试用例├── .eslintrc.js // eslint 相关配置├── postcss.config.js // postcss 配置├── .gitignore // git 忽略文件配置├── babel.config.js // preset 记录├── package.json // 依赖├── README.md // 项目 readme├── tsconfig.json // ts 配置└── vue.config.js // webpack 配置

tsconfig.js是ts的配置项

4.初步修改vue.config.js

const path = require("path");const webpack = require('webpack');function resolve(dir) { return path.join(__dirname, dir)}const router='http://xxx.xxx.xxx'module.exports = { publicPath: "./", //基本路径 outputDir: 'dist', //打包时生成的文件夹 lintOnSave: process.env.NODE_ENV === 'development', productionSourceMap: process.env.NODE_ENV === 'development', devServer: { port: 8080, open: true, proxy: { '/test': { target: router, changeOrigin: true } } }, configureWebpack: { name: process.env.VUE_APP_NAME, resolve: { alias: { '@': resolve('src'), } }, externals: {}, plugins: [], },}

至此,项目初步搭建完成,然后就开始封装安装插件

二. 安装插件和基本内容填充

这里我使用 的element-ui,echarts, babel-polyfill,jquery等

这里有个注意的,在typescript 中使用jquery,echarts等插件的 时候,必须要安装对应的声明文件,当然typescripe社区已经有很多大佬写好了,前人种树,后人乘凉复制代码

什么是声明文件:

https://github.com/xcatliu/typescript-tutorial/blob/master/basics/declaration-files.md

声明文件搜索地址: microsoft.github.io/TypeSearch/

untils 文件夹(可以放一些常用的工具函数,节流、防抖、localStorage等)

这个里面我存放了一些工具函数,date函数,axios的封装等

styles 文件夹 (存放全局scss文件)

这里面除了初始化一些样式外,我还定义了一些常亮,例如导航栏的高度,颜色等,便于 好改

router 文件夹(懒加载)

因为这个系统权限之类的并没有很复杂,路由也不是很多,就没有按模块引入,就直接写了。

/* webpackChunkName: "login" */ /*这里名字是什么,打包出来的名字就是什么*/ { path: '/', name: 'login', component: () => import(/* webpackChunkName: "login" */ '@/views/login/index.vue'), meta: { title:'登录页' keepAlive: false, } }, { path: "/home", name: "home", redirect: "/homepage", component: () => import(/* webpackChunkName: "home" */"@/views/Home.vue"), children: [ { path: "/homepage", component: () => import(/* webpackChunkName: "homepage" */ "@/views/homepage/index.vue"), name: "homepage", meta: { title: "首页", keepAlive: true } }, ]}

api 文件夹

根据不同模块的接口,去建不同的文件

三.vue中typescript的写法

typescript的写法和vue差不多,只是script的区别,例:

import { Component, Prop, Vue, Watch } from 'vue-property-decorator'@Component({ name: 'homepage', components: {}})export class MyComponent extends Vue { @Prop({ default: '' }) private name!: string @Watch('name', { deep: true }) changeName(newVal,olVal){} //data private count:number=5 private arr:string[]=[] mounted(){} //methods private test(){}}

四.typescript使用中的问题

1.获取refs

写法:

let layoutList:any = this.$refs.layout as HTMLDivElement

2.引用插件,且找不到声明文件或引用Json文件

在shims-vue.d.ts 文件中声明,再在组件中引用

declare module "*.json" { const value: any; export default value;}declare module "vue-count-to" { const count: any; export default count;}

页面里面

import * as myJson from '../../../public/test.json'

使用 myJson.default

3.计算属性

get age() { return this.aTagDatasF.filter(item => item.visible)}

4.@prop

@Prop()private datas!: any

感叹号是非null和非undefined的类型断言,所以上面的写法就是对datas这个属性进行非空断言

5.引入vue组件时,后面必须加 .vue

6.定义接口类型,前面加 I,例如,接口尽量定义类型,规范管理

interface IUserInfo{ name:string, index:number}

7.定义全局变量(可以用vuex取代)

在.ts文件里面

export var User:IUserInfo={ name:'111', index:996}

其他页面import ,然后 就可以获取到这个值

8.强行让ts不检测

//@ts-ignore 下一行不检测

五.开始改造页面代码(开始吐槽自己)

槽点1:组件切换

以前的代码(部分片段)

改造后:用component 用is去动态判断就行

<div class="haveClick> <component :is="echartsIndex" :obj="obj"/></div>

槽点2:对象赋值

以前的代码(部分片段):

改造后:

//这样写是因为initObj还有别的keyfor(let i in this.obj){ if(this.initObj(i)!=undefined){ this.initObj[i]=this.obj[i] }}//或者 写一个函数,如果key值一样就赋值

槽点3:switch case 判断之前的代码:

//片段,有十几个caseoptionList:['饼图','柱状图','折线图','...']筛选下拉后,aa为indexswitch (aa) { case 0: this.getData() break; case 1: this.avgBqzs() break; case 2: this.areaCount() break; case 3: this.yiqing() break; case 4: this.avgFinish() break; }

修改后:

private optionList=[{ title:'饼图', type:'getData'},{ title:'柱状图', type:'avgBqzs'} ......] 下拉后,用change事件获取 item (这里就不获取index了)例如:changeSelect(item:any){ //当然这里不能通过ts的编译 @ts-ignore this[item.type]()}

六.个人项目规范

1.尽量不要使用for,使代码观赏性更高

forEach 遍历 , map转换,filter 过滤

2.调接口使用 尽量 async和await来调用接口

例如:

private async getData() { const { data } = await getTransactions({})}

3.只需要部分筛选条件的时候用解构去获取值

public sizeTop={ id:'', City:'', County:'', time:''}const {City,County}=this.sizeTop private async getData() { const { data } = await getTransactions({City,County}) }

看完上述内容,是不是对如何实现ts+vuecli4重构项目有进一步的了解,如果还想学习更多内容,欢迎关注亿速云行业资讯频道。