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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-7-4 11:36:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
% h4 ~7 e+ s- h4 F; d' t
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。
下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时,元素获得焦点:
实例
* [& |5 h; _0 a( A; U, O4 D
3 }* y2 L' q  _2 N- H% \
  1. <div id="app">/ ~4 ~* I  X$ E) P- }$ x1 n5 e
  2.     <p>页面载入时,input 元素自动获取焦点:</p>& M% }% B& ~6 E& }- e8 j6 y
  3.     <input v-focus>
    - n: F7 Y6 q) d3 S
  4. </div>& C5 a  y' i4 W5 o

  5. 3 u* g  E/ j7 h5 ^4 S
  6. <script>
    4 r# t+ w+ E# g  `1 q4 X3 H5 p1 C
  7. // 注册一个全局自定义指令 v-focus
    6 M+ H0 ~3 H9 }0 |
  8. Vue.directive('focus', {
    1 @) h3 |0 u2 V. M8 @0 S
  9.   // 当绑定元素插入到 DOM 中。
    5 C, W( f! [* a
  10.   inserted: function (el) {
      t# m! m' S- Z2 X, V- q
  11.     // 聚焦元素
    ' K+ r; h# ?/ W) u! L) _2 A9 Q. c
  12.     el.focus()7 J* T0 u2 }8 _$ X
  13.   }- W* E) a- X0 f
  14. })
    3 L( L6 B3 V, o2 L- e; ^3 Y
  15. // 创建根实例
    * w# u' {$ Y0 k6 z0 t2 T# J
  16. new Vue({
    / P5 U6 |6 U9 P) T/ |# }5 I4 h1 \
  17.   el: '#app'
    - W; V# ?2 l! o8 V- ^. H
  18. })
    6 j" t- N. Q0 o0 n( i
  19. </script>
复制代码
我们也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:
实例
- D2 e. ?' `% {0 y9 P/ R9 F: ?: a0 X( ^+ k+ }
  1. <div id="app">
    2 ?0 u3 }; I$ \2 R2 i& p- d
  2.   <p>页面载入时,input 元素自动获取焦点:</p>+ g' X  a# B. Y3 c0 n
  3.   <input v-focus>
    + F  U6 L. |; v) @
  4. </div>5 t) j! M9 p8 N- h& ]4 D
  5. 4 b& k) H3 W! i) P& K5 f- T. l: I
  6. <script>
    ! p  w7 P# i/ N& z9 |9 D! S8 w$ k
  7. // 创建根实例4 ?6 B8 R+ H+ M1 B! G" A
  8. new Vue({+ l) H6 P4 }: ]; `( v; n: t% a- U5 W
  9.   el: '#app',
    0 V0 J/ j5 \$ v6 ]+ D
  10.   directives: {" X4 D) d5 F% h$ }
  11.     // 注册一个局部的自定义指令 v-focus' I# o$ l* `# d9 {2 k% d& X
  12.     focus: {
    2 F! Y0 J& O& m# l
  13.       // 指令的定义) P% ~) g, _5 n' p3 L
  14.       inserted: function (el) {7 y  p0 Q9 l* F% ]
  15.         // 聚焦元素
    ( N9 u2 ^+ q! ^$ o; W! \6 G
  16.         el.focus()
    ! H6 b4 c: ~( @8 R/ B# k, r. [, v
  17.       }
    ! y  Z, ]! y' W
  18.     }
    & z$ H4 {- v8 J/ E3 ~
  19.   }. ~- `/ B/ V2 _* U+ O# ]! J( }
  20. })
    7 \* }5 T: x' A! j+ A# J
  21. </script>
复制代码
钩子钩子函数
指令定义函数提供了几个钩子函数(可选):
  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  • unbind: 只调用一次, 指令与元素解绑时调用。
    " ?5 R1 H, w$ D6 L7 U/ Z
钩子函数参数
钩子函数的参数有:
  • 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 }。" I. P  Y4 o$ g
  • vnode: Vue 编译生成的虚拟节点。
  • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。: K% s" }; g6 A  }: j
以下实例演示了这些参数的使用:
实例) K0 ~( _' R+ {/ s8 o

- c- y) o) Z0 F1 a2 U' U( J
  1. <div id="app"  v-runoob:hello.a.b="message">. _: O2 R; L$ M! ~) M- Y2 U! ~
  2. </div>- j. R/ b7 |0 K+ n/ z" W: O/ }

  3. 1 {9 u# z+ I# ]2 P! ~  T" g
  4. <script>" P  B4 W/ F$ A4 J6 t& M  i
  5. Vue.directive('runoob', {% T5 q1 \; S1 b  S% E1 g/ K. i$ j
  6.   bind: function (el, binding, vnode) {6 z+ x" r* @7 |; D, \& G  E
  7.     var s = JSON.stringify
    ) k* }2 Y. q: C4 m1 G
  8.     el.innerHTML =; g) C( f- J. ?+ q
  9.       'name: '       + s(binding.name) + '<br>' +
    - @& J: C) m+ U3 N( B- X
  10.       'value: '      + s(binding.value) + '<br>' +
    ' |/ r! ?& o! ?+ a5 O( |% G
  11.       'expression: ' + s(binding.expression) + '<br>' +
    , k) p: B5 y$ J1 b6 V! ^
  12.       'argument: '   + s(binding.arg) + '<br>' +
    4 F: ^. V. m. n+ b3 @
  13.       'modifiers: '  + s(binding.modifiers) + '<br>' +6 a, i7 |7 p# R$ H0 U2 [9 M; z
  14.       'vnode keys: ' + Object.keys(vnode).join(', ')
    3 c/ B4 z4 v2 s2 \( l$ l, Q1 H
  15.   }# a5 J9 F8 o7 m3 Q2 n/ @6 l
  16. })
    ( d. d  j7 F, S( O  G
  17. new Vue({# `# w/ a% J9 h1 v0 x
  18.   el: '#app',
    ! F3 u4 m6 @' `
  19.   data: {
    , @2 f" _! p3 \- ~$ f
  20.     message: '菜鸟教程!'
    " ?+ B2 B; L1 ^1 N; |$ ]+ a6 S
  21.   }
    * y5 @' R4 O2 R8 m0 x
  22. })7 P1 t, s! b. b
  23. </script>
复制代码
有时候我们不需要其他钩子函数,我们可以简写函数,如下格式:& c' @% V, p4 ?) Y9 N/ }7 `
  1. Vue.directive('runoob', function (el, binding) {2 @" B# @9 b% a9 p/ Y: I4 P
  2.   // 设置指令的背景颜色/ K6 X; ?7 A5 Q
  3.   el.style.backgroundColor = binding.value.color
    % M  R9 g7 `$ e0 Y* i) A- x# B
  4. })
复制代码

' \+ |( w/ N8 d; }6 R6 Z2 K# Z& |$ K: A9 G  w" @
指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:
实例
! Z0 i5 o0 P% V# x. Y' U
0 w* Y' a' y5 v
  1. <div id="app">& p+ {/ N" G: J0 B
  2.     <div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div>
      t0 I& u) `- q) Z5 ?& k5 _
  3. </div>
    - ^) B0 l9 K# G1 C7 c6 ?

  4. & u; G8 j; x) c9 s; r6 r  j  K
  5. <script>. `% t* c8 V1 ~- N) j$ T3 o0 P8 H; e+ k
  6. Vue.directive('runoob', function (el, binding) {+ O: l. m8 X  Q% y  \
  7.     // 简写方式设置文本及背景颜色
    ' ~! H' m" Z, j3 F5 o! W4 j
  8.     el.innerHTML = binding.value.text0 y1 N! R, X: k% a* i
  9.     el.style.backgroundColor = binding.value.color
    % |+ d9 E* y6 F3 W5 B0 c
  10. })) I5 H% a: d' T* Y
  11. new Vue({
    + Q7 {$ J4 ^! O- Y: m! O; X
  12.   el: '#app'3 t$ w. P6 @6 O1 j2 k/ H9 j
  13. })
      U8 P2 g: {/ E, C& y" O+ E& k6 m
  14. </script>
复制代码

  ]9 O: {/ a7 F! f3 ?& o* x
% M/ Z; F8 D; _2 Y3 D1 ~
8 k( G! W9 G) U$ e6 S0 x* v
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2026-3-16 18:48 , Processed in 0.063593 second(s), 19 queries .

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