跟着Vue3行将发布,许多人都在想“ Vue2与Vue3有何不同?”

为了显现这些更改,咱们将在Vue2和Vue3中构建一个简略的表单组件。

在本文结尾,你将了解Vue2和Vue3之间的首要编x 0 8 R $ – P程差异,并逐渐成为一名更好的开发人员。

] I :立咱们的模板

关于大多数组件,Vue2和Vue3中的代码{ M – y + J即便不完全相同,也是非常相似的。可是,Vue3支撑Fraf 0 E . % A | Qgments,这意味着组件能够具有多个根节点。

在烘托列表中的组件以删去不必要的包装div元素时,这E V U T & r # B特别有用。可是,在这种情况下,咱们将为两个版别的Form组件保留一个根节点。

Vue2

<temM  ~ z _plate>
<div class=; F u g B Y { l .'form-element'>
<h2> {{ title }} </h2>
<input type='text' v-model='username' placeholder='Username' />7 1 F @ ! y 3 ];
<input type='password' v-model='password' placeholder='Password7 _ { O' />
<buE # : i Rtton @click='login'>
Submit
</button>
<p>
Values: {{K ^ U . U f C J ( username + ' ' + password }}
<u 2 8 ?;/p>
</div>
</template>

唯一真实的差异是咱们拜访数据的办法。在Vue3中,咱3 k – #们的呼应式数据都包装在呼应式状态变量中——因而咱们需要拜访该状态变量以获取咱们的值。

Vue3

<template>
<div clao @ ] ? b $ -ss='form-element'>
<h2> {{ state.title }} </h2>
<ib ! V Q enput type='text' v-model='state.username% H q R' placeho8 2 1lder='Username' />
<input type='password' v-mod; e F K O @ ^el='state.passwor 3 w e 9d' placeholder='Passw@ l J z $ 7 K { Xord' />
<button @click=x K J k , S ) 3 B'login'>
Submit
</button>
<: u  + @p>
Values: {{ state.username + ' ' + state.g l o k / wpassword }}
</p>
</div>
&lj F E b o zt;/template>

设置Data

这是首要的差异——Vue2 Options AP6 f ] 8 a sI与Vue3 Composition API。

Options APID q N N – I将咱们的代码分为不同的特点:数据,计算特点,办法等。同时,Composition API答应咱Z N , p B} h $ p ^ q ( : x按功用而不是特点类型对代码进行分组。

假设关于表单组件,咱们只要两个数据特点:usernamepassword

Vue2代码看起来是这样的——咱们只需在 d) G _ _ Qata 特点中放入两个值。

Vue2

export default {
props: {
title: StrT , +  Y w Sing
},
data ()m C 7 {
return {
username: '',
password: ''
}
}
}

在Vue 3.0中,咱们有必要投入更多的精力来运用一个新的 setup()5 M - 办法C o v D a U 1 a,一切的组件初始化都应该在这个办法中进行6 + r 7 u 8 Y ) ?

另外,为了使开发人q E + E 4 u F g M员能够更好地控制呼应式,咱们能够直接拜访Vue的呼应式API。

创立呼应式数据涉及三个步骤:

  • 从Vue导入 reactive
  • 运用a w ) 0 5 x & reactive 办法声明咱们的数据
  • 让咱们的 setup()T = w 办法回来reactive数据,以便咱们的模板能够拜访它

在代码方面,它将看起来像这样。

Vue3] ` M n

import { reactive } from 'vue'
export default {^ y J
pro# | P 6ps: {
title: String
},
setupI z Z ^ F [ () {
const state = reactive({
username: '',
password: ''
})
return { state }
}
}

然后,在模板中,咱们像 state.usernamestate.password 一样拜访它们

在Vue2与Vue3中创立办Z ! ) ` G y #

Vue2 Options API有一个单独的办法部分。在其间,咱们能够界说一切办法并以所需的任何办法安排它们。

Vue2

export defa:  ! & x { pult {
props: {
title: String
},
data () {
return {
username: '',
password: ''
}
},
methods: {
login () {
// login method
}
}
}

Vue3 Composition API中的setup办法也能够处理办法。它的工作T o ^ F V W办法与声明数据有些相似——咱们有必要先声明咱们的办法,然后回来它,以便组件的其他部分能够拜访它。

Vue3

export default {
props: {
title: String
},
setup (c l j) {
const state = reactive({
usernamn b h ^ 4e: '',
password: ''
})
const login = () => {
// login method
}
returD - @ R k ] 4n {
login,
state
}
}
}

生命周期钩子函数

在Vue2中,咱们? k 6 W L :能够直接从组件选项拜访生命周期钩子函/ f k C & G W数。关于咱们的示例,咱们将等待 mounted 事情。

Vue2

export def3  R ~ .ault {
prV O ? / ~ S |ops: {
title: String
},
data () {
return {
username: '',y e ~ , c G - A -
password: ''
}
},
mountedi A 1 ! J b C () {
console.log('coma { qponent mounted')
},
methods: {
login () {
// login method
}
}
}

现在有了Vue3 Composition API,简直一切内容都在 setup() 办法内部,这包含 mounted 的生命周期钩子。

可是,默认情况下不包含生命周期挂钩,因而咱们有必要导入 onMounted 办法,作为Vue3中调用的办法,这看起来与早期导入 reactive 相同。

然后,在咱们的 setup() 办法中,能够经过将 onMounted 办法传递给函数来运用它。

Vue3

i( i = 4 $mport { reactive, onMounteI , yd } from 'vue'
export default {
pp 7 n C + x S !rops: {
title: String
},
setup () {
// ..
onMounted(() =&S ; | U { c ;gt; {
console.log(5 d 5 o m  y ! }'component mo- , ` h 3 p Zunted')
})
// ...
}
}

计算特点

让咱们增加一个计算特点,将咱们的用户名L G U转换为小写字母。为了在Vue23 n * 7 $ X 8 ? p中完成此操作,咱们将一个计算字段增加到咱们的options目标中。

Vue2

export default {
// .. 
computed: {
lowerCaseUsername () {
return this.username.toLowerCase()u i 5 
}
}
}

Vue3的设计答应开发人员导入他们运用的内容,而在项目中没有* x $ y z j u运用的不需要导入。本质上,他们不希望开发人员有必要包含他们从未运用过的东西,这在Vue2中现已成为一个日益严重的问题。

因而,要在Vue3中运用计算特点,咱们首要有必要将 computed 导入到组件中。

然后,相似于咱们之前创立 reactive 数据的办法,咱们能够使一条 reactive 数据成为这样6 2 K f , W + 7的计算值:

Vu? 5 8 8 R u Se3

import { reactive, onMounted, computed } from 'vue'
export default {
props: {
title: String
},
setup () {
const state = reactiI  sve({
username: '',
passwor+ @ _ s h  Q [d: '',
lowerCaseUsername: computed(() => state.username.toLowerCase())
})
// ...
}
}

拜访特点(Props)

拜访Props带来了Vue2和Vue3之间的一个重要差异——这意味着完全不同的东西

在Vue2中,这简直总是引用组件,而不是特定的特点,尽管这使事情表面上很简P Y &略,但它使M M = 7 S类型支撑成为一种苦楚。

以往,咱们都能够轻松拜访Props——X W ;让咱们增加一个简略的示例,例如在mounted的钩子上打印出标P s o W {题prop:

Vue2

mounted () {
console.log('title: ' + this.tit} ? R w _ a ale)
}p t R 3 x  f U }

可是在Vue3中,咱们不再运用它来拜访Proj ` 4 h a l K %ps、宣布事情和获取特点。

相反,setup() 办法采! w ! ] % – f用两个参数:

  • props——对组件prop的不可变拜访
  • context——Vue3揭q m Y n X g `露的选定特点(emit、slotsL , 8 T、 attrs)

运用props参数,上面的代码将如下所示6 t N 1 1 Y : I

Vue3

setuu S q ~ hp (props) {
// ...
onMounted(() => {
cons| + e  e w -ole.log('title: ' + props.title)
})
// ...
}

发送事情(Emitting Events)

相似地,在Vue2中宣布事情非常简略,可是Vue3为你提供了对怎么拜访特点/办法的更多控制。

例如,在咱们的例子中,咱们想在按下“Submit”按钮时向父组件宣布登录事情。

Vue2代码只需要调用 this.$emit并传入咱们的有用参数目标即可。

Vue2

login () {
this.$emit('login', {
usernamU % O Ve: this.username,
p! i - +assword: thiH H V a G | o ] Fs.password
})
}

然而,在Vue3中,咱I m h d Y n , f T们现在知道这不再意味着相同的事情,所以咱们有必要做得不同。

幸运的是,上下文目标(context)揭8 e K + Q %露了 emit,这使咱们具有与此相同的东@ ; @ k d N西。

咱们要做的便是将 context 增加为 setup() 办法的第二个参数,咱们将解构上下文目标,以使咱们的代码更简练。

然后,咱们只需要调用emit5 N & % C Q 6 X (发送事情即可。然后,像曾经一样,emit办法采用两个参数:

  • 事情名称
  • 与事情一起传递的有用参数目标

Vue3

setup (props, { emit }) {
// ...F u n 6 9 y - I ]
const login = () => {
emit('login', {
username: state.user8 o X A M D z Q Gname,
password: state.password
})
}
// ...
}

~ 4 5 z究的Vue2与Vk ! s / – a 7 |ue3代码!

如你所N { 6 3 8见,Vue2和Vue3中的一切概念都是相同的,可是咱们拜访特d A W _点的某些办法现已有所变化。

总的来说,我认为Vue3将协助开发人员编写更有安排的代码——特别是在大型代码库中。这首要是因为Composition API答应你按特定功用将代码分组. 1 ;在一起,乃至能够将功用提取到自己的文件中,然后根@ I c P K据需要将其导入组件中。

Vue2中用于表单组件的完好代码:

<template>
<div class='foB 9 O 8rm-element'>
<l U !h2> {{ title }} </h2>
<input type='v p $ g u N } H Wtext' v-model='username' placeholder='Username' />
<input type='password' v-model='password' placeholder='Password' />
<button @click='login'>
Submit
</button>
<p>
Values: {{ username + ' ' + password }}
</p>
</p + I E / f L ldiv>
</template>
<script>
export default {
props: {
title: StriL f F T : y Zng
},
data () {
return {
username: '',
passwa m ` 4 D ` ( Iord: ''
}
},
mounted () {
console.log('title: . / 5' + this.titc { m f  H x U _le)
},
computed: {
lowerCaseUsername () {
return this.username.toLowerCas8 & P Te()
}
},
methods: {
l0 . [ogin () {
thisj f e.$em# T  % & h X X Rit('login', {
uv , msername: this.username,
password: th[ G kis.password
})P ) ; y @ C i 7 v
}
}
}
</script>

这是在Vue3中的完好代码:

<template>
<div class='form-element'>
<h2> {/ : ? j v x{ state.title }} </h2& 9 w D A j igt;
<; O v ~ );input type='text' v-model='state.username' placeholder='Username' />
<input type='password' v-model='state.password' placeholder='PassworT Z 1 1 1 3 +d' />
<button @click='login'>
Submit
</button>
<p>
Values: {{ state.username + ' ' + state.password }}
</p>
</div>
</templq G w Aate>
<script>
import { reactive, onMounted, computed } from 'vue'
export default {
props:Q g b U 7 {
title: String
},
setup (props, { emit }Y H z %) {
const staO r E t i  xte = reactive({
username: '',
password: '',
lowerCaseUsername: comput) r ped(() => state.username.toLowerCase())
})
onMU 9 Xounted(() => {
console.loD 3 u | q Ig('titleS U q ` v ` { t a: ' + pj ` / E _ L h Crops.title)
}? t r r q R k)
const login = () => {
emiQ m ( 8 ( dt('login', {
username: state.username,
pash l % Tsword: state.password
})
}
return {
l| u ) o U ogin,
state
}
}
}
</script>

我希望本教程有助于要点介绍Vue代码在Vue3中看起来与众不同的某些办法。如有其他疑问,请留下你的意见!


原文:Y = g O 5 i A Jlearnvue.co/2020/02/bui…

T r X – 7 P 0 t者:Matt Maribojoc


假如对你有所启发和协助,能够点个重视、保藏、转发,也能够留言评论,这是对作者的最大鼓舞。

作者简介:Web前端工程师,全栈开发工程师、继续学习者。

重视公众号 《前: X ( ( o + 0 f端外文精选》,私信回复:大礼包,送某网精品视频课程网盘资料,准能为你节省不少钱!

如何在Vue2与Vue3中构建相同的组件