创建Vue.js自定义指令

照片 by [雅诗兰黛森斯]

指令是带有v前缀的特殊属性。指令的工作是当其表达式的值发生变化时,对DOM反应性地应用副作用。js提供了广泛的指令供您使用。您可能已经使用了v-if、v-repeat、v-model和v-show指令。

在本文中,我将解释指令的各个部分以及可以使用的内容。然后,我将向您展示如何创建各种自定义指令,以便您可以将编程需求直接应用于DOM元素。因此,让我们开始讨论指令中包含的内容。

指令名称

最基本的自定义指令只有一个名称。它不接受任何参数,也没有任何修饰符。如果不传递值,这将不是非常灵活,但您仍然可以拥有DOM元素的一些功能。

您可能熟悉的一个示例是指令的最基本版本v-else。以下是我们即将创建的自定义指令的示例:

<app-navigation v-sticky></app-navigation>

将值传递给指令

您可以将值传递给自定义指令。这是一个例子:

<div v-if="isVisible">Show this</div>

在此示例中,如果data属性isVisible为true,则显示v-if指令。我们知道这是在寻找数据属性,因为它包含在引号中。相反,如果我们想要将一个字符串作为值传递给指令,您将执行以下操作:

<div v-color="'red'">Show this</div>

参数

自定义指令可以在指令名称后面加上冒号表示的“参数”。这是一个例子:

<app-navigation v-sticky:bottom></app-navigation>

在上面的示例中,自定义指令的名称是sticky。这个参数是bottom

指令只能采用一个参数

修饰符

修饰符是由点表示的特殊后缀,表示指令应以某种特殊方式绑定。修饰符控制指令的行为方式。以下是我们稍后将创建的自定义指令的示例:

<span v-format.underline>guide</span>

在上面的例子中,。underline修饰符告诉v-format指令将下划线应用于文本。

您可以通过链接指令在指令上使用多个修饰符。这是一个例子:

<span v-format.bold.highlight.underline>guide</span>

在上面的示例中,文本将为粗体,突出显示并具有下划线。

创建自定义指令

现在您了解了Vue.js中指令的基础知识。除了核心中提供的默认指令集外,Vue还允许您注册自己的自定义指令。让我们创建自己的自定义指令。

在它的基础上,我们可以通过使用Vue.directive并为其命名来创建全局指令。以下是使用名称sticky创建自定义指令的示例。

Vue.directive('sticky');

当我们想在DOM元素上使用这个自定义指令时,它看起来像:

<app-navigation v-sticky></app-navigation>

现在我们已经创建了第一个自定义指令,现在我们需要在它后面创建代码。在编写代码之前,我们需要了解Vue为我们在custom指令中提供的值。

指令挂钩

Vue为自定义指令提供了一系列钩子。每个钩子都有一些参数选项。以下是可用的钩子:

  • bind - 当指令附加到元素时会发生这种情况。
  • inserted - 一旦元素插入父DOM就会发生这种情况
  • update - 这在元素更新时发生,但子项尚未更新
  • componentUpdated - 一旦更新了组件和子组件,就会发生这种情况
  • unbind - 删除指令后会发生这种情况

其中每个都有elbindingvnode参数可供他们使用。这些参数是:

el - 绑定所依赖的元素

binding - 一个包含传递给钩子的参数的对象。有许多可用的参数,包括name,value,oldValue,expression,arg和modifiers。

vnode - 允许您根据需要直接引用虚拟DOM中的节点。

双方bindingvnode应被视为只读。

updatecomponentUpdated都公开了一个名为oldvnode的附加参数oldvnode参数用于传递旧值和新值之间进行区分。

bindupdate是五个中最有用的。

获取代码

如果要查看所有这些自定义指令的实际操作,可以在我创建的分支中。我们将创建的所有自定义指令都可以在main.js文件中找到。只需取消注释演示编号即可查看代码

演示#1 v-sticky

如果您在代码沙箱中跟随,那么这是在main.js文件中找到的Demo#1。v-sticky指令已应用于<app-navigation>。滚动时,导航将保持固定在屏幕上。

让我们编写我们想要的v-sticky指令所具有的行为。当该指令应用于DOM元素时,我们希望在屏幕上修复该元素。这是我们的v-sticky指令的自定义代码:

Vue.directive('sticky', 
    function(el, binding, vnode) {
        el.style.position = 'fixed';
    }
));

让我们分解一下代码中的内容。我正在使用Vue.directive创建一个名为“ sticky ” 的新全局指令。在名称之后,我们有一个函数,它具有我们之前讨论过的三个参数。在函数中,我正在使用指令已经应用的元素并获得它的样式然后它的位置。我把它设置为固定。

稍后我们将修改器应用于此自定义指令。

演示#2 v-orange

我们将创建的下一个自定义指令是v-orange。该指令将文本颜色设置为橙色。以下是此指令的代码:

Vue.directive("orange", function(el, binding, vnode) {
    el.style.color = "orange";
});

我们可以将此指令应用于HelloWorld组件中显示的消息。应用后,欢迎消息现在为橙色。


v-orange指令中的橙色文本

演示#3 v-color

之前的指令不是很通用。如果您希望文本为蓝色而不是橙色,则必须编写另一个自定义指令。我们将创建一个名为v-color的新自定义指令。此自定义指令将采用将传递给它的值。此值是我们要应用于欢迎消息的颜色。

前面我提到绑定是一个对象,它包含传递给指令的参数。该对象中包含的一个项是传入的值。我们将在代码中使用它来将文本设置为该值。

Vue.directive("color", function(el, binding, vnode) {
    el.style.color = binding.value;
});

现在我们的指令更加灵活。您可以传入任何众所周知的颜色字符串,如“红色”或“蓝色”,并传入有效的十六进制颜色,如#ffff00。这是我们新的v-color指令的图像被应用三次。第一次颜色为红色,第二次颜色为蓝色,最后一次颜色为黄色,使用#ffff00的十六进制代码。

我们的v-color自定义指令的结果

演示#4 v-sticky带有参数

您可以为自定义指令提供参数。我们将修改我们v-sticky之前创建的代码以接受参数。大多数网站的屏幕顶部都有导航,屏幕底部有一个页脚。

我们将使用该参数告诉我们导航是否应固定在屏幕的顶部或底部。绑定对象将包含一个名为arg的值,该值包含我们传递给自定义指令的参数。

为了简化操作,如果没有参数传递给指令,我假设导航应该固定在屏幕的顶部。如果我收到一个参数,那么导航将固定在屏幕的底部。

为了区分顶部和底部导航,我在顶部导航中添加了灰色的背景颜色,在底部导航中添加了棕褐色。这是代码:

Vue.directive("sticky", function(el, binding, vnode) {
  const loc = binding.arg === "bottom" ? "bottom" : "top";
  el.style.position = "fixed";
  el.style[loc] = 0;
  if (loc === "bottom") {
    el.style.background = "burlywood";
  } else {
    el.style.background = "#7e7e7e";
  }
});

将我们更新的自定义指令应用于导航和页脚后,它看起来像这样。

使用参数的v-sticky自定义指令

使用修饰符演示#5 v-format

您可以根据需要向自定义指令添加任意数量的修饰符。我们将创建一个名为format的新自定义指令。此自定义指令将接受以下一个或多个修饰符:

  • underline
  • bold
  • highlight

binding参数是一个对象。该对象包含自定义指令的所有修饰符。绑定上的修饰符实际上也是一个对象。该对象将包含已应用的每个修改器的键。我们将使用它来应用不同的文本格式。这是代码:

Vue.directive("format", function(el, binding, vnode) {
  const modifiers = binding.modifiers;
if (modifiers.underline) {
    el.style.textDecoration = "underline";
  }
if (modifiers.bold) {
    el.style.fontWeight = "bold";
  }
if (modifiers.highlight) {
    el.style.background = "#ffff00";
  }
});

在上面的代码中,我们获取修饰符对象并将其分配给名为修饰符的变量。然后我们检查我们支持的每个可能的修饰符。如果存在该修饰符,则我们应用相应的文本修饰。

我们已将underline修饰符应用于单词指南。我们已将bold修饰符应用于配置/定制。我已将highlight修饰符应用于单词check out

为了表明您可以将多个修饰符应用于自定义指令,我已将所有三个修饰符应用于文本Installed CLI Plugins

这是它的样子。

演示#6 v-hook-demo显示生命周期钩子

之前我在您的自定义指令中讨论了可用的生命周期钩子。如果希望自定义指令基于生命周期钩子工作,则需要为代码使用不同的格式。您将拥有一个对象,而不是在自定义指令的名称后面使用函数。该对象上的键将是一个或多个可用的生命周期钩子。

在代码沙箱中,我向About视图添加了一些代码。代码有一个按钮。单击按钮时,数字会更新。

HelloWorld组件中,我已将v-hook-demo组件应用于第一个div。

这是v-hook-demo组件的代码。

Vue.directive("hook-demo", {
  bind(el, binding, vnode) {
    console.log("bind");
  },
  inserted(el, binding, vndoe) {
    console.log("inserted");
  },
  updated(el, binding, vnode) {
    console.log("updated");
  },
  componentUpdated(el, binding, vnode, oldVnode) {
    console.log("componentUpdated");
  }
});

如果刷新屏幕,看看你的控制台,你会发现bindinserted生命周期挂钩得以实施。如果您转到“关于”页面并单击该按钮,您将看到componentUpdated生命周期钩子已实现。

结论

本文概述了在Vue.js中组成指令的项目。在介绍之后,我将向您介绍创建自定义指令的六个示例。这些示例显示了一个基本的自定义指令,一个传递值的指令,一个使用参数的指令以及一个使用修饰符的指令。最后一个示例显示了可用的生命周期挂钩。

我希望你喜欢这篇文章。如果您有任何疑问或想留下反馈,请发表评论。

转:https://medium.com/js-dojo/creating-custom-directives-in-vue-js-286142392fd8

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容