Zusätzlich zu den standardmäßig integrierten Direktiven der Kernfunktionen (
v-model
undv-show
). usw.) ermöglicht Vue auch das Registrieren benutzerdefinierter Direktiven. Beachten Sie, dass in Vue2.0 Komponenten die Hauptform der Wiederverwendung und Abstraktion von Code sind. In einigen Fällen müssen Sie jedoch dennoch Operationen auf niedriger Ebene für gewöhnliche DOM-Elemente ausführen. In diesem Fall werden benutzerdefinierte Anweisungen verwendet. [Teilen von Lernvideos: vue-Video-Tutorial, web front-end video]v-model
和v-show
等),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。【学习视频分享:vue视频教程、web前端视频】
作为使用Vue
的开发者,我们对Vue
指令一定不陌生,诸如v-model
、v-on
、v-for
、v-if
等,同时Vue也为开发者提供了自定义指令的api,熟练的使用自定义指令可以极大的提高了我们编写代码的效率,让我们可以节省时间开心的摸鱼~
对于Vue的自定义指令相信很多同学已经有所了解,自定义指令的具体写法这里就不细讲了,官方文档很详细。 但是不知道各位同学有没有这种感觉,就是这个技术感觉很方便,也不难,我也感觉学会了,就是不知道如何去应用。这篇文档就是为了解决一些同学的这些问题才写出来的。
PS:这次要讲的自定义指令我们主要使用的是vue2.x
的写法,不过vue3.x
不过是几个钩子函数有所改变,只要理解每个钩子函数的含义,两者的用法差别并不大。
我的上篇文章说到要自己实现一个v-model
指令,这里使用v-myodel
模拟一个简易版的,顺便再领不熟悉的同学熟悉一下自定义指令的步骤和注意事项。
首先梳理思路:原生input
控件与组件的实现方式需要区分,input
的实现较为简单,我们先实现一下input
的处理。
首先我们先定义一个不做任何操作的指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
上面的注释中详细的说明了各个钩子函数的调用时机,因为我们是给组件上添加input
事件和value
绑定,因此我们在bind
这个钩子函数中定义即可。所以我们把其他的先去掉,代码变成这样。
1 2 3 4 5 |
|
简单说一下bind
函数的几个回调参数,el
是指令绑定组件对应的dom
,binding
是我们的指令本身,包含name
、value
、expression
、arg
等,vnode
就是当前绑定组件对应的vnode
结点,oldVnode
就是vnode
更新前的状态。
接下来我们要做两件事:
input
事件,同步input
的value
值到外部value
值绑定,监听value
的变化,更新到input
的value
这对于input
原生组件比较容易实现:
1 2 3 4 5 6 7 8 9 |
|
这里解释一下上面的代码,vnode.context
是什么呢,他就是我们指令所在组件的上下文环境,可以理解就是指令绑定的值所在的组件实例。不熟悉vnode
结构的同学建议先看一下官方的文档,不过文档描述的比较简单,不是很全面,所以最好在控制台log
一下vnode
的对象看一下它具体的结构,这很有助于我们封装自定义指令,对理解Vue
原理也很有帮助。
我们可以通过context[binding.expression]
获取v-model上到绑定的值,同样可以修改它。上面的代码中我们首先通过在添加的input事件中操作vnode.context[binding.expression] = e.target.value
同步input
的value
值到外部(context
),与使用@input
添加事件监听效果是一样的;然后我们需要做第二件事,做value
值的绑定,监听value
的变化,同步值的变更到input
的value
上,我们想到我们可以使用Vue实例上的额$watch
方法监听值的变化,而context
就是那个Vue
实例,binding.expression
Vue
verwenden, müssen mit Vue
-Anweisungen wie v-model
, v-on</ vertraut sein code>, <code>v-for
, v-if
usw. Gleichzeitig stellt Vue Entwicklern auch eine API für benutzerdefinierte Anweisungen zur Verfügung Verbessern Die Effizienz unseres Code-Schreibens ermöglicht es uns, Zeit zu sparen und glücklich zu fischen~🎜🎜Für Vue< Ich glaube, dass viele Schüler bereits über die benutzerdefinierten Anweisungen Bescheid wissen. Ich werde hier nicht näher darauf eingehen, wie man benutzerdefinierte Anweisungen schreibt. Die offizielle Dokumentation ist sehr detailliert. Aber ich weiß nicht, ob es für Sie Studenten so ist. Ich habe auch das Gefühl, dass ich sie gelernt habe, aber ich weiß nicht, wie ich sie anwenden soll. Dieses Dokument wurde geschrieben, um diese Probleme einiger Studenten zu lösen. 🎜🎜PS: Die benutzerdefinierten Anweisungen, über die wir dieses Mal sprechen werden, verwenden hauptsächlich die Schreibmethode von vue2.x
, aber vue3.x
ist nur einige davon Hook-Funktionen Es gibt Änderungen. Solange Sie die Bedeutung der einzelnen Hook-Funktionen verstehen, gibt es keinen großen Unterschied in der Verwendung zwischen den beiden. 🎜v-model
-Anweisung implementieren muss. Hier verwenden wir v-myodel
, um eine einfache Version zu simulieren. Übrigens werden wir unbekannte Schüler mit den Schritten und Vorsichtsmaßnahmen benutzerdefinierter Anweisungen vertraut machen. 🎜Eingabe
-Steuerelemente und -Komponenten müssen unterschieden werden, < code>input ist relativ einfach. Implementieren wir zunächst die Verarbeitung von input
.
Zuerst definieren wir zunächst eine Anweisung, die keine Operation ausführt🎜1 |
|
input
-Ereignisse und value hinzufügen Komponente
Binding, sodass wir sie in der Hook-Funktion bind
definieren können. Also entfernen wir zuerst die anderen und der Code sieht so aus. 🎜1 2 3 4 |
|
bind
sprechen. el
ist der dom
, der der Anweisungsbindungskomponente entspricht, und binding< /code> ist unsere Anweisung selbst, einschließlich <code>name
, value
, expression
, arg
usw. , vnode
ist der vnode
-Knoten, der der aktuell gebundenen Komponente entspricht, und oldVnode
ist der Zustand vor der Aktualisierung von vnode
. 🎜🎜Als nächstes müssen wir zwei Dinge tun: 🎜input
-Ereignis und synchronisieren Sie den value
-Wert von input
mit Externevalue
-Wertbindung, überwacht Änderungen im value
und aktualisiert den value
der Eingabe</code > ></li></ul>🎜Dies ist einfacher für native <code>input
-Komponenten zu implementieren: 🎜1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
vnode.context</ ist code>? Es ist der Kontext der Komponente, in der sich unsere Anweisung befindet. Es kann verstanden werden, dass es sich um die Komponenteninstanz handelt, in der sich der an die Anweisung gebundene Wert befindet. Studenten, die mit der Struktur von <code>vnode
nicht vertraut sind, wird empfohlen, zuerst die offizielle Dokumentation zu lesen. Die Beschreibung im Dokument ist jedoch relativ einfach und nicht sehr umfassend, daher ist es am besten, log
in der Konsole. Werfen wir einen Blick auf die spezifische Struktur des vnode-Objekts. Dies ist für uns sehr hilfreich, um benutzerdefinierte Anweisungen zu kapseln, und ist auch hilfreich für das Verständnis des Vue
Prinzip. 🎜🎜Wir können den Bindungswert für das V-Modell über context[binding.expression]
abrufen und ihn auch ändern. Im obigen Code synchronisieren wir zunächst den value< von <code>input
, indem wir vnode.context[binding.expression] = e.target.value
in der hinzugefügten Eingabe ausführen event. /code>Value nach außen (context
), der Effekt ist derselbe wie die Verwendung von @input
, um das Abhören von Ereignissen hinzuzufügen; value
Wertbindung durchführen, Änderungen in value
überwachen, Wertänderungen mit value
von input
synchronisieren, wir dachten, wir könnten es Verwenden Sie die $watch
-Methode auf der Vue-Instanz, um Wertänderungen zu überwachen, und context
ist die Vue
-Instanz binding.expression</code >Es ist das Attribut, das wir überwachen wollen, wenn wir so schreiben 🎜<p>参考vue实战视频讲解:<a href="https://www.php.cn/link/56044f39f04b62676dfe11ce3c080741" target="_blank" rel="nofollow noopener noreferrer" title="https://kc7474.com/archives/1477" ref="nofollow noopener noreferrer">进入学习</a></p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'><input v-mymodel=&#39;message&#39;/></pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div><p>那么<code>binding.expression
就是字符串'message'
。所以我们想下面的代码这样监听绑定的响应式数据。1 2 3 4 |
|
至此,input
的v-mymodel
的处理就完成了(当然input
组件还有type
为checkbox
,radio
,select
等类型都需要去特别处理,这里就不再一一处理了,感兴趣的同学可以自己尝试去完善一下),但是对于非原生控件的组件,我们要特殊处理。
因此我们完善代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
接下来我们要处理的是自定义组件的逻辑,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
声明一下,上面的实现不是vue
源码的实现方式,vue
源码中实现v-model
更加复杂一点,是结合自定义指令、模板编译等去实现的,因为我们是应用级别的封装,所以采用了上述的方式实现。
实现此v-mymodel
需要同学去多了解一下Vnode
和Component
的API
,就像之前说的,最简单的方法就是直接在控制台中直接打印出vnode
对象,组件的vnode
上有Component
的实例componentInstance
。
接下来简单说一下上面的代码,首先我们可以在componentOptions.Ctor.extendOptions
上找到model
的定义,如果没有的话需要设置默认值value
和input
,然后分别对想原生input
的处理一样,分别监听binding.expression
的变化和modelEvent
事件即可。
需要注意的是,我们上面的代码直接给_prop
做了赋值操作,这实际上是不符合规范的,但是我目前没有找到更好的方法去实现,有好思路的同学可以在评论区留言指教。
下面?是完整的源码:
上文我们通过封装v-mymodel
为各位同学展示了如何封装和使用自定义指令,接下来我把自己在生产实践中使用自定义指令的一些经验分享给大家,通过实例,我相信各位同学能够更深刻的理解如何在在应用中封装自己的指令,提高效率。
下面我们定义一个v-permission
指令用于全平台的权限控制
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
|
简单说一下上面?指令的定义思路和使用方法。整体思路就是通过processingType处理权限逻辑,使用el.style.display控制组件显示或隐藏。我在这里从日常应用中提取了一些通用的processingType中的权限处理方式,方便大家理解也供大家参考。
下面逐一说一下权限指令各个类型的使用方法:
1 2 3 4 5 6 7 8 9 10 |
|
v-input 输入框限制,限制数字、保留n位小数点等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
|
这里需要特别注意的是下面这行代码
1 |
|
我们为什么需要添加这一句呢,我们明明已经为target.value做了赋值。
实际上这一句代码相当于指令作用组件内部的$emit('input',target.value)
,这是因为如果我们是在antd或者elementui中的输入框组件上添加我们定义的v-input指令,直接为target.value赋值是不能生效的,修改的只是原生input控件value值,并没有修改自定义组件的value,还需要通过触发input事件去同步组件状态,修改value值。(这里不了解为什么需要触发input事件区同步状态的同学了解一下v-model的语法糖原理即可理解,
使用方法:
1 2 3 4 |
|
我们也可以通过自定义指令做对内容到处理,比如
空值处理
数字千分数逗号分割
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
千分位分割代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
使用方法:
1 2 3 |
|
v-preview方便的实现文件预览功能
预览图片;
预览文件;
其他预览类业务功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
使用方法:
1 2 3 4 |
|
各位同学可以试着自己实现一个v-loading
的加载中的指令,通过设置一个bool
值来设置容器的加载状态。
如有疑问可以在评论区留言。
本文主要讲了如下几件事:
vue
自定义指令介绍v-model
Das obige ist der detaillierte Inhalt vonErfahren Sie mehr über benutzerdefinierte Anweisungen in Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!