前言
本文是博主vue实战系列中的一篇,本系列不是专业的前端教程,是专门针对后端熟悉前端的。前面我们用vue实现了一个基础的管理系统,前文专栏地址:
https://blog.csdn.net/joker_zjn/category_12469788.html?spm=1001.2014.3001.5482
接下来我们要基于typescript来重构该项目。
目录
目录
前言
目录
搭架子
安装依赖
迁移配置
迁移其它
重构路由
api重构
搭架子
重新建一个项目来做ts的重构吧。
npx vue create project-ts
不要选择vue2还是vue3,而是选择手动设置,在手动设置里,选择上ts:
选择配置上以下内容:
然后选择2.X版本,做以下配置:
创建出来的项目的目录结构:
可以看到由于上面选择了支持ts,main.js变成了main.ts,而且代码的工程目录中多了很多关于ts的配置文件:
-
shims-vue.d.ts,用来支持在ts中使用vue
-
tsconfig.json,用来对ts进行配置
安装依赖
架子搭好了,下一步就是安装依赖。
cnpm i element-ui font-awesome axios echarts@4 -S
迁移配置
仔细想想项目里会有哪些配置?无非就是vue的配置文件,vue.config.js以及main.js。
在新项目中建一个vue.config.js,把vue的配置从老项目中复制过去,并追加一些对webpack的配置:
module.exports = { devServer:{ open:true, host:'localhost', //配置代理 proxy:{ '/api':{ //目标地址 target:'http://127.0.0.1:8081/api/', //开启跨域 changeOrigin:true, pathRewrite:{ '^/api':'' } } } }, //对webpack进行配置 chainWebpack(chainWebpack){ chainableWebWebpack.resovle={extensions:['.js','.ts','.json','.d.ts']} } }
然后将老项目的main.js手动合并到新的项目的main.ts中来:
在合并过程中有可能有些import会报错,把对应的依赖在node_moudle中删除重新install即可。
import Vue from "vue"; import App from "./App.vue"; import router from "./router"; // import '../plugins/element.js' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import 'font-awesome/css/font-awesome.min.css'; import axios from "axios"; //import service from './utils/service'; import echarts from 'echarts'; Vue.use(ElementUI) //挂载到原型,可以在全局使用 Vue.prototype.axios=axios // Vue.prototype.service=service; Vue.config.productionTip = false Vue.prototype.$echarts=echarts Vue.config.productionTip = false; new Vue({ router, render: (h) => h(App), }).$mount("#app");
然后我们会发现,还有老项目中的service.js还要合过来,其实不止service.js,utils下面的所有js都要拿过来:
直接把整个utils文件夹拿过来吧。
然后需要在shims-vue中配置将echarts和自己写的这些js暴露出来,在main.ts中才能被引用到:
declare module "*.vue" { import Vue from "vue"; export default Vue; } //有一些第三方库和自定义的js或者三方的js,并不支持ts //用declare module可以将其完成兼容,从而在ts中import它们 declare module 'echarts' declare module '*.js'
迁移其它
配置和依赖都迁移完了,接下来该迁移其它东西了。其它还有什么?
assert文件夹、router文件夹、api文件夹、component文件夹、app.vue
将这些全数复制过来覆盖新项目默认初始化出来的即可。
重构路由
由于现在项目用的是ts不是js,所以要将原来的router.js重构为router.ts,项目初始化后router.js中是有配置示例的,直接将原来的路由里面的各个路由放入这个数组中即可:
import Vue from "vue"; import Router from "vue-router"; const routes: Array<any> = [ { path: "/", redirect: "/login", name: "首页", hidden: true, component: () => import("@/components/Login.vue"), }, { path: "/login", name: "Login", hidden: true, component: () => import("@/components/Login.vue"), }, { path: "/home", name: "学生管理", iconClass: "fa fa-users", //默认转跳到学生管理页 redirect: "/home/student", component: () => import("@/components/Home.vue"), children: [ { path: "/home/student", name: "学生列表", iconClass: "fa fa-list", component: () => import("@/components/students/StudentList.vue"), }, { path: "/home/info", name: "信息列表", iconClass: "fa fa-list-alt", component: () => import("@/components/students/InfoList.vue"), }, { path: "/home/infos", name: "信息管理", iconClass: "fa fa-list-alt", component: () => import("@/components/students/InfoLists.vue"), }, { path: "/home/work", name: "作业列表", iconClass: "fa fa-list-ul", component: () => import("@/components/students/WorkList.vue"), }, { path: "/home/workMent", name: "作业管理", iconClass: "fa fa-list", component: () => import("@/components/students/WorkMent.vue"), }, ], }, { path: "/home/dataview", name: "数据分析", iconClass: "fa fa-bar-chart", component: () => import("@/components/Home.vue"), children: [ { path: "/home/dataview", name: "数据概览", iconClass: "fa fa-list", component: () => import("@/components/dataAnalysis/DataView.vue"), }, { path: "/home/mapview", name: "地图概览", iconClass: "fa fa-line-chart", component: () => import("@/components/dataAnalysis/MapView.vue"), }, { path: "/home/travel", name: "旅游地图", iconClass: "fa fa-line-chart", component: () => import("@/components/dataAnalysis/ScoreMap.vue"), }, { path: "/home/score", name: "分数地图", iconClass: "fa fa-line-chart", component: () => import("@/components/dataAnalysis/TravelMap.vue"), }, ], }, { path: "/users", name: "用户中心", iconClass: "fa fa-user", component: () => import("@/components/Home.vue"), children: [ { path: "/home/user", name: "用户概览", iconClass: "fa fa-list", component: () => import("@/components/users/User.vue"), }, ], } ]; Vue.use(Router); const router = new Router({ mode: "history", routes, }); export default router;
唯一要注意的是,给各个组件跟上.vue,这是因为ts是有类型概念的,所以其类型检查要比js严格,使用js时路由转跳配置中组件可以没有后缀名,构建工具会在各类后缀名中反复尝试。但是到了ts,由于有强类型的概念了,构建工具就不会去自动尝试了而是一板一眼的来编译。所以在使用ts时强制要求声明文件后缀名,否则会报错。
api重构
在api目录下新建一个api.ts,将原来api.js中的内容拷贝过来,然后修改为ts。
首先在src下面创建一个type.d.ts,这是
然后拿原来的登陆方法login来示例。
先在type.d.ts中定义实体类:
export interface IUserData{ username:string; password:string; }
然后在api.ts中调用:
import { IUserData } from '../types'; export function login(data:IUserData){ return service({ method:'post', url:'/login', data }) }
最后改造出来的结果:
import service from '../utils/service.js' import { IUserData } from '../types'; export function login(data:IUserData){ return service({ method:'post', url:'/login', data }) } export function students(params:any){ return service({ method:'get', url:'/student/list', params }) } export function studentDel(id:any){ return service({ method: 'delete', url:`/student/${id}` }) } export function info(data:any){ return service({ method:'post', url:'/student/info', data }) } export function getInfo(){ return service({ method:'get', url:'/student/info' }) } //信息列表修改接口 export function updateInfo(data:any){ return service({ method:'put', url:'/student/info', data }) } export function deleteInfo(id:any){ return service({ method:'delete', url:`/student/info/${id}` }) }
api.ts写好后,api.js就可以删掉了,然后全局搜一下把对api.js的引用全部改为api.ts。