Vue3 Learning Note - 1

Vue3 Learning Note

記錄一些跟 Vue2 差異較大的部分以及較常忘記的部分。

setup 函數

  • 將 vue 引用進來,透過 Vue.createApp(App).mount('#app') 將 Vue 實體掛載到 id=app 的 DIV 上。
  • App 物件內,Vue 3 起手式,跟 Vue有關的操作全都寫在 setup() 內。
1
2
3
4
5
6
7
8
9
10
<div id="app"></div>
<script src="./js/vue.js"></script>
<script>
const App = {
setup() {
return {};
},
};
Vue.createApp(App).mount("#app");
</script>

ref()

  • ref 把資料包裝成物件,若沒透過此函式將資料包起來,資料不會跟畫面同步。
  • 若要修改用 ref 包裝起來的資料的值,須透過 變數名稱.value = .. 做修改。
  • 須將被 ref 包裝起來的變數 return 才能在 template 上使用。
1
2
3
4
5
6
7
8
import { ref } from 'vue'
setup() {
const test = ref('Hello World')
setTimeout(() => {
test.value = 'Ming'
},1000)
return { test }
}

reactive

  • 只能放物件 or 陣列
1
2
3
4
5
import { reactive } from 'vue'
setup() {
const msg = reactive({text: 'ming'})
return { msg }
}

ref 跟 reactive 的差別

  • ref 可以放任何型別的資料,可以接受任何型態的資料,但是不會對物件或陣列內部的屬性變動作監聽。
  • reactive 只能放物件或陣列,可作深層的監聽,且訪問資料時不需要 .value

v-on 事件綁定

1
2
3
4
5
6
7
8
import {ref} from 'vue'
setup() {
const num = ref(0)
const AddFn = () => {
num.value ++;
}
return {num, AddFn}
}

readonly

  • 確保更改資料時只有一個進入點跟進入口。
  • 先取出 readonly import {readonly} from 'vue'
    * 使用 ref, reactive readOnly 時都不能修改。
    1
    2
    3
    4
    5
    import { ref, reactive, readonly } from 'vue';
    const num = reactive({ idx: 0 })
    const Num = ref(0)
    // 若使用 copyNum.idx ++ 會出錯,因為readOnly不能修改,所以適合用在給其他function 或 component使用
    const copyNum = readonly(num)

class 狀態切換

1
2
3
4
5
6
7
8
9
import { ref, reactive } from 'vue'

setup() {
const isOpen = ref(true)
const HandListShow = () => {
isOpen.value != isOpen.value
}
return { isOpen, HandListShow }
}
1
2
3
<div :class="{'isOpen': isOpen}"></div>

<div :class="['box', {'isOpen': isOpen}]"></div>

Computed

1
2
3
4
5
6
7
8
9
10
11
12
import { ref, reactive, computed } from 'vue'

setup() {
const domH = computed(() => {
if(isOpen.value) {
return listArr.length * 40 + "px"
}else{
return 0;
}
})
return { domH }
}
1
<div class="box" :style="{'height': domH}"></div>

computed 跟 methods 的差別

* computed 會根據計算的資料進行緩存,只要有用到的資料沒有重新被更新,computed 不會被重新執行。

  • computed 計算完的結果要給其他 computed 計算需使用 computedName.value()
  • methods 不會進行緩存,每次都會重新執行,但是可以傳入參數。

資料監控 watch

  • 透過 watch 知道資料被改變了。
  • watch({'watch 的值'}, callback function),第一個值傳要 watch的資料,第二個傳入 callback function
  • watch 的第一個參數,只能是可以被 getter 的值,所以 reactive 包起來的資料需做特殊處理。
  • ref 無法對物件或陣列的資料做深層監控,除非設定 watch 第三個參數 {deep: true},但設定這個參數會對物件每個資料都做掃描會很耗效能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { watch } from 'vue'

setup() {
const idx = ref(0)
const data = reactive({ idx:0 })
watch(idx, (newidx, oldidx) => {
console.log(newidx, oldidx)
})

watch(() => data.idx, (newdata, olddata) => {
console.log(newdata, olddata)
})

setInterval(() => {
idx.value ++;
}, 1000)
return { idx }
}

深度監控資料

1
2
3
4
5
6
7
8
9
10
11
12
13
setup() {
const data = ref({user: {
name: ''
}})
// 建議針對某個值去做監控,不要針對整個物件,因為 deep: true很耗效能
watch(data.user.name, (newval) => {
console.log(newval)
}, {deep: true})

setTimeout(() => {
data.value.user["name"] = "ming"
}, 500)
}

watchEffect

  • watch 外另外一個監控資料的方式
  • 不需要傳入監控的資料,直接寫 callback function 就好。
  • 一開始就會執行,不會等到資料有變化在執行,之後若資料有變化會在執行。
  • warchEffect 會去掃描在他 callback function 內是否有改變的值(只要有一個被改變就會觸發),被使用到,若有才會觸發 callback function
  • watchEffect 是可以被中斷跟停止的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { watchEffect } from 'vue'

setup() {
const num = ref(0)
const numData = reactive({idx: 0})

const stop = watchEffect(() => {
console.log(num.value);
if (num.value >= 4) {
// 在執行一次就可以把 watchEffect 關掉
stop()
}
});

setInterval(() => {
num.value ++;
numData.idx ++;
}, 500)
}

Lifecycle hooks

  • 不同程式,不同階段會執行不同的事情,稱為生命週期。
  • 常見的三個生命週期 onBeforeMounted, onMounted, onUpdated
  • setup 也是一個生命週期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
setup() {
const idx = ref(0);
setTimeout(() => {
idx.value = 1;
console.log(idx.value);
}, 3000);
onBeforeMount(() => {
// DOM 渲染前
console.log("DOM 渲染前");
});
onMounted(() => {
// DOM 渲染完成後
console.log("DOM 渲染完成後");
});
onUpdated(() => {
// 在資料更改導致virtual DOM重新渲染後調用
console.log("資料更改後");
});
return {
idx,
};
},

其他

  • v-if 優先順序大於 v-for ,官方建議不要同時使用。
  • beforeCrate and created are replaced by setup()
  • <a href="Javascript:;"> 類似 @click.prevent