Vue3 composition API option API差異(1/n):ref, reactive, computed
Vue3開始支援composition API,但同時也支援Vue2的option API,我自己在接觸Vue時,雖然是使用Vue3,但還是用option API的寫法,直到最近到了新公司,發現Vue3就是要用composition API拉!好8學無止境只能再次打開筆記本ㄌ。
這次示範了同一件事情,用option API寫跟用composition API寫的差別,之後應該會覺得composition API真香。
Option API
根據程式功能來區分程式碼:
export default{
props: {},
components: {},
data() {
// 所有資料
},
computed() {
// 點擊增加資料
},
mounted() {
// axios取得資料
},
methods() {
// 刪除資料
}
}
一個功能可能會被切割到methods、computed中,不易維護也不方便閱讀。
Composition API
export default {
setup() {
// 所有資料...
// 取得資料...
// 增加資料...
// 刪除資料...
}
}
data( ) 預設值
Option API
<template lang="">
<div>
<h2>{{name}}</h2>
</div>
</template>
<script>
export default {
data(){
return {
name: 'wendy'
}
}
}
</script>
Composition API
把函數寫在setup()中,用const接收預設值,最後在底端把name
return出去。
<template lang="">
<div>
<h2>{{ name }}</h2>
</div>
</template>
<script>
export default {
setup(){
const name = 'wendy'
return { name }
}
}
</script>
v-model
Option API
<template lang="">
<div>
<input type="text" v-model="name">
<h2>{{name}}</h2>
</div>
</template>
<script>
export default {
data(){
return {
name:''
}
}
}
</script>
Composition API
- import
ref
進來 - 注意name後方的寫法
- 把
name
return出去
<template lang="">
<div>
<input type="text" v-model="name">
<h2>{{name}}</h2>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup(){
const name = ref(null)
return { name }
}
}
</script>
🍬setup語法糖
如果覺得export default的寫法太囉嗦,也可以這樣寫:
<template lang="">
<div>
<h2>{{name}}</h2>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const name = computed(() => {
return 'Kelly'
})
</script>
就不用再把const出來的變數return出去了,同理如果有import component,用這種寫法就不用再定義component:{ }
了。
另外這個只有Vue3可以用,Vue2不能使用。
ref( )
Composition API
ref()
是一個函數,可以接收任何型別的參數,並回傳響應式可變動的物件。以下示範把input框內的文字丟到alert上去。
- 接收click事件的按鈕
- 用const把事件函數包起來,取得ref內的資料要用
.value
去取。 - 把事件函數
handler
return出去
<template lang="">
<div>
<input type="text" v-model="name">
<h2>{{ name }}</h2>
<button @click="handler">click</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup(){
const name = ref('wendy')
const handler = ()=>{
alert(name.value)
}
return { name, handler }
}
}
</script>
會使用const
來包,是避免我們在要改變值時,忘記加上.value
,如果今天用let
的話,就會很難debug:
export default {
setup(){
let name = ref('wendy')
const handler = ()=>{
name = 'sandy'
console.log(name)
}
return { name, handler }
}
}
畫面會出現wendy
,而console.log
會出現sandy
現在就是把name用sandy這個String去取代了,而不是原本的ref,而let
的性質使程式不會報錯,所以這裡還是盡量使用const
比較好。
option API
- 預設值跟methods要分開寫
- methods內的函數要取最新的name,要用
this
去取
<template lang="">
<div>
<input type="text" v-model="name">
<h2>{{name}}</h2>
<button @click="handler">click</button>
</div>
</template>
<script>
export default {
data(){
return {
name:'wendy'
}
},
methods: {
handler(){
alert(this.name)
}
}
}
</script>
reactive( )
跟ref
很像的就是reactive()
,兩者同樣具備響應式功能,而reactive()
中只能放陣列或物件,並且不需要用.value
來做取用。
<template lang="">
<div>
<h2>{{data.name}}</h2>
<h2>{{data.age}}</h2>
<h2>{{data.address}}</h2>
</div>
</template>
<script setup>
import { ref, computed,reactive } from 'vue'
const data = reactive({
name: 'wendy',
age: 18,
address: 'Taiwan'
})
//兩秒後會置換
setTimeout(()=>{
data.name = 'sandy'
data.age = '16'
data.address = 'Taipei'
},2000)
</script>
watch( )監聽
講到ref()
跟reactive()
的差別就一定要提到watch監聽,watch可以用來監聽reactive()
內容有沒有改變,而不會監聽到ref
的改變。
watch(要監聽的物件, 回呼函式)
<template lang="">
<div>
<h2>{{people1.name}}</h2>
<h2>{{people2.name}}</h2>
</div>
</template>
<script setup>
import { ref, computed,reactive,watch } from 'vue'
const people1 = ref({
name: 'kevin'
})
const people2 = reactive({
name: 'kyle'
})
setTimeout(()=>{
people1.value.name = 'newKevin'
people2.name = 'newKyle'
},2000)
watch(people1,()=>{
console.log('people1 被改變了');
})
watch(people2,()=>{
console.log('people2 被改變了');
})
</script>
如果想要讓ref()被watch到,那就要在watch()中加入第三個參數{deep: true}
:
watch(people1,()=>{
console.log('people1 被改變了');
},{deep: true})
computed( )計算屬性
就是會return 一個值出去的那個,面試超愛考computed、methods、watch的差異。
option API
<template lang="">
<div>
<h2>{{newname}}</h2>
</div>
</template>
<script>
export default {
data() {
return {
name: 'wendy'
}
},
computed: {
newname(){
return this.name = 'sandy'
}
}
}
</script>
網頁會呈現sandy
Composition API
<template lang="">
<div>
<h2>{{name}}</h2>
</div>
</template>
<script>
import { ref, computed } from 'vue'
export default {
setup() {
const name = computed(() => {
return 'Kelly'
})
return { name }
}
}
</script>
網頁會呈現Kelly