Contents
  1. 1. 一、vue中自定义指令
    1. 1.0.1. 1. 什么是自定义指令?
    2. 1.0.2. 2. 什么时候需要自定义指令?
    3. 1.0.3. 3. 如何注册和使用自定义指令?
      1. 1.0.3.0.0.1. 1. 注册
      2. 1.0.3.0.0.2. 2. 使用
  • 2. 二、钩子函数
    1. 2.0.1. 1. 简介钩子函数
      1. 2.0.1.0.0.1. 注意:
  • 2.0.2. 2. 函数简写
  • 2.0.3. 模拟v-bind动态绑定属性值
  • 2.0.4. 模拟v-bind绑定class
  • 一、vue中自定义指令

    1. 什么是自定义指令?

    除了使用 Vue 提供的内置指令之外,我们可以自定义一些自己的指令,来实现业务操作。

    2. 什么时候需要自定义指令?

    当你需要不可避免的操作 DOM 的时候,使用自定义指令来解决

    3. 如何注册和使用自定义指令?

    1. 注册
    • 全局注册,在任何组件中都可以使用全局注册自定义指令
    • 局部注册,只能在当前组件使用该指令

    如果需要在多个不同的组件中使用该指令,则把它定义为全局的
    非通用的,不需要多次使用的指令我们定义到局部

    2. 使用

    例:注册一个自定义指令focus

    1
    2
    3
    4
    5
    6
    7
    8
    // 注册一个全局自定义指令 `v-focus`
    Vue.directive('focus', {
    // 当被绑定的元素插入到 DOM 中时……
    inserted: function (el) {
    // 聚焦元素
    el.focus()
    }
    })

    注册一个全局自定义指令 v-focus
    使用 声明Vue.directive()
    参一是指令的名字

    • 指令的名字随便起,但是在使用的时候务必加上 v- 前缀,所以我们在其名字的时候就不要加 v- 前缀
    • 如果是驼峰命名法的名称,则在使用的时候需要把驼峰转为小写使用 - 连接起来(例:myFocus 为 v-my-focus)

    参二是钩子函数
    下面我们将简单介绍钩子函数

    二、钩子函数

    1. 简介钩子函数

    vue中提供了5个钩子函数

    • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。(bind 中拿不到父元素)
    • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。如果你需要操作作用指令的父元素,则最起码写到这个 inserted 中
    • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    • unbind:只调用一次,指令与元素解绑时调用。

    每个钩子函数都可以接收两个参数:

    • el 作用该指令的 DOM 对象
    • binding 一个对象,可以获取指令的值等信息
    注意:
    1. bind 和 inserted 的相同之处是一上来都执行一次,以后再也不会执行,异同之处在于,bind 拿不到父元素,inserted 可以拿到父元素
    2. update 和 componentUpdated 只有在指令的绑定的值发生更新的时候才会触发调用
    3. update 和 componentUpdated 的区别是:
      update 中获取的是更新的之前的指令所在的 DOM 内容
      componentUpdated 获取的是更新之后的最新 DOM 内容
      update 拿到的是数据改变视图之前的视图内容
      componentUpdated 拿到的是数据改变视图之后的视图内容
      也就是说如果你需要获取数据改变视图之前的内容,则把代码写到 update 中
      如果需要获取数据改变视图之后的内容,则把代码写到 componentUpdated 里面

    例: 模拟v-show实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <div id="app">
    <!-- <input type="text" v-focus> -->
    <div class="box" v-my-show="seen">{{ seen }}</div>
    </div>
    Vue.directive('my-show', {
    bind (el, binding) {
    inserted (el, binding) {
    console.log('my-show inserted')
    if (binding.value) {
    el.style.display = 'block'
    } else {
    el.style.display = 'none'
    }
    },
    update (el, binding) {
    // console.log('my-show update', el, binding)
    console.log('my-show update', el.innerHTML)
    if (binding.value) {
    el.style.display = 'block'
    } else {
    el.style.display = 'none'
    }
    },
    componentUpdated (el, binding) {
    console.log('my-show componentUpdated', el.innerHTML)
    },
    unbind () {
    console.log('my-show unbind')
    }
    })

    2. 函数简写

    在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:

    1
    2
    3
    Vue.directive('color-swatch', function (el, binding) {
    el.style.backgroundColor = binding.value
    })

    我只关心 bind 和 inserted,所以可以这样简写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Vue.directive('my-show', function (el, binding) {
    // console.log('my-show update', el, binding)
    // console.log('my-show update', el.innerHTML)
    if (binding.value) {
    el.style.display = 'block'
    } else {
    el.style.display = 'none'
    }
    })


    模拟v-bind动态绑定属性值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <body>
    <div id="app">
    <h1 v-my-bind:title="message" v-my-bind:foo="message">{{ message }}</h1>
    <input type="text" v-model="message">
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
    // v-bind 作用
    // 动态绑定属性值
    // Vue.directive('my-bind', {
    // bind (el, binding) {
    // console.log(binding.value)
    // el.setAttribute(binding.arg, binding.value)
    // },
    // update (el, binding) {
    // el.setAttribute(binding.arg, binding.value)
    // }
    // })

    // 很多时候,我们都会在 bind 和 update 中执行相同的代码
    // 所我们可以使用简写的方式,.直接给一个函数,该函数会被作为 bind 和 update 的时候执行的函数
    Vue.directive('my-bind', function (el, binding) {
    el.setAttribute(binding.arg, binding.value)
    })


    const app = new Vue({
    data: {
    message: 'Hello Vue.js!'
    },
    methods: {}
    }).$mount('#app')
    </script>
    </body>

    模拟v-bind绑定class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    <style>
    .box {
    background-color: pink;
    }

    .box2 {
    color: red;
    }
    </style>
    </head>
    <body>
    <div id="app">
    <h1 v-my-bind:title="123">{{ message }}</h1>
    <input type="text" v-model="message">
    <input type="checkbox" v-model="toggleBox"> toggleBox
    <input type="checkbox" v-model="toggleBox2"> toggleBox2
    <div v-my-bind:class="{box: toggleBox, box2: toggleBox2}">
    hello vue
    </div>
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script>
    // v-bind:class = "{}"
    // v-bind:class = "xxx"
    Vue.directive('my-bind', function (el, binding) {
    console.log('所在模板更新了')
    if (binding.arg === 'class') {
    for (let key in binding.value) {
    if (binding.value[key]) {
    // 作用类名
    el.classList.add(key)
    } else {
    el.classList.remove(key)
    }
    }
    } else {
    el.setAttribute(binding.arg, binding.value)
    }
    })
    const app = new Vue({
    data: {
    message: 'Hello Vue.js!',
    toggleBox: true,
    toggleBox2: true
    },
    methods: {}
    }).$mount('#app')
    </script>
    </body>
    Contents
    1. 1. 一、vue中自定义指令
      1. 1.0.1. 1. 什么是自定义指令?
      2. 1.0.2. 2. 什么时候需要自定义指令?
      3. 1.0.3. 3. 如何注册和使用自定义指令?
        1. 1.0.3.0.0.1. 1. 注册
        2. 1.0.3.0.0.2. 2. 使用
  • 2. 二、钩子函数
    1. 2.0.1. 1. 简介钩子函数
      1. 2.0.1.0.0.1. 注意:
  • 2.0.2. 2. 函数简写
  • 2.0.3. 模拟v-bind动态绑定属性值
  • 2.0.4. 模拟v-bind绑定class