前面幾天我們重新回顧了Vue的語法結構,還有各種內建提供的指令用法。今天的重點放在 「如何把自己寫的內容」 定義成可以複用的函式,以及 「如何自訂指令」 ?讓我們把Vue更活用,Let's go!
組合式函式讓我們能夠複用特定代碼,聽起來跟模組好像有點像?
html
、script
、style
。<script setup>
或setup()
之下使用ref()
取代reactive()
,才不會在解構過程連同內部的響應式資料一起解構範例說明: 我們依照官方示範製作一個滑鼠追蹤函式,再套用自訂圖樣改變滑鼠呈現
useMouse.js
作為組合式函式//useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'
export function useMouse() {
//注意回傳值使用ref而非reactive
const x = ref(0)
const y = ref(0)
//用來更新滑鼠位置
function nowPosition(event) {
x.value = event.pageX
y.value = event.pageY
}
//註冊監聽滑鼠移動事件
onMounted(() => window.addEventListener('mousemove', nowPosition))
//註銷監聽滑鼠移動事件
onUnmounted(() => window.removeEventListener('mousemove', nowPosition))
return { x, y }
}
進入App.vue
引入useMouse
組合式函式,接下來就是設定我們想要的游標圖片(自己畫也可以啦):
import { useMouse } from '@/assets/useJS/useMouse.js'
//可以取得x,y座標了
const { x, y } = useMouse()
只要把x,y座標套用到runStyle
上面就沒問題了!
//利用computed處理動態座標
const runStyle = computed(() => {
return {
'width': '28px',
'position': 'absolute',
'left': x.value + 2 + 'px',
'top': y.value + 2 + 'px'
}
})
<img :style="runStyle" src="/cursor.png">
學到這裡我們對Vue的內建指令(v-on
、v-model
...)已經不陌生了,那麼透過 自定義指令 我們可以做到什麼事情呢?它主要是讓我們能複用 「對普通元素DOM的訪問邏輯」 ,直接上範例來瞧瞧它是怎麼運作的!
<script setup>
建構模式下使用:on
) const vFocus = {
//透過參數el達成.focus()效果,指定元素處於焦點狀態
mounted:(el) => el.focus()
}
<input v-focus type="text" placeholder="請輸入文字"/>
directives
註冊自訂指令export default {
setup() {
},
directives: {
//這裡命名不需要加上v
focus: {
mounted: (el) => el.focus()
}
}
}
//引用時一樣以v-xxx呼叫
<input v-focus type="text" placeholder="請輸入文字"/>
app.directive('focus', (el, binding) => {
//這會在mounted和updated時都調用
el.focus()
})
上面提到了內部可以定義掛載在不同的生命週期鉤子上,大致上分為這些:
created
(el, binding, vnode, prevVnode):在事件監聽器應用前調用beforeMount
(el, binding, vnode, prevVnode):在元素綁定DOM前調用mounted
(el, binding, vnode, prevVnode):元素與父組件綁定和其子節點掛載完調用beforeUpdate
(el, binding, vnode, prevVnode):綁定元素的父組件更新前調用updated
(el, binding, vnode, prevVnode):綁定元素與父組件和其子節點更新完調用beforeUnmount
(el, binding, vnode, prevVnode):綁定元素的父組件卸載前調用unmounted
(el, binding, vnode, prevVnode):綁定元素的父組件卸載後調用鉤子函式內部提供相關參數讓我們可以針對元素進行狀態設定:
el
:可以針對指令綁定元素直接操作DOMbinding
:一個對象,包含以下屬性:
value
:傳遞給指令的值oldValue
:之前的值,僅在beforeUpdate
和updated
中可用,如:v-test="2",值為2arg
:傳遞給指令的參數,如:v-test:hello,參數為hellomodifiers
:一個包含修飾符的對象,如:v-test.hello,修飾符對象是 { hello: true }instance
:使用該指令的組件實例dir
:指令的定義對象vnode
:代表綁定元素的底層VNode
prevVnode
:代表之前的渲染中指令所綁定元素的VNode
,僅在beforeUpdate
和updated
鉤子中可用官方針對上述參數的提示:
Note
除了 el 外,其他參數都是只讀的,不要修改它們。
如你需要在不同的鉤子間共享信息,建議通過元素的 dataset 屬性實現。
雖然自定義指令看似方便,但如果vue內建指令已經很夠用的情況下還是先以內建指令的使用為優先,後續才不會造成過多的渲染負擔喔!