# Vue2 自定义指令全面指南

指令中的作用域时window！！！

## 一、指令类型对比

| 类型   | 语法                                  | 触发时机      | 适用场景    |
| ------ | ------------------------------------- | ------------- | ----------- |
| 函数式 | `directives: { big(el, binding) {} }` | bind + update | 简单DOM操作 |
| 对象式 | `directives: { fbind: { hooks } }`    | 完整生命周期  | 复杂交互    |

## 二、对象式指令详解

### 1. 完整生命周期钩子
```javascript
fbind: {
    // 指令第一次绑定到元素时调用（初始化设置）
    bind(el, binding) {
        el.value = binding.value;
    },
    // 被绑定元素插入父节点时调用
    inserted(el, binding) {
        el.focus(); // 自动获取焦点
    },
    // 所在组件更新时调用
    update(el, binding) {
        el.value = binding.value;
        el.focus(); // 值更新后重新聚焦
    }
}
```

### 2. 执行流程示例
1. 初始化时：`bind` → `inserted`
2. 数据更新时：`update`
3. 模板重新解析时：`update`

## 三、最佳实践建议

### 1. 输入框增强指令
```javascript
Vue.directive('input-enhanced', {
    inserted(el) {
        el.select(); // 自动选中文本
    },
    update(el) {
        // 防抖处理避免频繁触发
        clearTimeout(el._timer);
        el._timer = setTimeout(() => {
            el.select();
        }, 300);
    },
    unbind(el) {
        // 清理工作
        clearTimeout(el._timer);
    }
});
```

### 2. 性能优化技巧
```javascript
update(el, binding) {
    if (binding.value !== binding.oldValue) {
        // 只有值变化时才执行操作
        el.value = binding.value;
    }
}
```

## 四、高级应用场景

### 1. 权限控制指令
```javascript
Vue.directive('permission', {
    inserted(el, binding) {
        if (!checkPermission(binding.value)) {
            el.parentNode.removeChild(el);
        }
    }
});
```
使用方式：
```html
<button v-permission="'admin'">管理按钮</button>
```

### 2. 拖拽指令实现
```javascript
Vue.directive('drag', {
    inserted(el) {
        el.style.cursor = 'move';
        el.onmousedown = function(e) {
            // 拖拽逻辑实现
        }
    },
    unbind(el) {
        el.onmousedown = null; // 清理事件
    }
});
```

## 五、常见问题解决方案

1. **指令不生效问题排查**
   - 检查指令名称是否使用kebab-case（短横线）
   - 确认绑定值是否为响应式数据
   - 验证是否在正确的生命周期钩子操作DOM

2. **动态指令参数**
```html
<div v-demo:[dynamicArg]="value"></div>
```
```javascript
binding.arg // 获取动态参数
```

3. **多修饰符处理**
```javascript
if (binding.modifiers.large) {
    el.style.fontSize = '20px';
}
if (binding.modifiers.red) {
    el.style.color = 'red';
}
```

## 六、与Vue3的对比

| 特性      | Vue2                   | Vue3                |
| --------- | ---------------------- | ------------------- |
| 钩子名称  | `bind` → `beforeMount` |                     |
|           | `inserted` → `mounted` |                     |
|           | 新增`beforeUpdate`     |                     |
| 参数传递  | 通过`binding`对象      | 更直观的上下文参数  |
| 组合式API | 无                     | 支持setup中使用指令 |
