渐进式使用vue3

2,477 阅读3分钟

目前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/cli
  • vue create vue-next-project 这里在输入命令后,需要选择Manually select features, 至少要把 babel router 选上,(vuex 看自身情况是否需要),不选Typescript,毕竟在vue2.x上typescript用的不多,减低一些接受成本。
  • cd vue-next-project
  • vue 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版本,之前项目中的依赖项可能还不支持新版,等社群进一步完善再迁移。

Vue 3.0 中文文档仓库

Vue 3.0 中文文档