• 自定义 Directive
    • 例子
    • 自定义Directive的命名方法
    • 钩子方法 (Hook Functions)
    • 自定义Directive可以接收到的参数
    • 实战经验

    自定义 Directive

    Vuejs除了自身提供的 v-if, v-model 等标准的Directive之外, 还提供了非常强大的自定义功能。 使用这个功能,我们就可以定义属于我们自己的Directive.

    例子

    我们看下面例子:

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. 下面是使用了自定义的Directive的input, 可以自动聚焦( 调用 focus() 方法) : <br/>
    8. <br/>
    9. <input v-myinput/>
    10. </div>
    11. <script>
    12. var app = new Vue({
    13. el: '#app',
    14. directives: {
    15. "myinput": {
    16. inserted: function(element){
    17. element.focus()
    18. }
    19. }
    20. }
    21. })
    22. </script>
    23. </body>
    24. </html>

    上面的代码中, 先是在 Vue中,定义了一个 directives 代码段:

    1. directives: {
    2. myinput: {
    3. inserted: function(element){
    4. element.focus()
    5. }
    6. }
    7. }
    • myinput 就是自定义Directive的名字。 使用的时候就是 v-myinput.
    • inserted: 这是一个定义好的方法(钩子方法),表示在页面被Vuejs渲染的过程中, 在该DOM被 “insert”(插入)到页面中的时候,被触发。触发的内容是 element.focus()

    用浏览器打开后,可以看到<input/> 标签是会自动聚焦的。 这个时候用户就可以直接输入内容了。 如下图所示:

    custom directive例子

    如果在 “webpack” 等可以修改 “全局Vue实例”的时候,也可以使用这样的方法:

    1. Vue.directive('myinput', {
    2. inserted: function (elemenet) {
    3. element.focus()
    4. }
    5. })

    自定义Directive的命名方法

    如果您希望把 v-myinput的调用,写成 v-my-input, 那么在定义的时候,就应该:

    1. directives: {
    2. // 注意下面的写法. 使用双引号括起来
    3. "my-input": {
    4. inserted: function(element){
    5. element.focus()
    6. }
    7. }
    8. }

    那么我们就可以在View中这样使用了:

    1. <input v-my-input />

    钩子方法 (Hook Functions)

    我们在上面的例子中,知道了 inserted 是一个钩子方法。 下面是一个完整的列表:

    • bind 只运行一次。 当该元素首次被渲染的时候。(绑定到页面的时候)
    • inserted 该元素被插入到父节点的时候(也可以认为是该元素被Vue渲染的时候)
    • update 该元素被更新的时候。
    • componentUpdated 包含的component被更新的时候。
    • unbind 只会运行一次。 当该元素被Vuejs从页面解除绑定的时候。

    自定义Directive可以接收到的参数

    Vuejs 为自定义Directive 实现了强大了功能, 可以接收很多个参数。 下面是个例子:

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. 下面是一个非常全面的自定义Directive的例子: <br/>
    8. <br/>
    9. <input v-my-input:foo.click="say_hi" />
    10. </div>
    11. <script>
    12. var a
    13. var app = new Vue({
    14. el: '#app',
    15. data: {
    16. say_hi: '你好啊,我是个value'
    17. },
    18. directives: {
    19. "my-input": {
    20. inserted: function(element, binding, vnode){
    21. element.focus()
    22. console.info("binding.name: " + binding.name)
    23. console.info("binding.value: " + binding.value)
    24. console.info("binding.expression: " + binding.expression)
    25. console.info("binding.argument: " + binding.arg)
    26. console.info("binding.modifiers: ")
    27. console.info(binding.modifiers)
    28. console.info("vnode keys:")
    29. console.info(vnode)
    30. }
    31. }
    32. }
    33. })
    34. </script>
    35. </body>
    36. </html>

    先看运行结果:

    custom directive arguments

    在上图中,可以看到, 自定义Directive 在声明的时候,接收了3个参数: function(element, binding, vnode)

    通过这三个参数,就可以看到很多对应的内容,包括 binding.name, binding.value, binding.expression. 他们的含义都是字面的意思。

    借助这些内容,我们可以实现我们自己想要的Directive.

    实战经验

    1.优先考虑使用Component.

    考虑到维护成本。 它的作用跟 JSP 中的自定义标签是一样的。 与其使用 Directive, 不如使用 Component.

    2.如果一定要用,把它实现的尽量简单。

    如果接手的新人水平不如你,那他很可能读不懂这块代码。