MST

星途 面试题库

面试题:Vue自定义指令中钩子函数的参数有哪些含义

在Vue中创建自定义指令时,钩子函数(如bind、inserted、update等)会接收一些参数。请详细说明这些参数分别代表什么含义,以及在实际应用场景中如何利用这些参数实现特定的功能。
43.1万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试
  1. 参数说明
    • el
      • 含义:指令所绑定的元素,可以用来直接操作DOM。
      • 示例场景:在bind钩子中,给绑定指令的按钮添加点击事件,如:
<template>
  <button v - my - directive>点击我</button>
</template>

<script>
export default {
  directives: {
    'my - directive': {
       bind(el) {
          el.addEventListener('click', () => {
            console.log('按钮被点击了');
          });
        }
      }
  }
};
</script>
  • binding
    • 含义:一个对象,包含指令的各种信息,如name(指令名)、value(指令绑定的值)、oldValue(指令绑定的上一个值,仅在updatecomponentUpdated钩子中有定义)、expression(指令的绑定表达式)、arg(传给指令的参数)、modifiers(一个包含修饰符的对象)。
    • 示例场景:通过binding.value来设置元素的文本内容,假设指令v - set - text绑定了一个字符串值:
<template>
  <div v - set - text="textValue"></div>
</template>

<script>
export default {
  data() {
    return {
      textValue: '这是设置的文本'
    };
  },
  directives: {
    'set - text': {
       bind(el, binding) {
          el.textContent = binding.value;
        }
      }
  }
};
</script>
  • vnode
    • 含义:Vue编译生成的虚拟节点。它是对真实DOM的一种抽象描述,包含了元素的标签名、属性、子节点等信息。
    • 示例场景:在自定义指令中获取虚拟节点的一些属性来做特定操作,例如获取组件的一些自定义属性。假设组件有一个自定义属性data - info
<template>
  <div v - my - directive>
    <my - component data - info="自定义信息"></my - component>
  </div>
</template>

<script>
import MyComponent from './MyComponent.vue';
export default {
  components: {
    MyComponent
  },
  directives: {
    'my - directive': {
       bind(el, binding, vnode) {
          const componentVnode = vnode.children[0];
          if (componentVnode && componentVnode.data.attrs['data - info']) {
            console.log('组件的自定义属性data - info:', componentVnode.data.attrs['data - info']);
          }
        }
      }
  }
};
</script>
  • oldVnode
    • 含义:上一个虚拟节点,仅在updatecomponentUpdated钩子中可用。用于比较前后虚拟节点的变化。
    • 示例场景:当一个元素的v - my - directive指令绑定的值发生变化时,通过比较oldVnodevnode中指令绑定值的变化来做动画。假设指令绑定的是一个数字,值变化时元素的字体大小改变:
<template>
  <div v - my - directive="numberValue">{{numberValue}}</div>
  <button @click="numberValue++">增加数字</button>
</template>

<script>
export default {
  data() {
    return {
      numberValue: 1
    };
  },
  directives: {
    'my - directive': {
       update(el, binding, vnode, oldVnode) {
          if (binding.value!== oldVnode.data.directives[0].value) {
            el.style.fontSize = `${binding.value * 10}px`;
          }
        }
      }
  }
};
</script>
  1. 实际应用场景及利用参数实现功能
    • 表单输入格式化
      • 场景:在输入框中输入金额时,需要格式化显示,如添加千分位分隔符。
      • 实现:利用bindupdate钩子中的elbinding.value参数。在bind钩子中给输入框添加input事件监听,在update钩子中根据binding.value的变化格式化输入框的值并显示。
<template>
  <input v - money - format v - model="moneyValue" />
</template>

<script>
export default {
  data() {
    return {
      moneyValue: ''
    };
  },
  directives: {
    'money - format': {
       bind(el) {
          el.addEventListener('input', function () {
            const value = this.value.replace(/\D/g, '');
            this.value = value.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
          });
        },
       update(el, binding) {
          el.value = binding.value.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        }
      }
  }
};
</script>
  • 元素的权限控制
    • 场景:根据用户的权限,决定某些按钮是否显示。
    • 实现:在bind钩子中,通过binding.value获取权限信息,利用el来控制元素的显示或隐藏。假设v - has - permission指令绑定一个布尔值表示用户是否有该权限:
<template>
  <button v - has - permission="hasDeletePermission" @click="deleteItem">删除</button>
</template>

<script>
export default {
  data() {
    return {
      hasDeletePermission: true
    };
  },
  methods: {
    deleteItem() {
      console.log('执行删除操作');
    }
  },
  directives: {
    'has - permission': {
       bind(el, binding) {
          if (!binding.value) {
            el.style.display = 'none';
          }
        }
      }
  }
};
</script>