前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue篇(011)-vue3带来的新特性/亮点

Vue篇(011)-vue3带来的新特性/亮点

作者头像
齐丶先丶森
发布2022-05-12 21:10:34
1.1K0
发布2022-05-12 21:10:34
举报
文章被收录于专栏:前端面试秘籍前端面试秘籍

参考答案:

1. performance: 性能比vue2.x块1.2~2倍;

2. Tree shaking support: 按需编译,体积比vue2.x更小;

3. Composition API: 组合API(类似React Hooks);

4. Fragment, Teleport, Suspense: 更先进的组件;

5. Better TypeScript support: 更好的 ts 支持;

6. Custom Render API: 暴露了自定义渲染的API;

解析:

一,performance: 性能比vue2.x块1.2~2倍;

diff算法的优化

  1. 在vue2中,虚拟dom是全量比较的。
  2. 在vue3中,增加了静态标记PatchFlag。在创建vnode的时候,会根据vnode的内容是否可以变化,为其添加静态标记PatchFlag。diff的时候,只会比较有PatchFlag的节点。PatchFlag是有类型的,比如一个可变化文本节点,会将其添加PatchFlag枚举值为TEXT的静态标记。这样在diff的时候,只需比对文本内容。需要比对的内容更少了。PatchFlag还有动态class、动态style、动态属性、动态key属性等枚举值。

render阶段的静态提升(render阶段指生成虚拟dom树的阶段)

  1. 在vue2中,一旦检查到数据变化,就会re-render组件,所有的vnode都会重新创建一遍,形成新的vdom树。
  2. 在vue3中,对于不参与更新的vnode,会做静态提升,只会被创建一次,在re-render时直接复用。
  3. 静态提升可以理解为第一次render不参与更新的vnode节点的时候,保存它们的引用。re-render新vdom树时,直接拿它们的引用过来即可,无需重新创建。

事件侦听缓存

  1. 在vue2中,我们写的@click="onClick"也是被当作动态属性,diff的时候也要对比。但我们知道它不会变化,比如变成@click=“onClick2”,绑定别的值。
  2. 在vue3中,如果事件是不会变化的,会将onClick缓存起来(跟静态提升达到的效果类似),该节点也不会被标记上PatchFlag(也就是无需更新的节点)。这样在render和diff两个阶段,事件侦听属性都节约了不必要的性能消耗。

二,Tree shaking support: 按需编译,体积比vue2.x更小;

在vue3中,可以如下面这样引用vue的功能函数,如果你的项目没有用到watch,那编译时就会把tree shaking掉。

代码语言:javascript
复制
import { computed, watch, nextTick } from "vue";

利用的就是 ES6 模块系统import/export。

三,Composition API: 组合API(类似React Hooks);

composition-api 是一个 Vue3 中新增的功能,它的灵感来自于 React Hooks ,是比 mixin 更强大的存在。 composition-api 可以提高代码逻辑的可复用性,从而实现与模板的无关性;同时使代码的可压缩性更强。另外,把 Reactivity 模块独立开来,意味着 Vue3.0 的响应式模块可以与其他框架相组合。

如上图,composition-api 把复杂组件的逻辑抽地更紧凑,而且可以将公共逻辑进行抽取。

四,Fragment, Teleport, Suspense: 更先进的组件;

Fragment

在书写vue2时,由于组件必须只有一个根节点,很多时候会添加一些没有意义的节点用于包裹。Fragment组件就是用于解决这个问题的(这和React中的Fragment组件是一样的)。

这意味着现在可以这样写组件了。

代码语言:javascript
复制
/* App.vue */
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

<script>
export default {};
</script>

或者这样

代码语言:javascript
复制
// app.js
import { defineComponent, h, Fragment } from 'vue';

export default defineComponent({
  render() {
    return h(Fragment, {}, [
            h('header', {}, ['...']),
            h('main', {}, ['...']),
            h('footer', {}, ['...']),
        ]);
  }
});

Teleport Teleport其实就是React中的Portal。Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。 一个 portal 的典型用例是当父组件有 overflow: hidden 或 z-index 样式时,但你需要子组件能够在视觉上“跳出”其容器。例如,对话框、悬浮卡以及提示框。

代码语言:javascript
复制
/* App.vue */
<template>
    <div>123</div>
    <Teleport to="#container">
        Teleport
    </Teleport>
</template>

<script>
import { defineComponent } from "vue";

export default defineComponent({
    setup() {}
});
</script>

/* index.html */
<div id="app"></div>
<div id="container"></div>
Suspense

同样的,这和React中的Supense是一样的。

Suspense 让你的组件在渲染之前进行“等待”,并在等待时显示 fallback 的内容。

代码语言:javascript
复制
// App.vue
<template>
    <Suspense>
        <template #default>
      <AsyncComponent />
        </template>
        <template #fallback>
            Loading...
        </template>
    </Suspense>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import AsyncComponent from './AsyncComponent.vue';

export default defineComponent({
  name: "App",
  
  components: {
    AsyncComponent
  }
});
</script>

// AsyncComponent.vue
<template>
    <div>Async Component</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

const sleep = () => {
    return new Promise(resolve => setTimeout(resolve, 1000));
};

export default defineComponent({
    async setup() {
        await sleep();
    }
});
</script>

五,Better TypeScript support: 更好的 ts 支持;

  1. vue2不适合使用ts,原因在于vue2的Option API风格。options是个简单对象,而ts是一种类型系统、面向对象的语法。两者有点不匹配。
  2. 在vue2结合ts的具体实践中,要用 vue-class-component 强化 vue 组件,让 Script 支持 TypeScript 装饰器,用 vue-property-decorator 来增加更多结合 Vue 特性的装饰器,最终搞的ts的组件写法和js的组件写法差别挺大。
  3. 在vue3中,量身打造了defineComponent函数,使组件在ts下,更好的利用参数类型推断 。Composition API 代码风格中,比较有代表性的api就是 ref 和 reactive,也很好的支持了类型声明。
代码语言:javascript
复制
import { defineComponent, ref, PropType, reactive } from 'vue'
import { Student } from '../store'
export default defineComponent({
  props: {
    success: { type: String },
    student: {
      type: Object as PropType<Student>,
      required: true
    }
  },
  setup() {
    const year = ref(2020)
    const state = reactive({ count: 3 });

    function handleClick() {
      state.count++;
    }
    return { year, state, handleClick };
  }
})

六,Custom Render API: 暴露了自定义渲染的API;

下面我们可以看到vue2和vue3的入口写法有所不同

代码语言:javascript
复制
// vue2
import Vue from 'vue'
import App from './App.vue'
new Vue({ => h(App)}).$mount('#app')

// vue3
const { createApp } from 'vue'
import App from "./src/App"
createApp(App).mount(('#app')

vue官方实现的 createApp 会给我们的 template 映射生成 html 代码,但是要是你不想渲染生成到 html ,而是要渲染生成到 canvas 之类的不是html的代码的时候,那就需要用到 Custom Renderer API 来定义自己的 render 渲染生成函数了。

代码语言:javascript
复制
// 你自己实现一个createApp,比如是渲染到canvas的。
import { createApp } from "./runtime-render";
import App from "./src/App"; // 根组件

createApp(App).mount('#app');

七,更快的开发体验(vite开发构建工具)

在使用webpack作为开发构建工具时,npm run dev都要等一会,项目越大等的时间越长。热重载页有几秒的延迟,但是如果用vite来做vue3的开发构建工具,npm run dev 秒开,热重载也很快。这种开发体验真是很爽,拒绝等待。

vite的原理还是用了浏览器支持import关键字了,启动项目不用webpack构建工具先构建了,浏览器直接请求路由对应的代码文件,代理服务器针对单个文件进行编译并返回。如果请求的文件里还import了其他文件,同理浏览器继续发请求,代理服务器返回。就这样实现了npm run dev时无需编译,实时请求实时编译。

总结:

其他的,数据监听方式变成了Proxy,消除了Object.defineProperty现有的限制(例如无法检测新的属性添加),并提供更好的性能。

vue3解决了vue2的一些问题,大型应用的性能问题、ts支持不友好问题,自定义渲染API解决体系架构存在的问题,如果在vue3的基础上实现weex框架会好很多。也做出了很多优化,Compostion API让代码的组织形式更好。vite开发构建工具让开发体验更好,Tree shaking让包更小、性能更优。

总的来说vue3还是非常棒的,带来了很多非常好的新特性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端面试秘籍 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Fragment
  • Suspense
  • 七,更快的开发体验(vite开发构建工具)
  • 总结:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档