在使用vue3时与vue2做对比区别与效率的提升

创建vue项目在使用v-cli和使用vite中的区别

比如mian.js中引入app.vue文件时后要把后缀名加上
    1、除了.js的后缀名不需要加后缀名,其他的都去要加上;而用v-cli中则不需要;
    2、index.html文件vite搭建的项目这个文件不是放在public文件夹下,而是放在根目录下
    3、打包vite做了优化,js文件体积变小了

在App.vue导入vue的区别

  • vue2

     import Vue from 'vue'
     import App from './App.vue'
    
  • vue3 具名导出

     import { createApp } from 'vue'
     import App from './App.vue'
    

使用vue创建vue实例不一样。vue3不存在构造函数,如何创建vue应用呢

  • vue2

       const app =new Vue(options);//返回的像组件实例
       app.$mount('#app');
    
  • vue3

       const app =new createApp(App);//返回的时一个纯vue实例对象,没有过多的$方法
       app.mount('#app')
    

组件中this的区别

vue2中this指代的就是这个vue组件实例

vue3中this指定时代理对象proxy,通过代理对象获取组件实例

template中的变化

在vue2中template中必须得用一个主元素包裹不然会报错 而在vue3中则不需要

vue2与vue3在标签或者组件中的ref="formRef"的dom元素的使用

  • vue2中直接使用this.$refs.formRef或者this.$refs['formRef']的方式就可以获取该组件或者dom的内容

  • vue3中由于setup函数中没有了this,那该如何使用呢?

    <div ref="mainContainer" ></div>
    setup() {
         const mainContainer = ref(null)
         onMounted(()=>{console.log(mainContainer)})
         return {
          mainContainer,
         }
    }
    
    • 由于setup函数创建时还没有VNode 所以想要使用该属性必须得在onMounted函数里面可以使用获取

vue3的效率提升主要表现在那些方面?

1、静态提升
2、预字符串化
3、缓存事件处理
4、Block tree
5、PatchFlag

具体说说这些的方面?

  • 静态节点

    • 没有绑定动态内容。什么是动态内容:比如动态绑定class/style,{{userInfo.name}}一些需要获取的数据
    • vue2与vue3作比较静态节点
      • 1、vue2的静态节点,通过预编译把template内容编译成render函数

          render(){
              createVNode('h1',null,'Hello World');
              //...
          }
        
      • 2、vue3的静态节点:首先直接定义一个变量去接收它,防止每次渲染的时候都去重新创建一个h1的虚拟节点【这个h1节点是不会变的所以不需要重新创建】

          const hoisted= createVNode('h1',null,'Hello World');
          function render(){
                  //直接使用histed
          }
        
  • 静态属性提升

    <div class="user">
          {{userInfo.name}}
    </div>
    
    • 这里div是动态的;但是div的class属性是静态的 vue3这里直接是把他定义出来

      **const histed={class:"user"}**
      function render(){
           createVNode('div',**histed**,userInfo.name);
           //...
      }
      
  • 预字符串化

      <div class="menu-bar-container">
          <div class="logo">
              <h1>logo</h1>
          </div>
          <ul class="nav">
          <li>< a href="" >menu</ a></li>
          <li>< a href="" >menu</ a>
          </li><li>< a href="" >menu</ a></li>
          <li>< a href="">menu</ a></li>
          <li>< a href="">menu</ a></li></ul>
          <div class="user">
             <span>{{ user.name }}</span>
          </div>
      </div>
    
    • 当编译器遇到大量连续的静态内容,绘制节将其编译为一个普通字符串节点

             const hoisted 2 =_ createStaticVNode("<div class=1"logol"><h1>logo</h1></div>
             <ul class=l"navl"<li>< a href= "l" >menu</ a></li><li><ahref="">menu</ a></li>
             <li>< a href=l"l">menu</ a>/li>li><ahref=l"l" >menu</a></li>
             <li>a href=V"N">menu</ a></li></ul>")
      
    • vue2会重新渲染虚拟节点,不管你是改变和不改变的都给你重新渲染 而vue3则是只重新创建动态的节点,而静态的改变数据时不会重新再去渲染,大大节省性能消耗 SSR(服务端渲染)里最明显

  • 缓存事件处理函数

    <button @click="count++" >puls</button>
    
    • vue2编译

           render(h){
               return createVNode("button",{
                   onClick:function($event){
                       h.count++;
                   }
               })
           }
      
    • vue3编译 【_cache缓存对象,编译的时候看一下这个缓存对象里面有没有这个函数,有的化就直接拿就不用再去创建,没有的化创建函数在赋值给缓存对象,大大节省性能消耗】

           render(h,_cache){
                   return createVNode("button",{
                       onClick:_cache[0]||(_cache[0]=($event)=>(h.count++))
                   }
                })
            }
      
  • Block tree

    • vue2在对比新旧树的时候,并不知道那些节点是静态的,那些是动态的,因此只能一层一层比较,这就浪费了大部分事件在对比静态节点上
    • vue3在对比的时候可以标记那些是动态节点,然后把这些动态节点放到根节点中,用一个数组记录这些动态节点,然后循环数组重新渲染这些,
  • PatchFlag

    • vue2在对比每一个节点时,并不知道这个节点那些星官信息会发生变化,因此只能将信息依次对比

    • vue3则会告诉你哪个地方什么东西时动态节点

           <div :class="user.name" data-id="1" title="user">
              <span :class="user.name">{{user.name}}</span>
           </div>
      编译后    
           export function render(_ctx,_cache) {
               return(_openBlock(),_createBlock("div", hoisted_1, [_ hoisted 2,_createVNode("div", f], {
                   class:[ "user", ctx.user. name ]
               },[_createVNode("span", {class:_ctx.user.name]},
                   _toDisplayString(_ctx.user.name), 3 /* TEXT, CLASS */)
               ],2/* CLASS */)   
           }
      如这里的: 3 /* TEXT, CLASS */就会告诉你,在span元素里面的text和class属性是动态的
                    2/* CLASS */ 表示div中的class属性是动态的
      

为什么vue3中去掉了vue的构造函数?

  • vue2的全局构造函数的静态方法会对所有vue应用生效,不利于隔离不同的应用如在一个html页面中, 可能会创建多个vue实例,但是你想给其中一个vue实例引入插件,但是一旦使用插件、全局的组件、全局的混合、全局的指令, 这样就会影响到其他vue应用,就相当于每个实例都得去获取这些插件,组件,混合和指令,有些不想用到,但是没办法改
  • vue2的构造函数集成了太多功能,不利于tree shaking,vue3把这些功能使用普通函数导出,能够充分利用 tree shacking优化打包体积
  • vue2没有把组件实例和vue应用两个概念区分开来,在vue2 中,通过new Vue创建的对象,既是一个vue应用,同时优势又一个特殊的vue组件。
  • vue3中把这两个概念区分开来了,通过createAPP创建的对象,是一个vue应用,它内部提供的方法是针对整个应用,而不再是一个特殊的组件

vue3数据响应式的理解

vue3不再使用Object.defineProperty的方式定义完成数据响应式,而是使用Proxy。

除了Proxy本身效率比Object.defineProperty更高之外,由于不必递归遍历所有属性,而是直接得到一个Proxy。

所以再vue3中,对数据的访问时动态的,当访问某个属性的时候,再看动态的获取和设置,这就极大的提升了再组件初始化阶段的效率

同时由于Proxy可以监控到成员的新增和删除,因此,再vue3中新增成员、删除成员,索引方式访问等均可以触发重新渲染,而这些再vue2中是难以做到的

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值