您尚未登录,请登录后浏览更多内容! 登录 | 立即注册

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 16444|回复: 0
打印 上一主题 下一主题

[Vue.js] Vue.js 自定义指令

[复制链接]
跳转到指定楼层
楼主
发表于 2018-7-4 11:36:23 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
5 P1 R* f& Y, S$ A- ~, ?
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。
下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时,元素获得焦点:
实例& O; @1 U% G5 }6 V3 ^

1 T1 v- W5 j& ]0 V. ?
  1. <div id="app"># u$ ]  d9 s& u/ Q: [2 O
  2.     <p>页面载入时,input 元素自动获取焦点:</p>1 n' l- h" y$ L/ h, r! C' L& K# C  O
  3.     <input v-focus>
    ' O9 Z/ o# O/ O0 E7 [) D+ S+ C
  4. </div>
    * D' ^# U% R7 }2 o8 O

  5. 1 L) O* u+ k) t6 Y" j
  6. <script>
    3 p' |6 A3 X! `8 O! Z" Y
  7. // 注册一个全局自定义指令 v-focus
    ! ~2 i  ~, P; B5 l5 N3 r
  8. Vue.directive('focus', {
    , V6 n. D, b6 ]. E8 M: }* L
  9.   // 当绑定元素插入到 DOM 中。4 |# O6 j& M7 {6 @& h
  10.   inserted: function (el) {
    8 g8 O' y: c7 B  t9 A( Q* W
  11.     // 聚焦元素1 t- D7 C3 }: I
  12.     el.focus()  C/ s+ {2 Z( o8 H6 b" p1 R; i
  13.   }
    . _: ?3 u  ]  e2 o% I3 V
  14. })  w6 ~+ O% L2 T( _
  15. // 创建根实例* C: s3 \  V+ K/ B- P
  16. new Vue({
    % ^: M5 r; p9 Z9 I( Z
  17.   el: '#app'4 E8 F3 k7 @1 t& m$ t! i$ k# U
  18. })' c8 x/ p: u( ]1 D+ w2 a3 e
  19. </script>
复制代码
我们也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:
实例
! S( r; h) Z& q6 [+ y) ?  S
2 I9 B, F6 X: K  ~" |# D7 ~7 ]
  1. <div id="app">: }& Z0 X2 d, l1 u! m. [7 F9 t
  2.   <p>页面载入时,input 元素自动获取焦点:</p>$ c& N+ p. ^- s  q" [% M
  3.   <input v-focus>
    # j- m" [5 C5 S, C6 X# Z5 p9 S
  4. </div>
    + R% L9 ]4 k. e; P2 q& V

  5. ( a- a! \8 w2 A7 m: V9 `5 }% a  ?. }
  6. <script>
    & u1 V  ~. Y- w% ?( v
  7. // 创建根实例
    0 U2 s1 @* F+ X1 A0 Q
  8. new Vue({$ ^7 a" \8 G. F4 n5 B5 O8 M
  9.   el: '#app',
    , C. O. O( R" n. o7 [# A* \: ?6 Z7 ^
  10.   directives: {
    ( e& o1 G' |: O; q! Z4 H5 s2 D
  11.     // 注册一个局部的自定义指令 v-focus
    / q9 ~; k+ T" p6 l9 N
  12.     focus: {
    4 Z' F" p8 v+ p! H4 @7 [1 @7 i, K- `
  13.       // 指令的定义8 x& U4 q0 ~  m/ H! U1 F
  14.       inserted: function (el) {
    % p+ e+ V* ?( h: c
  15.         // 聚焦元素3 Y9 j6 k0 n1 Z9 c5 T( f) k! @+ B
  16.         el.focus()
    % r4 Y, Y2 _* D  K8 B$ b
  17.       }# J3 S$ P5 G; \( t
  18.     }
    - x- T6 L6 r& W  M* o% V% }
  19.   }& P0 w4 y6 Z: {# `) \' h
  20. })( s! Y9 j  n  B3 S
  21. </script>
复制代码
钩子钩子函数
指令定义函数提供了几个钩子函数(可选):
  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  • unbind: 只调用一次, 指令与元素解绑时调用。

    / T  A3 d) R5 Y! G
钩子函数参数
钩子函数的参数有:
  • el: 指令所绑定的元素,可以用来直接操作 DOM 。
  • binding: 一个对象,包含以下属性:
    • name: 指令名,不包括 v- 前缀。
    • value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
    • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
    • arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
    • modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。; r* B! h+ x6 ?3 z* h3 f9 h1 T- E% z
  • vnode: Vue 编译生成的虚拟节点。
  • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
    / W1 v- R8 N0 f0 |" o
以下实例演示了这些参数的使用:
实例
: o& Y9 V" _8 H6 u0 S' `
8 ~8 }4 {0 |) u- o3 Y8 T* L
  1. <div id="app"  v-runoob:hello.a.b="message">
    , S9 N# p! @8 a$ E/ c- d
  2. </div>
    8 h' L/ _+ \& T3 @" J/ Q5 o

  3.   ~+ t7 n$ r* v; ]
  4. <script>
    & H( c) J. ?5 n& J/ f
  5. Vue.directive('runoob', {3 Q! J+ X4 D, e
  6.   bind: function (el, binding, vnode) {" N. E. i7 `! ]% P4 M
  7.     var s = JSON.stringify
    ; O" q5 h* X  T' c
  8.     el.innerHTML =
    ' N4 D0 r1 R# b2 j3 g/ N% A% j8 _
  9.       'name: '       + s(binding.name) + '<br>' +
    / W# T* |  }# @. h7 q- n, f  a
  10.       'value: '      + s(binding.value) + '<br>' +3 b) v* N0 m8 ?3 h& |1 S
  11.       'expression: ' + s(binding.expression) + '<br>' +
    7 F  ]7 z- |. N" E
  12.       'argument: '   + s(binding.arg) + '<br>' +
    * v+ b/ L0 `( _
  13.       'modifiers: '  + s(binding.modifiers) + '<br>' +6 w1 T4 j, W2 q8 e% T6 R" Z
  14.       'vnode keys: ' + Object.keys(vnode).join(', ')
    , T7 `0 C7 T$ ?: N/ f
  15.   }, ?/ l' \' A9 q, n" k. M; w
  16. })
    ) G# n; W5 ^& K; z# G" E2 ~
  17. new Vue({! D6 `  C9 _( B! u0 q
  18.   el: '#app',
    9 V+ h2 U4 R  l( O2 X: H
  19.   data: {
    1 `2 ^, L2 K& y3 _. a) ?8 v
  20.     message: '菜鸟教程!'2 ^9 z6 U0 }) R4 z6 |+ h) g
  21.   }
    1 U" [. N* D, h) _  E  ^# J2 e5 Z
  22. })
    7 U* k7 `0 b) K! Z
  23. </script>
复制代码
有时候我们不需要其他钩子函数,我们可以简写函数,如下格式:
- v5 \( S3 V$ p& f' X; V
  1. Vue.directive('runoob', function (el, binding) {8 M  a/ _- a+ m; Y
  2.   // 设置指令的背景颜色
    " {" M0 i+ H0 h$ r, l
  3.   el.style.backgroundColor = binding.value.color( N8 e$ K# n+ v
  4. })
复制代码

, x' E  }" l1 a. [
! L! M# m) N. p' ^+ u6 N, V' Q2 p
指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:
实例
0 a/ X% u" I: U7 i  I! e
* p* t* R, I8 L( J; U% h/ T, x3 @  h
  1. <div id="app">  m3 j" ?4 w, f. D: C+ T
  2.     <div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div>
    4 J  d: A9 N2 B: D- q+ Z% \. ]4 H
  3. </div>& ^( g6 q7 \4 Q. ^
  4. - b& a% E0 Q. ]' y' u: C
  5. <script>7 Q' e; V0 a6 W6 d5 h4 q. l- O' _3 z; e8 ]
  6. Vue.directive('runoob', function (el, binding) {: [1 F1 |! `+ p4 `1 N+ \. K# J
  7.     // 简写方式设置文本及背景颜色( S  O  z+ D1 p. S& l5 I3 R
  8.     el.innerHTML = binding.value.text
    0 @. E/ }4 T, b6 B
  9.     el.style.backgroundColor = binding.value.color
    8 J5 j: y2 q5 A3 ~8 E; @
  10. })3 u% f- D. L) G" |: z0 [
  11. new Vue({4 z* {4 j( ?& y9 U" _, s3 ^
  12.   el: '#app'9 Q" f& h( D3 M+ H* @: y
  13. })* ?0 G) C2 t. V! ?5 [
  14. </script>
复制代码
: R0 b; S4 y* P0 X; q" |. H9 x2 N

& x* f# ?/ f' b' r4 O
2 a! S" e( x# h, \4 n& A: l9 ~/ a$ v8 R
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2026-8-4 14:22 , Processed in 0.051209 second(s), 22 queries .

Copyright © 2001-2026 Powered by cncml! X3.2. Theme By cncml!