- 操作底层DOM
代码复用和抽象的主要形式是组件,有时候需要自定义指令来操作底层DOM。
让我们看一个例子:1
2// HTML
<input v-focus/>
1 | // 在组件的JS代码中自定义指令focus |
以上代码的作用是进入页面的时候输入框会自动获取焦点,即处于输入状态,注意,在使用的时候,Vue会自动在我们的指令前面加上前缀v-
,所以使用是指令表示为v-focus
。
钩子函数与钩子参数
与组件的操作过程类似,钩子用于处理底层DOM,所以天生携带组件的生命体征,即我们也会像操作组件一样来处理我们的指令,找到对应的时机:包含绑定指令,插入元素,数据更新,组件更新和解绑指令,这些表现为函数形式,操作我们的数据,表现为在相应的函数里传递和操作参数。
具体函数如下:bind
:顾名思义,绑定我们定义的指令到元素上,而且整个生命周期中只会绑定一次,我们可以在这里做一些一次性的创建工作。inserted
:当绑定元素已经插入到它的父节点的时候调用(它只保证父节点存在,不一定在文档中)。update
:包含组队的VNode被更新的时候调用,但是可能会在子组件更新之前调用。指令的值可能改变也可能不改变。componentUpdated
:包含组件的VNode和VNodes的子组件更新后调用。unbind
:仅调用一次,和bind
相对,自定义指令从元素解绑时调用。
有了这些函数,我们就可以在对应的阶段执行一些处理DOM的操作。要操作DOM我们还需要这些函数传递的参数,我们通过一个例子来认识这些参数:
1 | // HTML |
1 | // JS |
打印结果:
name:”demo”
value:”hello!”
expression:”message”
argument:”foo”
modifiers:{“a”:true,”b”:true}
vnode keys:tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholder
结合上面的例子,我们来认识这些参数:el
:指令绑定的元素,可以用它来直接操作DOMvnode
:通过Vue的编译器产生的虚拟DOM节点oldVnode
:之前的虚拟节点,仅在update
和componentUpdated
函数可用
binding
:一个对象,包含如下属性:
name
:指令名称,没有-v前缀,如”demo”value
: 传递给指令的值,如”hello!”expression
:绑定的表达式,用字符串表示,如上:”message”arg
:传递给指令的参数,如”foo”modifiers
:一个包含修饰符的对象,如上的修饰符对象是{“a”:true,”b”:true}oldValue
:之前的值,仅在update
和componentUpdated
函数可用,无论值是否改变它都是可用的。
注意
:
除了el
,其他的要素不要修改,作为只读属性。
动态指令参数
1 | // HTML |
1 | // JS |
这样我们就可以根据direction
的值来做页面的动态调整了。
对象字面值
可以使用JavaScript的字符串给指令传递对象字面值,例如:1
2// HTML
<div v-demo="{color: 'white', text: 'hello'}"></div>
1 | // JS |
参考:
自定义指令