vue3与vue2的区别是什么(vue,编程语言)

时间:2024-04-28 03:27:06 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

vue3与vue2的区别是什么

1.生命周期的变化:3.x(上) 2.x(下)

vue3与vue2的区别是什么
vue3与vue2的区别是什么

不难看出,vue3.0与vue2.0之间生命周期函数在销毁的时候有变化:

beforeDestroy-->beforeUnmountdestroyed-->unmounted
其他的区别主要在于书写使用的语言上的差别在ts中使用class类组件书写可以参考vue-class-component或者vue-property-decorator书写的风格和vue2.0的选项式区别不大。如果使用js书写代码则应当使用组合式。

具体变化带来的问题,会在下面的组合式写法中讲解。

2.定义全局变量的方法变化

//之前(Vue2.x)Vue.prototype.$http=()=>{}Vue.prototype.url='http://123'//之后(Vue3.x)constapp=createApp({})app.config.globalProperties.$http=()=>{}app.config.globalProperties.url='http://123'

3.创建vue实例变化

//=======vue3.x//使用createApp函数来实例化vue,//该函数接收一个根组件选项对象作为第一个参数//使用第二个参数,我们可以将根prop传递给应用程序import{createApp}from'vue'importAppfrom'./App.vue'importrouterfrom'./router'importstorefrom'./store'createApp(App,{userName:"blackLieo"}).use(store).use(router).mount('#app')//由于createApp方法返回应用实例本身,因此可以在其后链式调用其它方法,这些方法可以在以下部分中找到。//=======vue2.ximportVuefrom'vue'importAppfrom'./App.vue'importrouterfrom'./router'importstorefrom'./store'Vue({router,store,render:h=>h(App)}).$mount('#app')

4.插槽使用变化

//================vue2.0使用插槽基本上直接使用slot进行操作//其中vue2.0经历了两次更迭,2.6.0版本slot升级为v-slot<p><slot:current="toolTipData"name="test"></slot>//具名作用域插槽<slot></slot>//默认插槽</p>//父组件调用该组件<test><template><p>默认插槽</p></template>//作用域插槽<templateslot-scope="{current}"slot="test"><el-formlabel-width="80px":model="current"><el-form-itemlabel="id:"><el-linktype="info">{{current.id}}</el-link></el-form-item><el-form-itemlabel="name:"><el-linktype="info">{{current.name}}</el-link></el-form-item><el-form-itemlabel="label:"><el-linktype="info">{{current.label}}</el-link></el-form-item><el-form-itemlabel="group:"><el-linktype="info">{{current.group}}</el-link></el-form-item><el-form-itemlabel="runtime:"><el-linktype="info">{{current.runtime}}</el-link></el-form-item><el-form-itemlabel="category:"><el-linktype="info">{{current.category}}</el-link></el-form-item></el-form></template></test>//==============vue3.0使用插槽//在vue3.0中,插槽使用v-slot简写用#<p> <slotname="test":newData="slotsData"></slot><slot></slot></p><HelloWorldmsg="WelcometoYourVue.js+TypeScriptApp"><template#default>//可以写为v-slot:default#后面跟的是插槽名称<p>默认插槽</p></template>//作用域插槽<template#test="{newData}">//可以写为v-slot:test="newData"<p>{{newData.aa}}</p><p>{{newData.bb}}</p></template></HelloWorld>//一个组件里面具有多个插槽时,一定要带上名称,否则可能会导致作用域错乱

5.自定义指令

在 Vue 2 中实现一个自定义指令:

//注册一个全局自定义指令`v-focus`Vue.directive('focus',{//当被绑定的元素插入到DOM中时……inserted:function(el){//聚焦元素el.focus()}})

在 Vue 2 中, 自定义指令通过以下几个可选钩子创建:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

在 Vue 3 中对自定义指令的 API 进行了更加语义化的修改, 就如组件生命周期变更一样, 都是为了更好的语义化, 变更如下:
vue3与vue2的区别是什么

所以在 Vue3 中, 可以这样来自定义指令:

const{createApp}from"vue"constapp=createApp({})app.directive('focus',{mounted(el){el.focus()}})

然后可以在模板中任何元素上使用新的 v-focus指令, 如下:

<inputv-focus/>

6.v-model 升级

Vue 3 中 v-model 发生了很大的变化:

变更:在自定义组件上使用v-model时,属性以及事件的默认名称变了变更:v-bind的.sync修饰符在Vue3中又被去掉了,合并到了v-model里新增:同一组件可以同时设置多个v-model新增:开发者可以自定义v-model修饰符

我们来详细了解一下,并对比一下vue2与vue3 在组件上使用 v-model,
例如:
vue2 的输入框的双向绑定,其实就相当于传递了value属性, 并触发了input事件:

<!--Vue2--><inputv-model="searchValue"><input><!--相当于--><input:value="searchValue"@input="searchValue=$event"><input>

这时v-model只能绑定在组件的value属性上,那如果我们要给自己的组件用一个别的属性,并且我们不想通过触发input来更新值。

但是在实际开发中,有些场景我们可能需要对一个prop进行“双向绑定”,这里以最常见的dialog为例子:dialog挺合适属性双向绑定的,外部可以控制组件的visible显示或者隐藏,组件内部关闭可以控制visible属性隐藏,同时visible属性同步传输到外部。组件内部,当我们关闭dialog时,在子组件中以update:PropName模式触发事件。

事件为

this.$emit('update:visible',false)

然后在父组件中可以监听这个事件进行数据更新:

<el-dialog:visible="isVisible"@update:visible="isVisible=$event"></el-dialog>

在vue2的开发中,我们实际会发现一个新的东西sync,所以也可以使用v-bind.sync来简化实现:

<el-dialog:visible.sync="isVisible"></el-dialog>

上面说了 Vue2 中v-model实现以及组件属性的双向绑定,那么在 Vue 3 中应该怎样实现的呢?
在 Vue3 中, 在自定义组件上使用v-model, 相当于传递一个modelValue 属性, 同时触发一个update:modelValue事件:

<el-dialogv-model="isVisible"></el-dialog><!--相当于--><el-dialog:modelValue="isVisible"@update:modelValue="isVisible=$event"></el-dialog>

如果要绑定属性名, 只需要给v-model传递一个参数就行, 同时可以绑定多个v-model

<el-dialogv-model:visible="isVisible"v-model:content="content"></el-dialog><!--相当于--><el-dialog:visible="isVisible":content="content"@update:visible="isVisible"@update:content="content"></el-dialog>

这个写法完全没有.sync什么事儿了, Vue 3 中抛弃了.sync写法, 统一使用v-model。

7.异步组件的使用

Vue3 中 使用 defineAsyncComponent 定义异步组件,配置选项 component 替换为 loader ,Loader 函数本身不再接收 resolve 和 reject 参数,且必须返回一个 Promise,用法如下:

<template><!--异步组件的使用--><AsyncPage/></tempate><script>import{defineAsyncComponent}from"vue";exportdefault{components:{//无配置项异步组件AsyncPage:defineAsyncComponent(()=>import("./NextPage.vue")),//有配置项异步组件AsyncPageWithOptions:defineAsyncComponent({loader:()=>import("./NextPage.vue"),delay:200,timeout:3000,errorComponent:()=>import("./ErrorComponent.vue"),loadingComponent:()=>import("./LoadingComponent.vue"),})},}</script>

8.Composition API

使用CompositionAPI解决我们在完成功能时,在data、methods、computed以及mounted中反复的跳转,他将零散分布的逻辑组合在一起维护,并可以将单独的逻辑再分为单独的文件

如果想要了解<script setup></script>语法糖,请移步 vue3 setup语法糖(部分总结)

我们先来了解一下Composition具有的API
vue3与vue2的区别是什么

  • setup

setup 是 Vue3.x 新增的一个选项, 他是组件内使用 Composition API的入口。

setup 执行时机
通过一段代码 我们可以知道:

<script>import{defineComponent,reactive}from"vue";exportdefaultdefineComponent({beforeCreate(){console.log("----beforeCreate----");},created(){console.log("----created----");},setup(){conststate=reactive({count:0});console.log("----setup----");return{state,};},});</script>

会出现如下所示的输出结果:
vue3与vue2的区别是什么

setup 执行时机是在 beforeCreate 之前执行,详细的可以看后面生命周期讲解。

  1. setup 参数

使用setup时,它接受两个参数:

  • props: 组件传入的属性

  • context

setup 中接受的props是响应式的, 当传入新的 props 时,会及时被更新。
由于是响应式的, 所以不可以使用 ES6 解构,解构会消除它的响应式。
错误代码示例, 这段代码会让 props 不再支持响应式:

setup(props){const{name}=props;console.log(name);conststate=reactive({count:0});return{state,};},

对于以上的的问题,我们可以在后面的toRefs进行解释。
现在我们就来讲一下:

  1. reactive、ref、toRefs、readonly

在 vue2.x 中, 定义数据都是在data中。
但是 Vue3.x 可以使用reactiveref来进行数据定义。
那么ref和reactive他们有什么区别呢?

reactive用于处理对象的双向绑定,ref处理js基础类型或者处理对象的双向绑定。注意refs它接受一个内部值并返回一个响应式且可变的ref对象。ref对象具有指向内部值的单个property.value。
<template><p><p>计数:{{num}}s</p><p>主人年龄:{{person.age}}</p><p>主人姓名:{{person.name}}</p><p>动物类别:{{animal.type}}</p><p>动物名称:{{animal.name}}</p><p>动物年龄:{{animal.age}}</p></p></template><script>import{defineComponent,reactive,ref}from"vue";exportdefaultdefineComponent({setup(){//使用ref声明基本类型constnum=ref(0);//使用ref声明对象constperson=ref({age:20,name:"张三"});//使用reactive声明对象constanimal=reactive({type:"猫",name:"小花",age:5});setTimeout(()=>{person.value.age=person.value.age+1;person.value.name="李四";animal.age++;},1000);setInterval(()=>{num.value++;},1000);return{num,animal,person,};},});</script>

我们绑定到页面是通过user.name,user.age;这样写感觉很繁琐,我们能不能直接将user中的属性解构出来使用呢?
答案是不能直接对user进行结构, 这样会消除它的响应式, 这里就和上面我们说props不能使用 ES6 直接解构就呼应上了。
那我们就想使用解构后的数据怎么办,解决办法就是使用toRefs
toRefs 用于将一个 reactive 对象转化为属性全部为 ref 对象的普通对象。具体使用方式如下:

<template><p><p>计数:{{num}}s</p><p>主人年龄:{{person.age}}</p><p>主人姓名:{{person.name}}</p><p>动物类别:{{atype}}</p><p>动物名称:{{aname}}</p><p>动物年龄:{{aage}}</p></p></template><script>import{defineComponent,reactive,ref,toRefs}from"vue";exportdefaultdefineComponent({setup(){//使用ref声明基本类型constnum=ref(0);//使用ref声明对象constperson=ref({age:20,name:"张三"});//使用reactive声明对象constanimal=reactive({atype:"猫",aname:"小花",aage:5});setTimeout(()=>{person.value.age=person.value.age+1;person.value.name="李四";animal.aage++;},1000);setInterval(()=>{num.value++;},1000);return{num,person,...toRefs(animal),};},});</script>

有时我们想跟踪响应式对象 (ref 或 reactive) 的变化,但我们也希望防止在应用程序的某个位置更改它,这时候,我们就需要readonly
例如,当我们有一个被传递的响应式对象时,我们不想让它在传递的的时候被改变。为此,我们可以基于原始对象创建一个只读的 proxy 对象:

import{reactive,readonly}from'vue'constoriginal=reactive({count:0})constcopy=readonly(original)//通过original修改count,将会触发依赖copy的侦听器original.count++//通过copy修改count,将导致失败并出现警告copy.count++//警告:"Setoperationonkey'count'failed:targetisreadonly."
  • 生命周期钩子

在最开始的时候,我们就看到了两张图,其中的变化我们可以总结一下

vue3与vue2的区别是什么

我们可以看到beforeCreatecreatedsetup替换了(但是 Vue3 中你仍然可以使用, 因为 Vue3 是向下兼容的, 也就是你实际使用的是 vue2 的)。
其次,钩子命名都增加了on; Vue3.x 还新增用于调试的钩子函数onRenderTriggeredonRenderTricked
下面我们简单使用几个钩子, 方便大家学习如何使用,Vue3.x 中的钩子是需要从 vue 中导入的:

import{defineComponent,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,onErrorCaptured,onRenderTracked,onRenderTriggered,}from"vue";exportdefaultdefineComponent({//beforeCreate和created是vue2的beforeCreate(){console.log("------beforeCreate-----");},created(){console.log("------created-----");},setup(){console.log("------setup-----");//vue3.x生命周期写在setup中onBeforeMount(()=>{console.log("------onBeforeMount-----");});onMounted(()=>{console.log("------onMounted-----");});onBeforeUpdate(()=>{console.log("------onBeforeUpdate-----");});onUpdated(()=>{console.log("------onUpdated-----");});onBeforeUnmount(()=>{console.log("------onBeforeUnmount-----");});onUnmounted(()=>{console.log("------onUnmounted-----");});onErrorCaptured(()=>{console.log("------onErrorCaptured-----");});onRenderTracked(()=>{console.log("------onRenderTracked-----");});//调试哪些数据发生了变化onRenderTriggered((event)=>{console.log("------onRenderTriggered-----",event);});},});

具体怎么使用,是干什么的请参考官方文档,这里就不一一赘述了。

  • watch 与 watchEffect 的用法

watch 函数用来侦听特定的数据源,并在回调函数中执行副作用。默认情况是惰性的,也就是说仅在侦听的源数据变更时才执行回调。

watch(source,callback,[options])

参数说明:

  1. source: 可以支持 string,Object,Function,Array;

  2. 用于指定要侦听的响应式变量 callback:

  3. 执行的回调函数 options:支持 deep、immediate 和 flush 选项。

其实整体和原来的vue2.0有一定的相似性,基本参数没有发生大的改变。

接下来我会分别介绍这个三个参数都是如何使用的, 如果你对 watch 的使用不明白的请往下看:

//监听reactive对象:watch(()=>animal.aage,(curAge,preAge)=>{console.log("新值:",curAge,"老值:",preAge);});//监听ref变量watch(num,(newVal,oldVal)=>{console.log("新值:",newVal,"老值:",oldVal);});//多个值的监听watch([()=>animal.aage,num],([curAge,newVal],[preAge,oldVal])=>{console.log("新值:",curAge,"老值:",preAge);console.log("新值:",newVal,"老值:",oldVal);});//监听对象复杂时,请使用深度监听让函数的第三个参数为deep:truewatch(()=>state.animal,(newType,oldType)=>{console.log("新值:",newType,"老值:",oldType);},{deep:true});

默认情况下,watch 是惰性的, 那什么情况下不是惰性的, 可以立即执行回调函数呢?其实使用也很简单, 给第三个参数中设置
immediate: true即可。

//停止监听函数conststopWatchRoom=watch(()=>state.animal,(newType,oldType)=>{console.log("新值:",newType,"老值:",oldType);},{deep:true});setTimeout(()=>{//停止监听stopWatchRoom();},3000);

还有一个监听函数watchEffect,介绍一下watchEffect,看看它的使用和watch究竟有何不同,在上面代码的基础上,我们来编写。

watchEffect(()=>{console.log(num);});

执行结果首先打印一次num值;然后每隔一秒,打印num值。
从上面的代码可以看出, 并没有像watch一样需要先传入依赖,watchEffect会自动收集依赖, 只要指定一个回调函数。在组件初始化时, 会先执行一次来收集依赖, 然后当收集到的依赖中数据发生变化时, 就会再次执行回调函数。所以总结对比如下:

  • watchEffect 不需要手动传入依赖

  • watchEffect 会先执行一次用来自动收集依赖

  • watchEffect无法获取到变化前的值, 只能获取变化后的值

9.Hooks

在之前vue用的mixin,所谓的混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
现在的vue3.0提供了一种新的东西 vue-hooks。具体的vue-hooks,请参考网上教程

为什么产生了hooks
首先从class-component/vue-options说起:

  • 跨组件代码难以复用

  • 大组件,维护困难,颗粒度不好控制,细粒度划分时,组件嵌套存层次太深影响性能

  • 类组件,this不可控,逻辑分散,不容易理解

  • mixins具有副作用,逻辑互相嵌套,数据来源不明,且不能互相消费

当一个模版依赖了很多mixin的时候,很容易出现数据来源不清或者命名冲突的问题,而且开发mixins的时候,逻辑及逻辑依赖的属性互相分散且mixin之间不可互相消费。这些都是开发中令人非常痛苦的点。
hooks存在以下优势:

  • 允许hooks间相互传递值

  • 组件之间重用状态逻辑

  • 明确指出逻辑来自哪里

我们先来封装一个hooks,假如这个hooks是一个实现年龄加减,获取双倍年龄的函数。用单独的文件存储 bus/useAge.ts

import{ref,Ref,computed}from"vue";typeCountResultProps={age:Ref<number>;doubleAge:Ref<number>;increase:(curAge?:number)=>void;decrease:(curAge?:number)=>void;};exportdefaultfunctionuseCount(initValue=20):CountResultProps{constage=ref(initValue);constincrease=(curAge?:number):void=>{if(typeofcurAge!=="undefined"){age.value+=curAge;}else{age.value+=1;}};constdoubleAge=computed(()=>age.value*2);constdecrease=(curAge?:number):void=>{if(typeofcurAge!=="undefined"){age.value-=curAge;}else{age.value-=1;}};return{age,doubleAge,increase,decrease,};}

在组件里面调用该hooks

<template><p><p>计数:{{num}}s</p><p>主人年龄:{{person.age}}</p><p>主人姓名:{{person.name}}</p><p>动物类别:{{atype}}</p><p>动物名称:{{aname}}</p><p>动物年龄:{{aage}}</p><p>count:{{age}}</p><p>双倍年龄:{{doubleAge}}</p><p><button@click="increase()">加1</button><button@click="decrease()">减一</button></p></p></template><script>import{defineComponent,reactive,ref,toRefs,watch,watchEffect,}from"vue";importuseAgefrom"../bus/useAge.ts";exportdefaultdefineComponent({setup(){//使用ref声明基本类型constnum=ref(0);//使用ref声明对象constperson=ref({age:20,name:"张三"});//使用reactive声明对象constanimal=reactive({atype:"猫",aname:"小花",aage:5});setTimeout(()=>{person.value.age=person.value.age+1;person.value.name="李四";animal.aage++;animal.aname="小橘";},1000);setInterval(()=>{num.value++;},1000);const{age,doubleAge,increase,decrease}=useAge(22);return{num,person,...toRefs(animal),age,doubleAge,increase,decrease,};},});</script>

10.vue2.x 与vue3.x的响应式数据对比

在vue2.0中,应该很多人都使用了$set这个东西吧。
数据更新了,页面为什么不变化呢?什么时候我们用$forceUpdate强制更新呢?
在vue2.x中,实现数据监听使用的是Object.defineProperty。而vue3.x使用的是Proxy

  1. Object.defineProperty只能劫持对象的属性, 而 Proxy 是直接代理对象

由于Object.defineProperty只能劫持对象属性,需要遍历对象的每一个属性,如果属性值也是对象,就需要递归进行深度遍历。
但是Proxy 直接代理对象, 不需要遍历操作

  1. Object.defineProperty对新增属性需要手动进行Observe

因为Object.defineProperty劫持的是对象的属性,所以新增属性时,需要重新遍历对象,
对其新增属性再次使用Object.defineProperty进行劫持。也就是 Vue2.x
中给数组和对象新增属性时,需要使用$set才能保证新增的属性也是响应式的,
$set内部也是通过调用Object.defineProperty去处理的。

  1. Proxy有多种拦截方法,如apply,deleteProperty等等,是Object.defineProperty()不具备的。

  2. Proxy是返回值是一个对象,可以直接进行操作,而defineProperty()要先遍历所有对象属性值才能进行操作。
    但是相对来说,Object.defineProperty()兼容性高一些。

11.Teleport

Teleport 是 Vue3.x 新推出的功能

Teleport 是什么呢?

Teleport 就像是哆啦 A 梦中的「任意门」,任意门的作用就是可以将人瞬间传送到另一个地方。有了这个认识,我们再来看一下为什么需要用到 Teleport 的特性呢,看一个小例子:

例如我们在使用Dialog组件时,我们实际开发中经常会使用到 Dialog,此时Dialog就被渲染到一层层子组件内部,处理嵌套组件的定位、z-index和样式都变得困难。但是组件希望位于页面的最上方,这时候我们将Dialog组件挂载在body上面是最好控制的,我们能够很好的通过zIndex来控制Dialog的位置,当他嵌套在templat里面的时候就不那么容易了。简单来说就是,即希望继续在组件内部使用Dialog,又希望渲染的 DOM 结构不嵌套在组件内部的 DOM 中。

此时就需要 Teleport 上场,我们可以用<Teleport>包裹Dialog, 此时就建立了一个传送门,可以将Dialog渲染的内容传送到任何指定的地方。

<template><p><p>计数:{{num}}s</p><p>主人年龄:{{person.age}}</p><p>主人姓名:{{person.name}}</p><p>动物类别:{{atype}}</p><p>动物名称:{{aname}}</p><p>动物年龄:{{aage}}</p><p>count:{{age}}</p><p>倍数:{{doubleAge}}</p><p><button@click="increase()">加1</button><button@click="decrease()">减一</button></p><el-buttontype="text"@click="dialogVisible=true">点击打开Dialog</el-button><teleportto="#dialogLL"><el-dialogtitle="提示"v-model="dialogVisible"width="30%"><span>这是一段信息</span><template#footer><spanclass="dialog-footer"><el-button@click="dialogVisible=false">取消</el-button><el-buttontype="primary"@click="dialogVisible=false">确定</el-button></span></template></el-dialog></teleport></p></template><script>import{defineComponent,reactive,ref,toRefs,}from"vue";exportdefaultdefineComponent({setup(){//使用ref声明基本类型constnum=ref(0);constdialogVisible=ref(false);//使用ref声明对象constperson=ref({age:20,name:"张三"});//使用reactive声明对象constanimal=reactive({atype:"猫",aname:"小花",aage:5});setTimeout(()=>{person.value.age=person.value.age+1;person.value.name="李四";animal.aage++;animal.aname="小橘";},1000);setInterval(()=>{num.value++;},1000);return{dialogVisible,num,person,...toRefs(animal),};},});</script>

我们可以很清楚的看到teleport上有一个to属性,这个属性是讲当前节点传送到制定位置去的。位置应该传送到哪里呢?
答案就是在index.html上面
下面是我们的首页 你会看到有一个p的ID名为dialogLL,teleport就将节点挂载在这里来了

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><linkrel="icon"href="/favicon.ico"/><metaname="viewport"content="width=device-width,initial-scale=1.0"/><title>ViteApp</title></head><body><pid="app"></p><pid="dialogLL"></p><scripttype="module"src="/src/main.js"></script></body></html>

如图所示:
vue3与vue2的区别是什么

12.Suspense

Suspense是 Vue3.x 中新增的特性, 那它有什么用呢?我们通过 Vue2.x 中的一些场景来认识它的作用。 Vue2.x 中应该经常遇到这样的场景:

<template><p><pv-if="!loading">...</p><pv-if="loading">加载中...</p></p></template>

在前后端交互获取数据时, 是一个异步过程,一般我们都会提供一个加载中的动画,当数据返回时配合v-if来控制数据显示。
它提供两个template slot, 刚开始会渲染一个 fallback 状态下的内容, 直到到达某个条件后才会渲染 default 状态的正式内容, 通过使用
Suspense组件进行展示异步渲染就更加的简单。
具体的使用,我们可以用下面的例子来表示:
这是需要等待取值完成的的组件:

<template><h2>{{getData.result}}</h2></template><script>exportdefault{name:"NewModel",asyncsetup(){letgetData=awaitnewPromise((resolve)=>{setTimeout(()=>{returnresolve({result:"OK"});},3000);});return{getData,};},};</script>

在其他组件内调用它,当等待取值的组件取值完成后,会将loading状态变为OK状态

<template><p><suspense><template#default><NewSuspense></NewSuspense></template><template#fallback><h2>Loadding...</h2></template></suspense></p></template><script>importNewSuspensefrom"./suspens.vue";exportdefault{name:"AppMain",components:{NewSuspense,},};</script><style></style>

效果如图:
vue3与vue2的区别是什么

13.片段(Fragment)

在 Vue2.x 中, template中只允许有一个根节点:

<template><p><span></span><span></span></p></template>

但是在 Vue3.x 中,你可以直接写多个根节点:

<template><span></span><span></span></template>

14.Tree-Shaking变化

Vue3.x 在考虑到 tree-shaking的基础上重构了全局和内部 API, 表现结果就是现在的全局 API 需要通过 ES Module的引用方式进行具名引用, 比如在 Vue2.x 中,我们要使用 nextTick:

//vue2.ximportVuefrom"vue"Vue.nextTick(()=>{...})或者this.nextTick(()=>{...})

Vue.nextTick() 是一个从 Vue 对象直接暴露出来的全局 API,其实 $nextTick() 只是 Vue.nextTick() 的一个简易包装,只是为了方便而把后者的回调函数的 this 绑定到了当前的实例。
在 Vue3.x 中改写成这样:

import{nextTick}from"vue"nextTick(()=>{...})

受影响的 API

这是一个比较大的变化, 因为以前的全局 API 现在只能通过具名导入,这一更改会对以下 API 有影响:

  1. Vue.nextTick

  2. Vue.observable(用 Vue.reactive 替换)

  3. Vue.version

  4. Vue.compile(仅限完整版本时可用)

  5. Vue.set(仅在 2.x 兼容版本中可用)

  6. Vue.delete(与上同)

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:vue3与vue2的区别是什么的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:怎么安装和使用BootstrapVue构建项目界面下一篇:

11 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18