# Vue3
為了達到響應式,Vue 有提供幾個語法
# Vue3 Reactive API
## ref
ref 會建立一個響應式物件,裡面有一個 property: `.value`
我們可以透過 `.value` 來讀取或寫入值
ref 可以接受任何型態的資料,但是不會對物件或陣列內部的屬性變動做監聽
```javascript
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
const countArray = ref([1,2,3,4,5])
countArray.value[0]++
console.log(countArray.value[0]) //1
countArray.value = [5,6,7,8,9]
console.log(countArray.value) //[5,6,7,8,9]
```
## reactive
reactive 只能接受 Object 或 Array,會對內部的屬性變動做深層的監聽
取資料時不需要 `.value`
```javascript
const obj = reactive({ count: 0 })
obj.count++
```
監聽差別: https://codepen.io/MikeCheng1208/pen/rNLNxmJ
## computed()
computed 會提供一個 getter 讓你讀取計算結果
會監聽 computed 裡用到的響應式資料來進行計算
computed 的特性是計算結果會被暫存
如果計算的資料沒有變更就會直接提供暫存的資料
```javascript
const count = ref(1)
const plusOne = computed(() => count.value + 1)
const aa = computed(() => count.value);
const bb = () => { count.value + 1 };
bb();
bb();
bb();
console.log(plusOne.value) // 2
plusOne.value++ // error
```
除了 getter 的寫法也有 setter 的寫法
```javascript
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
```
## watch()
可以監聽響應式的內容,當響應式的內容變了就會執行 callback
callback 可以帶入 parameter,分別會是監聽對象新的值與舊的值
```javascript
const count = ref(0)
watch(count, (count, prevCount) => {
console.log('newCount', count);
console.log('oldCount', prevCount);
})
```
watch 預設是當響應式內容變了才會執行 callback
如果想要在 watcher 一開始就執行 callback
vue 有提供可選設定: `immediate`
```javascript
watch(count, (count, prevCount) => {
console.log('newCount', count);
console.log('oldCount', prevCount); //undefined
}, { immediate: true })
```
如當觀察值的特性為 call by reference,例如 Object 時
想要監聽到 object 的內部屬性時
可以開啟設定: `deep`
```javascript
const people = {
age: 15,
name: 'Apple'
}
watch(people, (people, prevPeople) => {
console.log('new', people);
console.log('old', prevPeople);
}, { immediate: true })
people.age = 20; // new: {age: 20, name: Apple}
```
## watchEffect()
watchEffect 會立刻執行一次 callback
並且在這之後會觀測他有用到的響應式變數
如果變數改變就會執行 callback
```javascript
const count = ref(0)
watchEffect(() => console.log(count.value)) // 0
count.value++ // 1
```
# Vue 生命週期



# Next Tick & Event Loop
## Event Loop
### Call Stack
Call Stack 是一種 Javascript 用來追蹤 Function 執行狀態的機制
首先進入 stack 的會是全域環境的程式(這裡稱作 main)
接著 printSquare 會被呼叫(invoke)因此進入堆疊(stack)的最上方
然後一直跟著呼叫順序往上堆疊

## Web APIs & Callback Quene
當有非同步方法出現怎麼辦?
ex: setTimeout()
```javascript
console.log('a');
setTimeout(function(){
console.log('b in setTimeout');
}, 0);
console.log('c');
```




## NextTick
當我們修改 Vue 裏的資料時,Vue 不會馬上更新畫面
如果每修改一次就更新畫面,那下面這段 code 畫面會渲染一千次
```htmlembedded
<div> {{ n }} </div>
```
```javascript
for(let i = 0; i < 1000; i++) {
this.n = i
}
```
Vue 會在一個 eventloop 結束後去更新畫面
而 nextTick 會在更新畫面後馬上執行 callback,獲取更新後的 DOM。