Vue2.0与Vue3.0的区别

对比

入口使用方式

首先我们先打开main.js文件,会发现它与过去的版本发生了一些变化:

//vue3.0
import { createApp } from 'vue';
import App from './App.vue'
createApp(App).mount('#app')

//vue2.0
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
  render: h => h(App),
}).$mount('#app')

常用方法

接下来我会从以下几个属性及常用的方法,将2.0和3.0进行一些对比:

  • Data
  • Method
  • LifeCycle
  • Computed
  • Components
  • Props,Emit
1.Data使用变化

// vue2.0 Data返回的对象
export default {
  data(){
    return{

    }
  }
},
// 取而代之是使用以下的方式去初始化数据:
<template>
  <div class="hello">
    123
  </div>
  <div>{{name.name}}</div>
</template>

import { reactive } from 'vue' 
export default {
 setup(){
   const name = reactive({
     name:'hello 番茄'
   })
   return {name}
 }  
}

tip:在新版当中setup等效于之前2.0版本当中得到beforeCreate,和created,它是在组件初始化的时候执行,甚至是比created更早执行。值得注意的是,在3.0当中如果你要想使用setup里的数据,你需要将用到值return出来,返回出来的值在模板当中都是可以使用的。

假设如果你不return出来,而直接去使用的话浏览器是会提醒你:

runtime-core.esm-bundler.js?5c40:37 [Vue warn]: Property "name" was accessed during render but is not defined on instance. 
  at <Anonymous>  
  at <Anonymous> (Root)

这个也是3.0当中需要注意的地方。细心的朋友应该已经发现,我在模板里放入2个子节点,其实这个在2.0里是不被允许的,这也是3.0的一项小的改变 reactive是3.0提供的一个数据响应的方式,它主要是对对象进行数据响应,接下来会介绍另一种数据响应的方式ref。

2.Method使用变化
<template>
  <div class="hello">
    <div>{{name.name}}</div>
    <div>{{count}}</div>
    <button @click="increamt">button</button>
  </div>
</template>

<script>
import {reactive,ref} from 'vue'
export default {
 setup(){
   const name = reactive({
     name:'王'
   })
   const count=ref(0)
   const increamt=()=>{
     count.value++
   }
   return {name, count, increamt}
 }  
}

在介绍Method的代码中,我引用了vue提供的ref新函数,它的作用是用来创建一个引用值,它主要是对String,Number,Boolean的数据响应作引用。也许有人会问,为什么不直接给count赋值,而是采用ref(0)这样的方式来创建呢,按我的理解就是,如果直接给count赋值就是等于把这个值直接抛出去了,就很难在找到它,而采用ref这种方法等于你在向外抛出去值的是同时,你还在它身上牵了一根绳子,方便去追踪它。

需要注意的时,在ref的函数中,如何你要去改变或者去引用它的值,ref的这个方法提供了一个value的返回值,对值进行操作。

3.LifeCycle(Hooks)

3.0当中的生命周期与2.0的生命周期出现了很大的不同:

  • beforeCreate -> 请使用 setup()
  • created -> 请使用 setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured
import {reactive, ref, onMounted} from 'vue'
export default {
 setup(){
   const name = reactive({
     name:'王'
   })
   const count=ref(0)
   const increamt=()=>{
     count.value++
   }
   onMounted(()=>{
     console.log('123')
   })
   return {name,count,increamt}
 }  
4.computed
<template>
  <div class="hello">
    <div>{{name.name}}</div>
    <div>{{count}}</div>
    <div>计算属性{{computeCount}}</div>
    <button @click="increamt">button</button>
  </div>
  
</template>

<script>
import {reactive, ref, onMounted,computed} from 'vue'
export default {
 setup(){
   const name = reactive({
     name:'王'
   })
   const count = ref(0)
   const increamt = ()=>{
     count.value++
   }
   const computeCount = computed(()=>count.value*10)
   //使用computed记得需要引入,这也是刚接触3.0容易忘记的事情
   onMounted(()=>{
     console.log('123')
   })
   return {name, count, increamt, computeCount}
 }  
}
</script>

5.Props,Emit

Vue2.0 样例

  • 父组件
<template>
  <div id="app">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>
  • 子组件
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data(){
    return{
      
    }
  },
  method:{
    handleClick(){
      this.$emit('childclick','123')
    }
  }
}
</script>

以上是最常见的父子组件之间的调用,但是在vue3.0中就存在差异。
vue3

  • 父组件
<template>
  <div class="hello">
    <div>123</div>
  <NewComp :name="name" @childClick="parentClick"/>
  </div>
  
</template>

<script>
import {reactive} from 'vue'
import NewComp from './newComp.vue'
export default {
  components:{
    NewComp
  },
 setup(){
   const name=reactive({
     name:'hello 番茄'
   })
   const parentClick=(e)=>{
     console.log(e)
     console.log('123')
   }
   return {name,parentClick}
 }  
}
</script>
  • vue3 子组件
<template>
    <div>
        <button @click="handleClick">组件</button>
    </div>
</template>

<script>
export default {
    setup(props,{emit} ){
        const handleClick=()=>{
            emit('childClick','hello')
        }
        return {
            props,
            handleClick
        }
    }
}
</script>

通过上面的vue3.0父子组件之间的调用,我们不难发现:

  1. 父组件当中在调用子组件时,基本与2.0相同,
  2. 在子组件当中,要想获取到父组件传递过来的参数,我们是直接在setup()中直接获取到props值和emit事件。

这是因为setup为我们提供了props以及context这两个属性,而在context中又包含了emit等事件。

变化

vue3的变化可以总结为以下几点:

  • 更小
  • 更快
  • 加强typescript支持
  • Api一致性
  • 提高可维护能力
  • 开放更多底层功能

其中前三点是最主要的变化。

更小:

vue2采用面向对象编程的思想,vue3则采用函数式编程的思想。

/// vue2源码中代码是这样组织的:
function vue(){...} 
vue.prototype.init = ...

/// vue3源码中是这样组织的:
//监听方法:
function watch(){...} 
//渲染方法:
function render(){...}

原因:充分利用函数式编程组合大于继承的优势,采用函数式编程更利于逻辑功能的复用,webpack打包时更有利于tree-shaking,更利于代码的压缩,更利于返回值类型校验,压缩后的文件体积更小。

更快:

vue3修改了虚拟dom的算法

vue2需要diff所有的虚拟dom节点,而vue3参考了SVELTE框架的思想,先分层次-然后找不变化的层-针对变化的层进行diff,更新速度不会再受template大小的影响,而是仅由可变的内容决定。经过尤雨溪自己的测试,大概有6倍的速度提升。

加强typescript支持:

vue3的源码开始采用了ts进行编写,给开发者也提供了支持ts的开发模式。

Api一致性

vue3最开始的版本可以完美兼容vue2的api。

提高可维护能力

从源码的层面上提供了更多的可维护能力。

开放更多底层功能

把更多的底层功能开放出来,比如render、依赖收集功能,我们可以更好的进行自定义化开发,可以写更多的高阶组件。

最后我们再谈谈两者在数据双向绑定方面的区别。

数据双向绑定:

关于数据双向绑定的实现,vue2 采用了defineProperty,而vue3则采用了proxy。

优点:

使用proxy不污染源对象,会返回一个新对象,defineProperty是注入型的,会破坏源对象
使用proxy只需要监听整个源对象的属性,不需要循环使用Object.defineProperty监听对象的属性
使用proxy可以获取到对象属性的更多参数,使用defineProperty只能获取到监听属性的新值newvalue

/* vue2.0*/
var a = { b:123, c:444};
Object.defineProperty(a, 'b', {
    set: function(newvalue){
        console.log('i am be set')
    }
 }) 

//只能获取到newvalue这个参数

/* vue3.0 */
var a={ b:123, c:444};

var newa = new Proxy(a,{
    set:function(target,key,newvalue){
        console.log(target,key,newvalue)
    }
}) 

//可以获取到target,key,newvalue三个参数

参考链接:

  • https://www.jianshu.com/p/b1fb5d549fcd
  • https://blog.csdn.net/weixin_39938331/article/details/111134611
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从未、淡定

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值