ref()
為 Reactivity API 最重要的 API,用來宣告 State。只要我們在 JavaScript 修改 state,HTML 就會 Reactive 地跟著改變;反之若我們在 HTML 修改 state,JavaScript 也會隨之改變。
Version
Vue 3.4
Composition API
<template>
<button class="plus" @click="onClick">+</button>
<div class="result">{{ count }}</div>
</template>
<script setup>
import { ref } from 'vue'
let count = ref(0)
let onClick = () => count.value++
</script>
<style scoped>
.plus {
cursor: pointer;
}
.result {
color: red;
}
</style>
- Counter 可視為前端 的 Hello World,雖然簡單,卻有很多觀念在裡面
<template>
</template>
<script setup>
</script>
<style scoped>
</style>
- Vue 分成 3 大區塊:
- template:寫 HTML
- script:寫 JavaScript
- style:寫 CSS
剛好一個 component (
.vue
) 同時具備 HTML、JavaScript、CSS
- template:
- Vue 3 解除 Vue 2 所有 HTML 必須在一個 root element 限制
- script:
- setup:支援 Script Setup,所有代碼會被 Vite 放進
setup()
- setup:支援 Script Setup,所有代碼會被 Vite 放進
- style:
- scoped:所有的 class 只在此
.vue
內有效,避免 side effect
- scoped:所有的 class 只在此
Q:若有跨 page 需求的 CSS sytle 呢?
A:請將該需求抽成 component,而非使用 global CSS
Line 1
<template>
<button class="plus" @click="onClick">+</button>
<div class="result">{{ count }}</div>
</template>
- @:原本應為
v-on:click="onClick"
,其中v-on
可以縮寫成@
,表示指定 event handler - Text Interpolation:將 state
單向
顯示在 HTML,只要該 state 在 JavaScript 有變動,Vue 會自動 render HTML - class:指定 CSS class
<button>
是 inline element 不換行,<div>
是 block element 會換行
Line 6
<script setup>
import { ref } from 'vue'
let count = ref(0)
let onClick = () => count.value++
</script>
- ref()
- Vue 3 的 API 都是以 ESM 呈現,沒有所謂的 global function,所以要用什麼 function 都要手動 import,也有助於 Vite 運作與 Tree Shaking
- 若要定義需與
HTML 連動
的 state,必須使用ref()
宣告 - 若只是 JavaScript 不同 function 的
共用變數
,不牽涉
與 HTML 連動,則不必
使用ref()
宣告 - 使用
ref()
宣告過的變數,在 HTML 可直接讀寫,但在 JavaScript 必須透過.value
才能讀寫 - 可藉由有沒有
.value
分辨是與HTML 連動
的變數,還是普通 JavaScript 變數
- Method
- 需與 HTML template 互動的 function
- Event Handler (
@click
) - Directive (
v-if
)
- Event Handler (
- Vue 3 的 method 只需以普通 function 定義即可
- 由於 Vue 3 不必再以
this
存取 data,可大膽使用 arrow function
- 需與 HTML template 互動的 function
function
的this
因為可隨 context 而變,因此 Options API 可藉由改變 context 而指向 Vue instance,但 arrow function 的this
不可變,永遠指向 function 自己,無法透過改變 context 而指向 Vue instance
Line 14
<style scoped>
.plus {
cursor: pointer;
}
.result {
color: red;
}
</style>
- Style 區塊可如既往一樣寫 CSS
Options API
<template>
<button @click="onClick">+</button>
<div>{{ count }}</div>
</template>
<script>
export default {
data: () => ({
count: 0,
}),
methods: {
onClick() {
this.count++
},
},
}
</script>
- 最後附上相同功能的 Options API 供參考
- State 宣告在
data()
function - Method 宣告在
methods
Object
Conclusion
ref()
雖然很基本的 function,但卻非常實用,讓我們不必像 Vanilla.js 或 jQuery 一樣,不斷地讀取 HTML,不斷地寫入 HTML
,JavaScript 只需專心處理 state 即可,HTML 由 Vue 負責處理- 很多人從 jQuery 改寫 Vue 時一直跨不過去的檻:總是想手動處理 HTML,雖然 Vue 也可以這樣寫,但這並非 Vue 設計的初衷
- Vue 心法:
處理 HTML 是 Vue 的事情,我們只要專心處理 state 即可