MST

星途 面试题库

面试题:Vue指令结合Composition API实现动态指令参数的复杂场景应用

假设你需要在一个Vue应用中实现一个可复用的拖拽指令,该指令的目标元素、拖拽范围等参数需要动态变化。请说明如何利用Vue指令系统和Composition API来实现这一功能,要求详细描述实现步骤,包括如何在setup函数中处理响应式数据以及如何编写自定义指令的钩子函数。
41.6万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试
  1. 创建Vue项目并设置基础结构
    • 确保已经安装了Vue CLI,使用vue create drag - directive - demo创建一个新的Vue项目。
    • src/components目录下创建一个组件,例如DragComponent.vue,用于演示指令的使用。
  2. 在setup函数中处理响应式数据
    • DragComponent.vue中,使用Composition API的setup函数。
    • 引入ref来创建响应式数据。例如:
<template>
  <div v - drag:element="dragTarget" :drag - range="dragRange">
    <!-- 这里是目标元素的内容 -->
  </div>
</template>

<script setup>
import { ref } from 'vue';

// 目标元素
const dragTarget = ref(null);
// 拖拽范围
const dragRange = ref({
  x: 0,
  y: 0,
  width: window.innerWidth,
  height: window.innerHeight
});
</script>
  1. 编写自定义指令
    • src/directives目录下创建drag.js文件。
    • 使用Vue.directive或者在Composition API中通过app.directive来创建自定义指令。
    • 定义指令的钩子函数:
import { onMounted, onUnmounted } from 'vue';

export default {
  mounted(el, binding, vnode) {
    let startX, startY;
    let initialLeft, initialTop;

    const handleMouseDown = (e) => {
      startX = e.clientX;
      startY = e.clientY;
      initialLeft = parseInt(el.style.left || '0');
      initialTop = parseInt(el.style.top || '0');

      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
    };

    const handleMouseMove = (e) => {
      const dx = e.clientX - startX;
      const dy = e.clientY - startY;
      let newLeft = initialLeft + dx;
      let newTop = initialTop + dy;

      const { x, y, width, height } = binding.value.dragRange;
      if (newLeft < x) newLeft = x;
      if (newLeft + el.offsetWidth > x + width) newLeft = x + width - el.offsetWidth;
      if (newTop < y) newTop = y;
      if (newTop + el.offsetHeight > y + height) newTop = y + height - el.offsetHeight;

      el.style.left = newLeft + 'px';
      el.style.top = newTop + 'px';
    };

    const handleMouseUp = () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };

    el.addEventListener('mousedown', handleMouseDown);
  },
  updated(el, binding, vnode) {
    // 如果拖拽范围等参数变化,可以在这里更新相关逻辑
  },
  unmounted(el) {
    el.removeEventListener('mousedown', () => {});
    document.removeEventListener('mousemove', () => {});
    document.removeEventListener('mouseup', () => {});
  }
};
  1. 注册自定义指令
    • main.js中注册指令:
import { createApp } from 'vue';
import App from './App.vue';
import dragDirective from './directives/drag';

const app = createApp(App);
app.directive('drag', dragDirective);
app.mount('#app');

这样就实现了一个可以动态变化目标元素和拖拽范围的可复用拖拽指令,在DragComponent.vue中可以根据需要修改dragTargetdragRange的值来改变指令的行为。