项目背景:
一个以前的项目( 刚入职实习的时候写的,用的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的配置项
具体可以看官网自己配置: https://www.tslang.cn/docs/handbook/compiler-options.html
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还有别的key for(let i in this.obj){ if(this.initObj(i)!=undefined){ this.initObj[i]=this.obj[i] } } //或者 写一个函数,如果key值一样就赋值
槽点3:switch case 判断之前的代码:
//片段,有十几个case optionList:['饼图','柱状图','折线图','...'] 筛选下拉后,aa为index switch (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重构项目的实现的文章就介绍到这了,更多相关ts+vuecli4重构内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!