这篇主要是笔记。(我估计会是第一篇,因为只迁移了一个项目)
1. 安装新包
只记录必须重装的:
npm i vue@3 vue-loader@16.0.0-beta.8 vue-router@4.0.0-beta.13 @vue/compiler-sfc
2. 修改 Webpack 配置
// v2
const VueLoaderPlugin = require('vue-loader/lib/plugin');
// v3
const {VueLoaderPlugin} = require('vue-loader');
// for DefinePlugin
{
plugins: [
new DefinePlugin({
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
}),
],
}
3. 修改入口文件
没有 new Vue({})
了,取而代之的是 Vue.createApp({})
,后者还支持 tree-shaking。
也不需要注册 Vue-router 了,直接 app.use(router) 就好。所以传统的入口文件就要修改为:
// v2
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './app';
import 'bootstrap/dist/css/bootstrap.min.css';
import '@/styl/index.styl';
import router from './router';
Vue.use(VueRouter);
Vue.config.productionTip = false;
new Vue({
router,
...App,
}).$mount('#app');
// v3
import {createApp} from 'vue';
import App from './app';
import 'bootstrap/dist/css/bootstrap.min.css';
import '@/styl/index.styl';
import router from './router';
const app = createApp({
...App,
});
app.use(router);
app.mount('#app');
4. 修改 router
Vue-router 的变化很大,建议大家好好看看 迁移手册。就我厂这个项目而言,主要是三个变化:
- 使用支持 tree-shaking 的函数
createRouter
等 - 修改
history: createWebHistory()
- 使用渲染函数
h
替换之前渲染方式
// 加载方式
import {h} from 'vue';
import {
createRouter,
createWebHistory,
createWebHashHistory,
RouterView,
} from 'vue-router';
const routes = [
{
path: '/',
name: 'home',
component: {
// vue-router v3
render(createElement) {
return createElement('router-view');
}
// vue-router v4
render() {
return h(RouterView);
},
},
children: components,
},
// ....
];
const router = createRouter({
// vue-router v3
mode: process.env.NODE_ENV === 'production' ? 'history' : 'hash',
// vue-router v4
history: process.env.NODE_ENV === 'production'
? createWebHistory()
: createWebHashHistory(),
scrollBehavior: (to) => {
if (to.hash && !/^#/.test(to.hash)) {
return {selector: to.hash};
}
// 这里有个小改动,x => left, y => top,简单提一下
return {top: 0};
},
routes,
});
5. 自定义组件 v-model
修改
- prop:
value
=>modelValue
- event:
input
=> `update:modelValue`
6. 一些小修改
beforeDestroy
=>beforeUnmount
7. createApp
与 Application,与 Component
v2 时,我们可以通过 new Vue({})
初始化 Vue 实例。这个阶段,Vue 默认有一个全局对象 + 若干个实例,除了 local 的,就是全局的。
v3 时,引入了 Application(应用)的概念,在全局和组件之间,增加了一个新的层级。这样一来,我们就可以在同一个 Web 产品中,使用 Application 来划分命令、组件、mixins 的范围。应该会增加代码的强壮程度(虽然我暂时还没用到)。
不过,迁移代码的时候,也要注意。以前我们可能 new
一个实例,调用它的 methods
;现在不行了,要这样做:
// v2
const ins = new Vue({});
ins.doSomething();
// v3
const app = createApp({});
const vm = app.mount('$el');
vm.doSomething();
8. 新的响应式 API
v3 最大的变化就是重构了响应式实现,所以新增了不少响应式 API。同时,也会检查开发者的代码,如果发现不需要响应式的地方用到响应式对象,就会提示开发者,因为响应式会增加系统开销。
这个时候可以用 markRaw
和 toRaw
方法来修改对象,撤销之前附加在上面的响应式属性,提高访问效率。
其它 API 还很多,后面慢慢更新吧。
9. Devtool 和 SourceMap
遗憾的是,目前 Vue Devtool 无法检测到 Vue。老项目的 SourceMap 也完全不生效,无法正常对 SFC 进行 debug。
欢迎吐槽,共同进步