Hooks對(duì)于Vue作用意義詳解

前言
本篇主體譯自:https://css-tricks.com/what-hooks-mean-for-vue/
作者:Sarah Drasner
OS:雖然這是一篇 19 年 4 月的文章,但是對(duì)于 Hooks 說(shuō)的非常清晰,作者也是請(qǐng)到尤大進(jìn)行了原文的訂正,對(duì)于了解 Vue Hooks 的設(shè)計(jì)及發(fā)展,還是有很好的閱讀性的。
本文要談到的 Hooks,不同于 Lifecycle Hooks(生命周期鉤子),它是在 v16.7.0-alpha 中引入 React 的;盡管 Hooks 是由 React 提出,但是它的本質(zhì)是一種重要的代碼組合機(jī)制,對(duì)于整個(gè) JavaScript 的框架系統(tǒng)都大有好處;今天花點(diǎn)時(shí)間具體來(lái)談?wù)劊?strong>Hooks 對(duì)于 Vue 意義著什么?
Hooks 提供了一種更明確的方式來(lái)組織代碼,使得代碼能重用,更重要的是,它允許不同的邏輯部分進(jìn)行通信、協(xié)同工作。
問(wèn)題背景
Hooks 為什么被提出?就 React 而言,最初的問(wèn)題背景是這樣的:
在表達(dá)狀態(tài)概念時(shí),類 是最常見(jiàn)的組織形式。類本身存在一些問(wèn)題,比如綁定關(guān)系冗長(zhǎng)、復(fù)雜,導(dǎo)致不易讀,This 的指向總會(huì)讓人摸不清頭腦;
不僅如此,在重用方面,使用渲染工具或高階組件類的模式很常見(jiàn),但這樣容易陷入 “pyramid of doom” (末日金字塔),可以將它理解為過(guò)度的嵌套關(guān)系;
Hooks 就是來(lái)解決這些問(wèn)題的;Hooks 允許我們使用函數(shù)調(diào)用來(lái)定義組件的狀態(tài)邏輯,這些函數(shù)有更強(qiáng)的組合性、重用性;同時(shí),仍然可以進(jìn)行狀態(tài)的訪問(wèn)和維護(hù);
示例:@dan_abramov's code from #ReactConf2018
圖①

圖②

有圖①到圖②的轉(zhuǎn)變,對(duì)組件代碼進(jìn)行了再次組合,然后以函數(shù)的的方式進(jìn)行導(dǎo)出,供外部重用;
在維護(hù)方面,Hooks 提供了一種單一的、功能性的方式來(lái)處理共享邏輯,并有可能減少代碼量。
Vue Hooks
那 Vue 中為什么要用 Hooks 呢?畢竟 Vue 中沒(méi)有很頻繁的使用類;在 Vue 中我們使用 mixin 來(lái)解決組件相同的重用邏輯;
mixin 的問(wèn)題在哪?Hooks 能解決嗎?
問(wèn)題主要有兩點(diǎn):
- mixin 之間不能傳遞狀態(tài);
- 邏輯來(lái)源并沒(méi)有清晰的說(shuō)明;
而這兩點(diǎn),Hooks 能很好地解決;
舉個(gè)例子:
傳遞狀態(tài)
Hooks1
import { useData, useMounted } from 'vue-hooks';
export function windowwidth() {
const data = useData({
width: 0
})
useMounted(() => {
data.width = window.innerWidth
})
// this is something we can consume with the other hook
return {
data
}
}Hooks2
// the data comes from the other hook
export function logolettering(data) {
useMounted(function () {
// this is the width that we stored in data from the previous hook
if (data.data.width > 1200) {
// we can use refs if they are called in the useMounted hook
const logoname = this.$refs.logoname;
Splitting({ target: logoname, by: "chars" });
TweenMax.staggerFromTo(".char", 5,
{
opacity: 0,
transformOrigin: "50% 50% -30px",
cycle: {
color: ["red", "purple", "teal"],
rotationY(i) {
return i * 50
}
}
},
...兩個(gè)鉤子之間傳值:
<script>
import { logolettering } from "./../hooks/logolettering.js";
import { windowwidth } from "./../hooks/windowwidth.js";
export default {
hooks() {
logolettering(windowwidth());
}
};
</script>我們可以在整個(gè)應(yīng)用程序中使用 Hooks 組合邏輯;
來(lái)源清晰
在 src/hooks 文件夾中,創(chuàng)建了一個(gè) Hooks,用于實(shí)現(xiàn):打開(kāi)對(duì)話框查看內(nèi)容時(shí),暫停頁(yè)面,并在查看完對(duì)話框后,允許再次滾動(dòng)。
它很有可能在應(yīng)用程序中被多次使用;
import { useDestroyed, useMounted } from "vue-hooks";
export function preventscroll() {
const preventDefault = (e) => {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
// keycodes for left, up, right, down
const keys = { 37: 1, 38: 1, 39: 1, 40: 1 };
const preventDefaultForScrollKeys = (e) => {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
useMounted(() => {
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.touchmove = preventDefault; // mobile
window.touchstart = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
});
useDestroyed(() => {
if (window.removeEventListener)
window.removeEventListener('DOMMouseScroll', preventDefault, false);
//firefox
window.addEventListener('DOMMouseScroll', (e) => {
e.stopPropagation();
}, true);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.touchmove = null;
window.touchstart = null;
document.onkeydown = null;
});
} 在 AppDetails.vue 組件中調(diào)用它:
<script>
import { preventscroll } from "./../hooks/preventscroll.js";
...
export default {
...
hooks() {
preventscroll();
}
}
</script>小結(jié)
原文小結(jié)
Vue Hooks 已經(jīng)可以與 Vue 2.x 一起使用,但仍處于試驗(yàn)階段。我們計(jì)劃將 Hooks 集成到 Vue 3 中,但是它跟 React Hooks 還是會(huì)有所差異;
本瓜小結(jié)
Hooks 已經(jīng)應(yīng)用到 Vue3 了,也就是 setup 那一坨,但是它確實(shí)有一些不同于 React 的 Hooks 的地方;推薦閱讀 Vue3 究竟好在哪里?(和 React Hook 的詳細(xì)對(duì)比);
其實(shí)理解到它的設(shè)計(jì)意圖了,即使不原原本本的挪用框架,自己用 JS 原生,也能整一個(gè)類似的復(fù)用邏輯吧。把實(shí)現(xiàn)一個(gè)完整功能的邏輯,封裝進(jìn)一個(gè)函數(shù)中,就看函數(shù)名稱,就知道它是干嘛的了,不用知道其內(nèi)部實(shí)現(xiàn),如果想知道,再到對(duì)應(yīng)的 hooks 里面去找,至少就這一點(diǎn)來(lái)說(shuō),和函數(shù)式編程設(shè)計(jì)思路是一致的;
以上就是Hooks之于Vue意義詳解的詳細(xì)內(nèi)容,更多關(guān)于Hooks Vue意義的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue組件實(shí)現(xiàn)可搜索下拉框擴(kuò)展
這篇文章主要為大家詳細(xì)介紹了vue組件實(shí)現(xiàn)可搜索下拉框的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
最細(xì)致的vue.js基礎(chǔ)語(yǔ)法 值得收藏!
這篇文章主要為大家推薦了一篇值得收藏和學(xué)習(xí)的vue.js最細(xì)致的基礎(chǔ)語(yǔ)法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Vue開(kāi)發(fā)實(shí)例探究key的作用詳解
這篇文章主要為大家介紹了Vue開(kāi)發(fā)實(shí)例探究key的作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
vue項(xiàng)目中圖片選擇路徑位置static或assets的區(qū)別及說(shuō)明
這篇文章主要介紹了vue項(xiàng)目中圖片選擇路徑位置static或assets的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
until封裝watch常用邏輯簡(jiǎn)化代碼寫(xiě)法
這篇文章主要介紹了until將watch最常用的邏輯進(jìn)行封裝簡(jiǎn)化代碼寫(xiě)法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07

