热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

和touchmovevue_[译]Hooks对Vue而言意味着什么

原文地址:WhatHooksMeanforVue原文作者:SarahDrasner译文出自:掘金翻译计划本文永久链接:htt

15e284b2c42409538e50a6962909fdf0.png

  • 原文地址:What Hooks Mean for Vue

  • 原文作者:Sarah Drasner

  • 译文出自:掘金翻译计划

  • 本文永久链接:https://github.com/xitu/gold-miner/blob/master/TODO1/what-hooks-mean-for-vue.md

  • 译者:Ivocin

  • 校对者:LeoYang, TUARAN

不要把 Hooks 和 Vue 的生命周期钩子(Lifecycle Hooks) 弄混了,Hooks 是 React 在 V16.7.0-alpha 版本中引入的,而且几天后 Vue 发布了其概念验证版本。虽然 Hooks 是由 React 提出的,它是一个对各 Javascript 框架生态系统都有价值的、重要的组合机制,因此我们今天会花一点时间讨论 Hooks 意味着什么。

Hooks 主要是对模式的复用提供了一种更明确的思路 —— 避免重写组件本身,并允许有状态逻辑的不同部分能无缝地进行协同工作。

最初的问题

就 React 而言,问题在于:在表达状态的概念时,类是最常见的组件形式。无状态函数式组件也非常受欢迎,但由于它们只能单纯地渲染,所以它们的用途仅限于展示任务。

类本身存在一些问题。例如,随着 React 变得越来越流行,类的问题也普遍成为新手的阻碍。开发者为了理解 React,也必须理解类。绑定使得代码冗长且可读性差,并且需要理解 Javascript 中的 this。这里还讨论了使用类所带来的一些优化障碍。

在逻辑复用方面,我们通常使用 render props 和高阶组件等模式。但使用这些模式后会发现自己处于类似的“厄运金字塔”中 —— 样式实现地狱,即过度使用嵌套可能会导致组件难以维护。这导致我想对 Dan Abramov 像喝醉了一样大吼大叫,没有人想要那样。

Hooks 允许我们使用函数调用来定义组件的有状态逻辑,从而解决这些问题。这些函数调用变得更具有组合性、可复用性,并且允许我们在使用函数式组件的同时能够访问和维护状态。React 发布 Hooks 时,人们很兴奋 —— 下面你可以看到 Hooks 展示的一些优势,关于它们如何减少代码和重复:

将 @dan_abramov 的代码(来自 #ReactConf2018)可视化,你能看到 React Hooks 为我们带来的好处。pic.twitter.com/dKyOQsG0Gd

— Pavel Prichodko (@prchdk) 2018 年 10 月 29 日

在维护方面,简单性是关键,Hooks 提供了一种单一的、函数式的方式来实现逻辑共享,并且可能代码量更小。

为什么 Vue 中需要 Hooks?

读到这里你肯定想知道 Hooks 在 Vue 中必须提供什么。这似乎是一个不需要解决的问题。毕竟,类并不是 Vue 主要使用的模式。Vue 提供无状态函数式组件(如果需要它们),但为什么我们需要在函数式组件中携带状态呢?我们有 mixins 用于组合可以在多个组件复用的相同逻辑。问题解决了。

我想到了同样的事情,但在与 Evan You 交谈后,他指出了我忽略的一个主要用例:mixins 不能相互消费和使用状态,但 Hooks 可以。这意味着如果我们需要链式封装逻辑,可以使用 Hooks。

Hooks 实现了 mixins 的功能,但避免了 mixins 带来的两个主要问题:

  • 允许相互传递状态。

  • 明确指出逻辑来自哪里。

如果使用多个 mixins,我们不清楚哪个属性是由哪个 mixins 提供的。使用 Hooks,函数的返回值会记录消费的值。

那么,这在 Vue 中如何运行呢?我们之前提到过,在使用 Hooks 时,逻辑在函数调用时表达从而可复用。在 Vue 中,这意味着我们可以将数据调用、方法调用或计算属性调用封装到另一个自定义函数中,并使它们可以自由组合。数据、方法和计算属性现在可用于函数式组件了。

例子

让我们来看一个非常简单的 hook,以便我们在继续学习 Hooks 中的组合例子之前理解构建块。

useWat?

好的,Vue Hooks 和 React Hooks 之间存在交叉部分。使用 use 作为前缀是 React 的约定,所以如果你在 React 中查找 Hooks,你会发现 Hooks 的名称都会像 useStateuseEffect 等。更多信息可以查看这里。

在 Evan 的在线 demo 里,你可以看到他在何处访问 useStateuseEffect 并用于 render 函数。

如果你不熟悉 Vue 中的 render 函数,那么看一看官网文档可能会有所帮助。

但是当我们使用 Vue 风格的 Hooks 时,我们会如何命名呢 —— 你猜对了 —— 比如: useData, useComputed等。

因此,为了让我们看看如何在 Vue 中使用 Hooks,我创建了一个示例应用程序供我们探索。

详见视频演示:https://css-tricks.com/wp-content/uploads/2019/01/hooks-demo-shorter.mp4

演示网站

GitHub 仓库

在 src/hooks 文件夹中,我创建了一个 hook,它在 useMounted hook 上阻止了滚动,并在 useDestroyed上重新启用滚动。这有助于我在打开查看内容的对话框时暂停页面滚动,并在查看对话框结束时再次允许滚动。这是一个好的抽象功能,因为它在整个应用程序中可能会多次使用。

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 一样的 Vue 组件中调用它:

import { preventscroll } from "./../hooks/preventscroll.js";

...

export default {

...

hooks() {

preventscroll();

}

}

我们不仅可以在该组件中使用它,还可以在整个应用程序中使用相同的功能!

能够相互理解的两个 Hooks

我们之前提到过,Hooks 和 mixins 之间的主要区别之一是 Hooks 实际上可以互相传值。让我们看一下这个简单但有点不自然的例子。

在我们的应用程序中,我们需要在一个可复用的 hook 中进行计算,还有一些需要使用该计算结果的东西。在我们的例子中,我们有一个 hook,它获取窗口宽度并将其传递给动画,让它知道只有当我们在更大的屏幕上时才会触发。

详见视频演示:https://css-tricks.com/wp-content/uploads/2019/01/hook-logo.mp4

第一个 hook:

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

}

}

然后,在第二个 hook 中,我们使用它来创建一个触发动画逻辑的条件:

// 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

}

}

},

...

然后,在组件内部,我们将一个 hook 作为参数传递给另一个 hook:

import { logolettering } from "./../hooks/logolettering.js";

import { windowwidth } from "./../hooks/windowwidth.js";

export default {

hooks() {

logolettering(windowwidth());

}

};

现在我们可以在整个应用程序中使用 Hooks 来编写逻辑!再提一下,这是一个用于演示目的不太自然的例子,但你可以看到这对于大型应用程序,将逻辑保存在较小的、可复用的函数中是有效的。

未来的计划

Vue Hooks 现在已经可以与 Vue 2.x 一起使用了,但仍然是实验性的。我们计划将 Hooks 集成到 Vue 3 中,但在我们自己的实现中可能会偏离 React 的 API。我们发现 React Hooks 非常鼓舞人心,正在考虑如何向 Vue 开发人员介绍其优势。我们想以一种符合 Vue 习惯用法的方式来做,所以还有很多实验要做。

你可以查看这个仓库作为起步。Hooks 可能会成为 mixins 的替代品,所以虽然这个功能还处于早期阶段,但是一个在此期间探索其概念是有好处的。

(真诚地感谢 Evan You 和 Dan Abramov 为本文审阅。)

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。

c3205fe4c4efc96cb6290f96c1442734.png




推荐阅读
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • React 小白初入门
    推荐学习:React官方文档:https:react.docschina.orgReact菜鸟教程:https:www.runoob.c ... [详细]
  • 详解 Python 的二元算术运算,为什么说减法只是语法糖?[Python常见问题]
    原题|UnravellingbinaryarithmeticoperationsinPython作者|BrettCannon译者|豌豆花下猫(“Python猫 ... [详细]
  • 程序员_阿里Antd藏圣诞节彩蛋 程序员被离职
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了阿里Antd藏圣诞节彩蛋程序员被离职相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 我正在尝试使用scrapycrallsingle运行完美运行的scrapy蜘蛛,但我无法在python脚本中运行它.主要问题是从不执行SingleBlogSpider.parse方 ... [详细]
  • ReactJSUIAnt设计空组件原文:https://w ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了Flutter添加APP启动StoryView相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 前言作为一个移动端初学者、爱好者,能使用前端技术开发原生游戏一直是一件渴望而不可及的事情,暂且不说游戏逻辑的复杂度,算法的健壮性ÿ ... [详细]
  • 随着前端技术的发展,越来越多的开发者开始使用react、vue等web框架,但很少有人深入理解这些框架的源码。然而,这些框架底层都是由原生的javascript构建而成。对于初学前端的人来说,可能会认为javascript很容易上手,但实际上只是因为它被高度封装了。与能够使用封装类的人相比,能够理解框架原理的人则处于另一个层面。本文将深入剖析jquery源码,探寻框架底层的原理,帮助读者更好地理解web框架的运行机制。 ... [详细]
  • CentOS7.8下编译muduo库找不到Boost库报错的解决方法
    本文介绍了在CentOS7.8下编译muduo库时出现找不到Boost库报错的问题,并提供了解决方法。文章详细介绍了从Github上下载muduo和muduo-tutorial源代码的步骤,并指导如何编译muduo库。最后,作者提供了陈硕老师的Github链接和muduo库的简介。 ... [详细]
  • PyTorch框架中有一个非常重要且好用的包:torchvision,该包主要由3个子包组成,分别是:torchvision.datasets、torchvision.models、torchv ... [详细]
author-avatar
罗丝012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有