目前vue3.0已进入最终测试版,rc(release candidata) 阶段意味着API已经成熟稳定,这个阶段只是改改bug,没有大问题的话不会有功能变动。
vue3.0为了兼顾2.x的升级,将支持2.x的大部分语法,像现在的
data, methods, computed,watch,生命周期等,减少升级成本,小范围可以试点使用了。附上官方的生命周期图,可以看出之前的beforeDestroy,destoryed没了。
一、搭建vue3.x
npm install -g @vue/clivue create vue-next-project这里在输入命令后,需要选择Manually select features, 至少要把 babel router 选上,(vuex 看自身情况是否需要),不选Typescript,毕竟在vue2.x上typescript用的不多,减低一些接受成本。cd vue-next-projectvue add vue-next
完成以上几步主体环境算搭建完成了。
弄个案例会发现Vue2.x的大部分支持。
整体体验感受,留意 组件里this操作 与 option API 的 composition API 的区别。
vue3 新特性
一、Fragments(片段)
在vue2.x 中,如果你创建了一个vue组件,那么它只能有一个根节点。使用vue2.x的开发者肯定遇到过,往往我们会主动去包一层div 来解决,致使dom 结构层级越来越深。
原因: 代表任何vue组件的vue实例都需要绑定到单个DOM 元素中。创建具有多个DOM节点的组件的唯一方法是创建一个没有基础vue实例的功能组件。
如下写法:
在vue2.x 中报错,vue3.x 是直接支持的。类似<react.Fragment>xxxx</react.Fragment> 的 。
当然,如果vue2.x要使用,可引入vue-fragments插件来解决。
import { Plugin } from "vue-fragments";
Vue.use(Plugin);
use
<template>
<v-fragment>
<div>Fragment 1</div>
<div>Fragment 2</div>
</v-fragment>
</template>
二、Teleport (传送门) 解决弹窗痛点
弄个模态功能,弹窗之类的,我们通常会将对应的dom 结构放置到</body>标签之前。
<body>
<div>
<!--main page content here-->
</div>
<!--modal here-->
</body>
这样做是因为模式会要求覆盖页面顶层,或者页面布局层级要求。在vue2.x 中,就需要操作Dom,管理dom 进行。在Vue3 中有了一个新的组件<teleport>,并且销毁teleport 组件时,会自动清空相应的Dom,无需人工处理。
案例:
- 首先在模板文件里加
<div id="teleportId"></div>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<div id="teleportId"></div>
</body>
- 之后就可以在组件任意地方写
teleport组件,最终都会放置的teleportId dom 结构中。
<template>
<div>
<div>
<p>这里是teleported, count 值为: {{ count }}</p>
<teleport to="#teleportId" v-if="count !== 3">
<div>
<div>我是组件里的内容</div>
<div @click="teleEvt">我是组件里的内容,搬定了事件</div>
</div>
</teleport>
</div>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
export default {
name: "HelloWorld",
setup() {
const state = reactive({
count: 0
});
const teleEvt = () => {
state.count++;
};
return {
teleEvt,
...toRefs(state)
};
}
};
</script>
有了这个teleport,后面这种document.body.appendChild 这种高难度操作慢慢就没了。
三、Suspense
Suspense功能性组件,它会先展示fallback组件,直到异步组件逻辑完成,在渲染异步组件。(setup函数执行ok,即可)
案例: 页面上使用
<template>
<div class="about">
<h1>This is an about page</h1>
<Suspense>
<testSuspense />
<template #fallback>
<p>Loading...</p>
</template>
</Suspense>
</div>
</template>
<script>
import testSuspense from "@/components/testSuspense.vue";
export default {
components: {
testSuspense
}
};
</script>
testSuspense 异步组件内容
<template>
<div>
<h1>suspense</h1>
<p>suspense 组件里的内容</p>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
export default {
name: "Hello Suspense",
async setup() {
const state = reactive({
count: 0
});
const _wait = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("ok");
}, 3000);
});
};
await _wait();
return {
...toRefs(state)
};
}
};
</script>
<style scoped>
h3 {
margin: 40px 0 0;
}
</style>
vue2.x 需要自行去判断组件是否加载完,加载ok 然后展示组件。可以看到类型如下骚操作
<template>
<div v-if="pageOk">xxxxx</div>
<div v-else>Loading....</div>
</template>
vite 新构建工具体验
目前 vite 是和 vue 3 搭配的,当然vite 还提供了 react、preat 相关的模板。
看一个图,你就明白vite 的革命性,未来可能革了 webpack 的命。
体验一下,感觉编译速度。
$ npm init vite-app <project-name>
$ cd <project-name>
$ npm install
$ npm run dev
2020-09-18,尤大建议不用立即升级到vue3.0版本,之前项目中的依赖项可能还不支持新版,等社群进一步完善再迁移。