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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-7-4 11:36:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

7 G8 f7 X3 C7 b: r
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。
下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时,元素获得焦点:
实例
4 b  X7 J9 m# a, H+ N& H6 S6 R, n
  1. <div id="app">! }' ~' |9 {# E9 [2 ^4 y
  2.     <p>页面载入时,input 元素自动获取焦点:</p># f- I7 {- I- k& G7 k& U
  3.     <input v-focus>; Q' I! @& G$ Q' F7 |7 |9 n
  4. </div>2 _0 t; H" N; q/ N% l! o) y
  5. 3 _: `: q  n, }5 G" G8 n$ ~3 c
  6. <script>( v5 e3 d+ M( E- g0 T) z
  7. // 注册一个全局自定义指令 v-focus& Q; d) \; h1 h, @: S- B: D
  8. Vue.directive('focus', {; x" S8 ]- S' |6 Y- `
  9.   // 当绑定元素插入到 DOM 中。
    9 b( j8 d$ g- W' a
  10.   inserted: function (el) {! }8 ]6 u  A3 @, i& N6 D2 ]4 `
  11.     // 聚焦元素
    3 V) a4 ^( A' A" B1 X8 g
  12.     el.focus()" O  C* p" {; p. u9 g
  13.   }  K6 o7 M7 u. u$ K/ G; a4 D4 X0 S" O
  14. })
    6 |4 h" N2 I; r
  15. // 创建根实例6 o4 G9 d% l9 x  B  ~/ Z/ @' E
  16. new Vue({
    ( i4 n( D  m! o! }2 ]/ A
  17.   el: '#app'2 R: X3 ~' M# ^5 B) [3 X. q0 r
  18. }), \# ^/ }- t! u! D3 ?" s9 k9 a
  19. </script>
复制代码
我们也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:
实例3 l0 b. l4 F; t5 t, F9 H
9 {; R1 k# c9 n2 q: G1 B* P: g, n
  1. <div id="app">+ q- b/ l* ?8 I$ \3 u7 C+ Y9 V
  2.   <p>页面载入时,input 元素自动获取焦点:</p>% D3 J- n4 ]4 B0 d/ [
  3.   <input v-focus>" t! V% Q6 f2 ?' X- N
  4. </div>; g/ ~8 ]# e1 V# J) k) M  F' o
  5. % b  v9 X1 ]" O. `; F/ G6 ]
  6. <script>4 ^7 E# \3 ^4 a1 s- C$ O1 J/ ?4 C
  7. // 创建根实例  Q7 I* Z8 |+ y! r1 U3 x' N9 V0 a
  8. new Vue({/ j8 n9 S* L  i" |0 D
  9.   el: '#app',2 L9 D/ _3 i, w* F" e- j9 p, x- C
  10.   directives: {4 A/ F  ~7 V+ x
  11.     // 注册一个局部的自定义指令 v-focus/ g' K. }0 y! f2 Y% f
  12.     focus: {
      k6 M; B4 j8 n  r& z9 C* j
  13.       // 指令的定义
    3 }5 @- p0 F! l- a7 n1 _
  14.       inserted: function (el) {
    ; L" f" p7 U" i! g3 h
  15.         // 聚焦元素
    % ~8 K2 g$ D, k3 C/ L. j
  16.         el.focus()
    ! U  ~4 F3 P3 [( s/ S1 C
  17.       }( g6 e' k4 @9 O9 t6 x, x
  18.     }( v6 A+ C5 }3 _1 E4 e
  19.   }
    ( g4 u7 n" a$ k
  20. })
    $ ]) [% A1 r* W; g6 y- F
  21. </script>
复制代码
钩子钩子函数
指令定义函数提供了几个钩子函数(可选):
  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  • unbind: 只调用一次, 指令与元素解绑时调用。

    2 d, b  M, z1 _
钩子函数参数
钩子函数的参数有:
  • 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 }。
      4 g8 }; ~! F" Q# O! P$ d; i
  • vnode: Vue 编译生成的虚拟节点。
  • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
    ) q  E  d8 M9 C2 A9 A, Y
以下实例演示了这些参数的使用:
实例/ L* n* ^! R& |3 b1 l" a

' O4 |  y/ I+ }0 F
  1. <div id="app"  v-runoob:hello.a.b="message">4 c, h  w" _2 }$ z
  2. </div>2 }& S/ h# }% e" j

  3. 0 _9 L$ N5 ^3 j
  4. <script>
    - G6 {0 i, W+ G6 Q
  5. Vue.directive('runoob', {. n3 w, w4 f/ m% p. A3 W5 z
  6.   bind: function (el, binding, vnode) {& C2 t) g- t9 P. }: O
  7.     var s = JSON.stringify
    % f1 L/ b; m* @/ `) g/ R
  8.     el.innerHTML =
    + C# i7 c- y: A. ~0 d: w6 L1 S
  9.       'name: '       + s(binding.name) + '<br>' +
    3 v9 x! R' L4 c4 T- G. N+ D# n
  10.       'value: '      + s(binding.value) + '<br>' +
    3 l7 P! i" ?, C/ {1 b5 F4 a  F* C; Q
  11.       'expression: ' + s(binding.expression) + '<br>' +  `9 i8 Y) W' i& I6 f8 V+ b, r
  12.       'argument: '   + s(binding.arg) + '<br>' +
    " _/ L- s4 L* l  w3 u5 F; Z% t, `
  13.       'modifiers: '  + s(binding.modifiers) + '<br>' +" w9 B5 P5 R1 x- T- \: y/ N
  14.       'vnode keys: ' + Object.keys(vnode).join(', ')
    . W: {- T+ W0 _# q8 d
  15.   }. s  q5 U+ t/ a( p" o9 _& c
  16. })
    : ]+ k+ o# p/ i6 |
  17. new Vue({
    * _  z# O- c: _2 P
  18.   el: '#app',
      d  ^5 f; }0 C# R0 d$ u2 _2 K/ }
  19.   data: {
    6 J( W4 H( `9 _6 w0 K
  20.     message: '菜鸟教程!'( K1 C3 F% w, O( Y( `$ g. B
  21.   }
    0 K2 S# ]0 Q& d# D& n; F9 v' X" g
  22. }). f$ j5 K" E! L4 u/ v
  23. </script>
复制代码
有时候我们不需要其他钩子函数,我们可以简写函数,如下格式:
7 A" y) t6 k# n8 c
  1. Vue.directive('runoob', function (el, binding) {
    1 P  p8 T0 D4 w( m6 {
  2.   // 设置指令的背景颜色
    % z9 P! p, k* c% `
  3.   el.style.backgroundColor = binding.value.color- K: K) X7 h8 Q: T9 i5 m: _" l
  4. })
复制代码
& E. {/ L. h6 I% W7 F+ Z

/ g9 U4 N% M! P6 j) f! r
指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:
实例
& k1 F& D/ [8 c) _
8 }2 d0 N! |4 q1 E: \  s
  1. <div id="app">
    : O# {- J% r4 J7 ^, d
  2.     <div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div>
    ' R3 ?( N' i" W5 ?/ N
  3. </div>
    ( n* T# S- A6 F  `* \. Z0 J5 j
  4. ; Z1 r5 N! b& u3 e
  5. <script>
    9 H( s2 F, p$ I  A
  6. Vue.directive('runoob', function (el, binding) {0 |& Y; E7 |5 h6 z1 s2 H
  7.     // 简写方式设置文本及背景颜色* H+ X) P, W' v8 s8 b; u6 a
  8.     el.innerHTML = binding.value.text9 R! T7 ]3 F. f6 x& G, q
  9.     el.style.backgroundColor = binding.value.color! M4 G2 p" s9 V# l; f
  10. })
      Q1 O1 F- |; B2 a; D
  11. new Vue({
    ! G+ Z3 F" L9 \- u/ ^  Y- z
  12.   el: '#app'; z/ U$ }' `7 p% F1 E
  13. }). U% g7 u0 ]( e# N- B9 [% p5 }
  14. </script>
复制代码

- @7 l1 O: z: m! T1 o$ n3 w( p# s# V# R9 M; F& K) k
4 W* ^+ V; _% S$ U+ P& H
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2026-1-30 14:28 , Processed in 0.066566 second(s), 20 queries .

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