隨着Vue3即將發佈,許多人都在想「 Vue2與Vue3有何不一樣?」javascript
爲了顯示這些更改,咱們將在Vue2和Vue3中構建一個簡單的表單組件。html
在本文結尾,你將瞭解Vue2和Vue3之間的主要編程差別,並逐步成爲一名更好的開發人員。前端
對於大多數組件,Vue2和Vue3中的代碼即便不徹底相同,也是很是類似的。可是,Vue3支持Fragments,這意味着組件能夠具備多個根節點。vue
在渲染列表中的組件以刪除沒必要要的包裝div元素時,這特別有用。可是,在這種狀況下,咱們將爲兩個版本的Form組件保留一個根節點。java
Vue2react
<template>
<div class='form-element'>
<h2> {{ title }} </h2>
<input type='text' v-model='username' placeholder='Username' />
<input type='password' v-model='password' placeholder='Password' />
<button @click='login'>
Submit
</button>
<p>
Values: {{ username + ' ' + password }}
</p>
</div>
</template>
複製代碼
惟一真正的區別是咱們訪問數據的方式。在Vue3中,咱們的響應式數據都包裝在響應式狀態變量中——所以咱們須要訪問該狀態變量以獲取咱們的值。編程
Vue3數組
<template>
<div class='form-element'>
<h2> {{ state.title }} </h2>
<input type='text' v-model='state.username' placeholder='Username' />
<input type='password' v-model='state.password' placeholder='Password' />
<button @click='login'>
Submit
</button>
<p>
Values: {{ state.username + ' ' + state.password }}
</p>
</div>
</template>
複製代碼
這是主要的區別——Vue2 Options API與Vue3 Composition API。ide
Options API將咱們的代碼分爲不一樣的屬性:數據,計算屬性,方法等。同時,Composition API容許咱們按功能而不是屬性類型對代碼進行分組。函數
假設對於表單組件,咱們只有兩個數據屬性:username
和 password
。
Vue2代碼看起來是這樣的——咱們只需在 data
屬性中放入兩個值。
Vue2
export default {
props: {
title: String
},
data () {
return {
username: '',
password: ''
}
}
}
複製代碼
在Vue 3.0中,咱們必須投入更多的精力來使用一個新的 setup()
方法,全部的組件初始化都應該在這個方法中進行。
另外,爲了使開發人員可以更好地控制響應式,咱們能夠直接訪問Vue的響應式API。
建立響應式數據涉及三個步驟:
reactive
reactive
方法聲明咱們的數據setup()
方法返回reactive
數據,以便咱們的模板能夠訪問它在代碼方面,它將看起來像這樣。
Vue3
import { reactive } from 'vue'
export default {
props: {
title: String
},
setup () {
const state = reactive({
username: '',
password: ''
})
return { state }
}
}
複製代碼
而後,在模板中,咱們像 state.username
和 state.password
同樣訪問它們
Vue2 Options API有一個單獨的方法部分。在其中,咱們能夠定義全部方法並以所需的任何方式組織它們。
Vue2
export default {
props: {
title: String
},
data () {
return {
username: '',
password: ''
}
},
methods: {
login () {
// login method
}
}
}
複製代碼
Vue3 Composition API中的setup方法也能夠處理方法。它的工做方式與聲明數據有些相似——咱們必須先聲明咱們的方法,而後返回它,以便組件的其餘部分能夠訪問它。
Vue3
export default {
props: {
title: String
},
setup () {
const state = reactive({
username: '',
password: ''
})
const login = () => {
// login method
}
return {
login,
state
}
}
}
複製代碼
在Vue2中,咱們能夠直接從組件選項訪問生命週期鉤子函數。對於咱們的示例,咱們將等待 mounted 事件。
Vue2
export default {
props: {
title: String
},
data () {
return {
username: '',
password: ''
}
},
mounted () {
console.log('component mounted')
},
methods: {
login () {
// login method
}
}
}
複製代碼
如今有了Vue3 Composition API,幾乎全部內容都在 setup()
方法內部,這包括 mounted 的生命週期鉤子。
可是,默認狀況下不包括生命週期掛鉤,所以咱們必須導入 onMounted
方法,做爲Vue3中調用的方法,這看起來與早期導入 reactive 相同。
而後,在咱們的 setup()
方法中,能夠經過將 onMounted
方法傳遞給函數來使用它。
Vue3
import { reactive, onMounted } from 'vue'
export default {
props: {
title: String
},
setup () {
// ..
onMounted(() => {
console.log('component mounted')
})
// ...
}
}
複製代碼
讓咱們添加一個計算屬性,將咱們的用戶名轉換爲小寫字母。爲了在Vue2中完成此操做,咱們將一個計算字段添加到咱們的options對象中。
Vue2
export default {
// ..
computed: {
lowerCaseUsername () {
return this.username.toLowerCase()
}
}
}
複製代碼
Vue3的設計容許開發人員導入他們使用的內容,而在項目中沒有使用的不須要導入。本質上,他們不但願開發人員必須包含他們從未使用過的東西,這在Vue2中已經成爲一個日益嚴重的問題。
所以,要在Vue3中使用計算屬性,咱們首先必須將 computed 導入到組件中。
而後,相似於咱們以前建立 reactive 數據的方式,咱們可使一條 reactive 數據成爲這樣的計算值:
Vue3
import { reactive, onMounted, computed } from 'vue'
export default {
props: {
title: String
},
setup () {
const state = reactive({
username: '',
password: '',
lowerCaseUsername: computed(() => state.username.toLowerCase())
})
// ...
}
}
複製代碼
訪問Props帶來了Vue2和Vue3之間的一個重要區別——這意味着徹底不一樣的東西。
在Vue2中,這幾乎老是引用組件,而不是特定的屬性,雖然這使事情表面上很容易,但它使類型支持成爲一種痛苦。
以往,咱們均可以輕鬆訪問Props——讓咱們添加一個簡單的示例,例如在mounted的鉤子上打印出標題prop:
Vue2
mounted () {
console.log('title: ' + this.title)
}
複製代碼
可是在Vue3中,咱們再也不使用它來訪問Props、發出事件和獲取屬性。
相反,setup()
方法採用兩個參數:
props
——對組件prop的不可變訪問context
——Vue3公開的選定屬性(emit、slots、 attrs)使用props參數,上面的代碼將以下所示。
Vue3
setup (props) {
// ...
onMounted(() => {
console.log('title: ' + props.title)
})
// ...
}
複製代碼
相似地,在Vue2中發出事件很是簡單,可是Vue3爲你提供了對如何訪問屬性/方法的更多控制。
例如,在咱們的例子中,咱們想在按下「Submit」按鈕時向父組件發出登陸事件。
Vue2代碼只須要調用 this.$emit
並傳入咱們的有效參數對象便可。
Vue2
login () {
this.$emit('login', {
username: this.username,
password: this.password
})
}
複製代碼
然而,在Vue3中,咱們如今知道這再也不意味着一樣的事情,因此咱們必須作得不一樣。
幸運的是,上下文對象(context)公開了 emit
,這使咱們擁有與此相同的東西。
咱們要作的就是將 context 添加爲 setup()
方法的第二個參數,咱們將解構上下文對象,以使咱們的代碼更簡潔。
而後,咱們只須要調用emit發送事件便可。而後,像之前同樣,emit方法採用兩個參數:
Vue3
setup (props, { emit }) {
// ...
const login = () => {
emit('login', {
username: state.username,
password: state.password
})
}
// ...
}
複製代碼
如你所見,Vue2和Vue3中的全部概念都是相同的,可是咱們訪問屬性的某些方式已經有所變化。
總的來講,我認爲Vue3將幫助開發人員編寫更有組織的代碼——特別是在大型代碼庫中。這主要是由於Composition API容許你按特定功能將代碼分組在一塊兒,甚至能夠將功能提取到本身的文件中,而後根據須要將其導入組件中。
Vue2中用於表單組件的完整代碼:
<template>
<div class='form-element'>
<h2> {{ title }} </h2>
<input type='text' v-model='username' placeholder='Username' />
<input type='password' v-model='password' placeholder='Password' />
<button @click='login'>
Submit
</button>
<p>
Values: {{ username + ' ' + password }}
</p>
</div>
</template>
<script> export default { props: { title: String }, data () { return { username: '', password: '' } }, mounted () { console.log('title: ' + this.title) }, computed: { lowerCaseUsername () { return this.username.toLowerCase() } }, methods: { login () { this.$emit('login', { username: this.username, password: this.password }) } } } </script>
複製代碼
這是在Vue3中的完整代碼:
<template>
<div class='form-element'>
<h2> {{ state.title }} </h2>
<input type='text' v-model='state.username' placeholder='Username' />
<input type='password' v-model='state.password' placeholder='Password' />
<button @click='login'>
Submit
</button>
<p>
Values: {{ state.username + ' ' + state.password }}
</p>
</div>
</template>
<script> import { reactive, onMounted, computed } from 'vue' export default { props: { title: String }, setup (props, { emit }) { const state = reactive({ username: '', password: '', lowerCaseUsername: computed(() => state.username.toLowerCase()) }) onMounted(() => { console.log('title: ' + props.title) }) const login = () => { emit('login', { username: state.username, password: state.password }) } return { login, state } } } </script>
複製代碼
我但願本教程有助於重點介紹Vue代碼在Vue3中看起來不同凡響的某些方式。若有其餘疑問,請留下你的意見!
文章首發於公衆號 《前端外文精選》,私信回覆:大禮包,送某網精品視頻課程網盤資料,準能爲你節省很多錢!