将你的项目从Angular迁移至Vue需要注意什么?

如果你是一名前端开发工程师

且正在尝试将你的项目从 Angular迁移至 Vue

那么本篇文章可以帮你少踩一些坑

介绍

因为公司项目需要 TS 语言的支持

在开发项目时使用的是 Vue Class Component 写法,如下:

在本篇中涉及到的语法大部分都是基于此,请知悉

LifeCycle

钩子AngularVue
构造函数constructor()created()
初始化ngOnInit()mounted()
视图渲染完成ngAfterViewInit()mounted()【存疑】

Class

Angular

1
2
// 在 ts 文件中
export class HelloComponent implements OnInit{}

Vue

1
2
// 在 vue 文件的 `<script>` 标签中
export default class HelloComponent extends Vue{}

Service

1. 导入导出

Angular

1
2
3
@Injectable()
export class ModelOperationService {
}

Vue

1
2
3
import {HttpRequestService} from '@/apis/http-service';
export default class ModelOperationService extends HttpRequestService {
}

2.注入

Angular

1
2
3
// 在 Angular 中是有构造函数的概念的,而一些服务是直接在构造函数中注入的
public constructor(private translateService: TranslateService) {
}

Vue

1
2
3
4
5
// 在 Vue 中是没有构造函数的概念的,所以直接在导出的 class 中直接实例化即可
private userService = new UserService();
// 同时多个组件使用同一个服务时,需要注意是否采用单例模式,例如用户信息,只需要在登录的时候获取即可
// 这里的SingleFactory是自己封装的单例模式
private userService = SingleFactory.getInstance(UserService);

父子组件

1.输入输出

比较项AngularVue
输入@Input()@Prop()
输出@Output()@Emit()
输入初始值可以通过 = 来直接赋值不可通过 = 直接设置初始值,需要使用 default 项来指明
输出类型事件类型函数,且返回具体的值
仓库Github

2.引入子组件

Angular

1
2
@ViewChild('tag', { static: false })
public customerTag: CustomerTagComponent;

Vue

1
2
3
4
5
6
7
8
// 模板
<CustomerTag ref="customerTag"></CustomerTag>
// 逻辑
@Ref('customerTag')
public customerTag: CustomerTag;

@Ref('customerTag')
public customerTag: InstanceType<typeof CustomerTag>;

3.获取组件中的元素

Angular

1
2
3
4
// 通过el来进行获取类名为total的元素
constructor(private el: ElementRef) { }
// 调用
this.el.nativeElement.querySelector('.total');

Vue

1
2
3
4
5
// 通过ref来获取类名为total的元素
@Ref('total')
public total: HTMLDivElement;
// 调用
this.container;

日期格式化

Angular 中自带了 formatDate 日期格式化

Vue解决方法:

  • moment.js —— vue-moment
  • day.js
  • 自己封装格式化逻辑

对比如下:

比较项Moment.jsDay.jsdate-fns
大小16.7k(重)2.87k(轻)5.76k(轻)
最后更新时间2021.02(停止开发,仅维护)2021.092021.12
优势支持number类型直接转换为时间对象返回新的实例,不可变数据,支持链式操作,API与Moment一致,支持插件模块化加载,适用复杂项目,不可变性和纯粹性
劣势可变对象不支持number类型直接转换不支持全局导入
浏览器兼容FireFox与Safari有异常全浏览器
Tree-shaking不支持不支持支持
模式OOOOFunctional
国际化支持支持支持
TypeScript支持支持支持
LicenseMITMITMIT
文档中文中文外文
仓库GitHubGitHubGitHub

参考链接:

国际化

对比如下:

比较项AngularVue
插件ngx-translatevue-i18n
html内容中使用{{'public' | translate}}{{ $t('public') }}
html标签中使用<span translate='public'></span><span v-t="'public'"></span>
属性中使用<span :title="$t('public')">public</span>
ts/js文件中使用translate.instant('public')this.translate.t('public');