composables 中文為可組合的
程式就像是積木一樣,會希望將一再重複的東西變成積木重複使用它(根據需求去組合)
在 vue2 的時候有一個 mixins
讓使用者把組件重複的東西(data, methods, 生命週期...etc)抽出來
但是 mixins 有幾個問題
參考官網:
https://cn.vuejs.org/guide/reusability/composables.html#comparisons-with-other-techniques
其中我覺得最大的問題是同名稱會互相覆蓋
舉個非常簡單的例子
function sayHi() {
console.log("hi");
}
function sayHi() {
console.log("hi hi");
}
sayHi(); //hi hi
在 vue 也是,如果組件引用的 mixins 和 該組件有同名稱的方法,組件會把 mixins 的方法覆蓋掉
更詳細可以看這篇下面的例子:
https://www.twblogs.net/a/5ee7b6fb93db66959e4cc98f
到了 vue3 推出新的東西叫做 composables 組合式函數,目的是取代 mixins
我們來看一下官方的範例:
<script setup>
//如同一般在寫 js 一樣引入 export 的方法
import { useMouse } from './mouse.js'
const { x, y } = useMouse()
</script>
<template>
Mouse position is at: {{ x }}, {{ y }}
</template>
//引用需要的 vue3
//ref == vue2 的 data
//onMounted == vue2 的 mounted
//onUnmounted == vue2 的 destroyed
import { ref, onMounted, onUnmounted } from 'vue'
export function useMouse() {
//宣告2個變數之後回傳給需要用到的組件
const x = ref(0)
const y = ref(0)
function update(event) {
//ref的值要用value賦值
x.value = event.pageX
y.value = event.pageY
}
//組件掛載時 註冊滑鼠移動事件
onMounted(() => window.addEventListener('mousemove', update))
//組件解除掛載時將事件監聽解除 (ex 昨天的例子:切換不同路由)
//不解除會影響效能
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
組件寫法要改成這樣
<script>
import { useMouse } from './mouse.js'
export default {
setup(){
const { x, y } = useMouse()
return {x,y}
}
}
</script>
看完上面的例子,如果有用過 React 一定覺得很像在寫 hooks (useState,UseEffect)
沒錯官方也承認這點:
https://cn.vuejs.org/guide/reusability/composables.html#comparisons-with-other-techniques
組合式函數
解決了以往mixins
會碰到的問題,讓開發者把重複的邏輯或變數能自由地抽出去共用
也支援生命週期的使用,讓資料維持響應式的同時也大大增加了程式碼的可維護性
讀者們不彷親自玩玩看~
https://cn.vuejs.org/guide/reusability/composables.html#conventions-and-best-practices
https://ithelp.ithome.com.tw/m/articles/10259305