🎉 事件总结
This commit is contained in:
parent
afd04a456b
commit
5ca6962782
|
@ -0,0 +1,21 @@
|
|||
## Vue2 模板语法详解
|
||||
|
||||
在 Vue2 中,使用双大括号 `{{}}` 的语法称为插值语法(Mustache 语法),它用于在模板中显示数据。
|
||||
|
||||
### 基本用法
|
||||
```html
|
||||
<h3>你好:{{name}}</h3>
|
||||
```
|
||||
|
||||
### 实现原理
|
||||
当 Vue 实例创建时,会将 data 对象中的属性转换为 getter/setter,使其成为响应式数据。当数据变化时,视图会自动更新。
|
||||
|
||||
```javascript
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
name: "Bunny", // 响应式数据
|
||||
url: "https://v2.cn.vuejs.org/"
|
||||
}
|
||||
})
|
||||
```
|
|
@ -0,0 +1,95 @@
|
|||
# Vue2 数据绑定
|
||||
|
||||
本示例展示了 Vue2 中的两种数据绑定方式:
|
||||
- 单向数据绑定 (`v-bind`)
|
||||
- 双向数据绑定 (`v-model`)
|
||||
|
||||
## 核心概念详解
|
||||
|
||||
### 1. 数据绑定类型
|
||||
|
||||
| 类型 | 指令 | 特点 | 示例 |
|
||||
| -------- | --------- | ----------------- | ----------------------------- |
|
||||
| 单向绑定 | `v-bind` | 数据→视图单向流动 | `<input v-bind:value="name">` |
|
||||
| 双向绑定 | `v-model` | 数据⇄视图双向同步 | `<input v-model="name">` |
|
||||
|
||||
### 2. Vue 实例创建方式
|
||||
|
||||
```javascript
|
||||
// 推荐写法 (ES6简写)
|
||||
data() {
|
||||
return {
|
||||
name: "数据绑定"
|
||||
}
|
||||
}
|
||||
|
||||
// 等价于
|
||||
data: function() {
|
||||
return {
|
||||
name: "数据绑定"
|
||||
}
|
||||
}
|
||||
|
||||
// 不推荐在组件中使用
|
||||
data: {
|
||||
name: "数据绑定"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 动态挂载机制
|
||||
|
||||
```javascript
|
||||
// 延迟挂载示例
|
||||
setTimeout(() => {
|
||||
v.$mount("#app"); // 手动挂载到#app
|
||||
}, 1000);
|
||||
|
||||
// 实例销毁与重建
|
||||
setTimeout(() => {
|
||||
v.$destroy(); // 销毁旧实例
|
||||
|
||||
const v2 = new Vue({ // 创建新实例
|
||||
data: { name: "新数据绑定" }
|
||||
});
|
||||
v2.$mount("#root"); // 挂载到新位置
|
||||
}, 2000);
|
||||
```
|
||||
|
||||
1. **数据绑定选择**:
|
||||
- 表单元素使用 `v-model` 实现双向绑定
|
||||
- 普通属性使用 `v-bind` 实现单向绑定
|
||||
|
||||
2. **实例管理**:
|
||||
- 避免在同一个元素上重复挂载不同实例
|
||||
- 切换挂载目标时务必先销毁旧实例
|
||||
|
||||
3. **数据定义**:
|
||||
- 组件中必须使用函数形式返回data对象
|
||||
- 根实例可以使用对象形式
|
||||
|
||||
4. **性能优化**:
|
||||
- 大量数据绑定时考虑使用计算属性
|
||||
- 复杂场景可使用自定义指令优化
|
||||
|
||||
## 扩展说明
|
||||
|
||||
### 1. `v-model` 原理
|
||||
`v-model` 本质上是语法糖,等价于:
|
||||
```html
|
||||
<input
|
||||
:value="name"
|
||||
@input="name = $event.target.value">
|
||||
```
|
||||
|
||||
### 2. 挂载方式对比
|
||||
| 方式 | 示例 | 适用场景 |
|
||||
| ---------- | ------------------- | -------------------- |
|
||||
| el选项 | `el: "#app"` | 初始化时确定挂载点 |
|
||||
| $mount方法 | `vm.$mount("#app")` | 需要延迟或条件挂载时 |
|
||||
|
||||
### 3. 实例生命周期
|
||||
- `new Vue()` 创建实例
|
||||
- `$mount()` 触发挂载流程
|
||||
- `$destroy()` 触发销毁流程
|
||||
|
||||
通过本文档,您可以全面了解 Vue2 的数据绑定机制和实例管理方法,为实际开发提供参考。
|
|
@ -0,0 +1,76 @@
|
|||
# `Object.defineProperty` 方法
|
||||
|
||||
## 一、基本概念
|
||||
|
||||
`Object.defineProperty()` 是 JavaScript 中用于直接在一个对象上定义一个新属性,或者修改一个对象的现有属性的方法。它允许精确控制属性的行为特性。
|
||||
|
||||
## 属性描述符详解
|
||||
|
||||
### 1. 数据描述符(已注释部分)
|
||||
```javascript
|
||||
{
|
||||
value: 18, // 属性值
|
||||
enumerable: true, // 是否可枚举(for...in或Object.keys())
|
||||
writable: true, // 是否可修改
|
||||
configurable: true // 是否可删除或修改特性
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 存取描述符(实际使用部分)
|
||||
```javascript
|
||||
{
|
||||
get() {
|
||||
// 读取属性时调用
|
||||
return age;
|
||||
},
|
||||
set(value) {
|
||||
// 设置属性时调用
|
||||
age = value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 特性说明
|
||||
|
||||
| 特性 | 类型 | 默认值 | 描述 |
|
||||
| ------------ | ---- | --------- | ------------------------ |
|
||||
| configurable | 布尔 | false | 是否可删除属性或修改特性 |
|
||||
| enumerable | 布尔 | false | 是否出现在枚举属性中 |
|
||||
| value | 任意 | undefined | 属性值 |
|
||||
| writable | 布尔 | false | 是否可被赋值运算符改变 |
|
||||
| get | 函数 | undefined | 读取属性时调用的函数 |
|
||||
| set | 函数 | undefined | 设置属性时调用的函数 |
|
||||
|
||||
## 使用场景
|
||||
|
||||
1. **实现数据响应式**(如Vue2的核心实现)
|
||||
2. **创建私有属性**(通过getter/setter控制访问)
|
||||
3. **属性访问拦截**(在读取或设置时执行额外操作)
|
||||
4. **定义不可枚举属性**(如内置对象的一些方法)
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 数据描述符(value, writable)和存取描述符(get, set)不能同时使用
|
||||
2. 默认情况下,通过defineProperty添加的属性不可枚举、不可写、不可配置
|
||||
3. 在严格模式下,setter必须设置一个参数,否则会抛出错误
|
||||
4. getter不应有副作用(如修改其他属性值)
|
||||
|
||||
**实现简单响应式**
|
||||
|
||||
```javascript
|
||||
function defineReactive(obj, key, val) {
|
||||
Object.defineProperty(obj, key, {
|
||||
get() {
|
||||
console.log(`读取 ${key}: ${val}`);
|
||||
return val;
|
||||
},
|
||||
set(newVal) {
|
||||
console.log(`设置 ${key}: ${newVal}`);
|
||||
val = newVal;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const data = {};
|
||||
defineReactive(data, 'message', 'Hello');
|
||||
```
|
|
@ -0,0 +1,104 @@
|
|||
# JavaScript 数据代理实现文档
|
||||
|
||||
## 一、基本概念
|
||||
|
||||
数据代理是指通过一个对象(代理对象)间接访问和操作另一个对象(目标对象)的属性。本示例展示了如何使用 `Object.defineProperty` 实现简单的数据代理。
|
||||
|
||||
## 二、代码实现解析
|
||||
|
||||
```javascript
|
||||
let obj1 = { x: 100 }; // 目标对象(被代理对象)
|
||||
let obj2 = { y: 200 }; // 代理对象
|
||||
|
||||
// 在obj2上定义x属性的代理
|
||||
Object.defineProperty(obj2, "x", {
|
||||
get() {
|
||||
return obj1.x; // 读取时返回obj1的x属性
|
||||
},
|
||||
set(value) {
|
||||
obj1.x = value; // 设置时修改obj1的x属性
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 三、核心机制说明
|
||||
|
||||
1. **代理原理**:
|
||||
- 通过 `Object.defineProperty` 在代理对象(obj2)上定义新属性
|
||||
- 使用 getter/setter 方法实现对目标对象(obj1)属性的间接访问
|
||||
|
||||
2. **访问流程**:
|
||||
- 读取 `obj2.x` → 触发 getter → 返回 `obj1.x` 的值
|
||||
- 设置 `obj2.x` → 触发 setter → 将值赋给 `obj1.x`
|
||||
|
||||
3. **特性**:
|
||||
- 透明的属性访问(使用者无需知道代理存在)
|
||||
- 可以在访问前后执行额外逻辑(如验证、日志等)
|
||||
|
||||
## 四、应用场景
|
||||
|
||||
| 场景 | 说明 | 示例 |
|
||||
| -------- | -------------------- | ------------------------------ |
|
||||
| 属性转发 | 跨对象访问属性 | 本示例实现 |
|
||||
| 数据验证 | 设置属性前检查有效性 | setter中添加验证逻辑 |
|
||||
| 访问控制 | 限制某些属性的访问 | getter中添加权限检查 |
|
||||
| 日志记录 | 跟踪属性访问 | getter/setter中添加console.log |
|
||||
|
||||
## 五、扩展实现
|
||||
|
||||
### 1. 多属性代理
|
||||
```javascript
|
||||
function proxyProperties(target, source, props) {
|
||||
props.forEach(prop => {
|
||||
Object.defineProperty(target, prop, {
|
||||
get() {
|
||||
return source[prop];
|
||||
},
|
||||
set(value) {
|
||||
source[prop] = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
proxyProperties(obj2, obj1, ['x', 'a', 'b']);
|
||||
```
|
||||
|
||||
### 2. Vue2 风格的数据代理
|
||||
```javascript
|
||||
function observe(obj) {
|
||||
const handler = {
|
||||
get(target, prop) {
|
||||
console.log(`读取 ${prop}`);
|
||||
return target[prop];
|
||||
},
|
||||
set(target, prop, value) {
|
||||
console.log(`设置 ${prop} 为 ${value}`);
|
||||
target[prop] = value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return new Proxy(obj, handler);
|
||||
}
|
||||
|
||||
const observed = observe(obj1);
|
||||
```
|
||||
|
||||
## 六、注意事项
|
||||
|
||||
1. **性能考虑**:
|
||||
- 每个代理属性都会增加访问开销
|
||||
- 避免在性能关键路径上过度使用
|
||||
|
||||
2. **引用关系**:
|
||||
- 代理对象和目标对象保持独立
|
||||
- 修改代理属性会影响原始对象
|
||||
|
||||
3. **枚举特性**:
|
||||
- 默认情况下代理属性不可枚举
|
||||
- 需要显式设置 `enumerable: true`
|
||||
|
||||
4. **兼容性**:
|
||||
- `Object.defineProperty` 是 ES5 特性
|
||||
- 现代开发可考虑使用 ES6 Proxy
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="js/vue@2.7.16.js"></script>
|
||||
<title>Vue中的数据代理</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
Vue中的数据代理: <span>{{name}}</span>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
const vm = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
name: "代理..."
|
||||
}
|
||||
});
|
||||
|
||||
// 如果要查看可以使用 vm._data 看到name,在_data中做了数据劫持
|
||||
// 验证,data==_data 可以将data定义到外部之后使用 vm._data == data 即可
|
||||
// 通过 Object.defineProperty 对vm中对象进行映射,只要修改了 vm._data 或者 vm.xxx 会触发双向绑定
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,146 @@
|
|||
# Vue2 数据代理机制详解
|
||||
|
||||
## 一、核心概念
|
||||
|
||||
Vue2 中的数据代理是指 Vue 实例(vm)代理其 `data` 对象中属性的访问和修改操作。通过这种机制,我们可以直接通过 `vm.xxx` 访问 `data` 中的属性,而不需要写 `vm._data.xxx`。
|
||||
|
||||
## 二、代码示例解析
|
||||
|
||||
```html
|
||||
<div id="app">
|
||||
Vue中的数据代理: <span>{{name}}</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const vm = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
name: "代理..."
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## 三、实现原理
|
||||
|
||||
### 1. 数据存储结构
|
||||
- 原始 `data` 对象被存储在 `vm._data` 属性中
|
||||
- 通过 `Object.defineProperty` 将 `data` 的属性代理到 Vue 实例上
|
||||
|
||||
### 2. 验证方法
|
||||
```javascript
|
||||
// 验证代理关系
|
||||
const externalData = { name: "代理..." };
|
||||
const vm = new Vue({
|
||||
el: "#app",
|
||||
data: externalData
|
||||
});
|
||||
|
||||
console.log(vm._data === externalData); // true
|
||||
console.log(vm.name === vm._data.name); // true
|
||||
```
|
||||
|
||||
### 3. 代理实现机制
|
||||
Vue 内部大致执行了以下操作:
|
||||
```javascript
|
||||
// 伪代码展示代理原理
|
||||
Object.keys(data).forEach(key => {
|
||||
Object.defineProperty(vm, key, {
|
||||
get() {
|
||||
return vm._data[key];
|
||||
},
|
||||
set(value) {
|
||||
vm._data[key] = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 四、数据流图示
|
||||
|
||||
```
|
||||
模板访问
|
||||
↓
|
||||
vm.name (代理访问)
|
||||
↓
|
||||
vm._data.name (实际数据存储)
|
||||
↓
|
||||
数据劫持 (响应式系统)
|
||||
```
|
||||
|
||||
## 五、关键特性
|
||||
|
||||
| 特性 | 说明 | 示例 |
|
||||
| ---------- | ---------------------- | ------------------------------ |
|
||||
| 直接访问 | 省略 `_data` 前缀 | `vm.name` 代替 `vm._data.name` |
|
||||
| 响应式绑定 | 代理属性也是响应式的 | 修改 `vm.name` 会触发视图更新 |
|
||||
| 数据隔离 | `_data` 保存原始数据 | 防止直接修改破坏响应式 |
|
||||
| 统一入口 | 提供一致的数据访问方式 | 简化模板和方法的编写 |
|
||||
|
||||
## 六、与数据劫持的关系
|
||||
|
||||
1. **数据代理**:
|
||||
- 解决的是访问便捷性问题(`vm.xxx` vs `vm._data.xxx`)
|
||||
- 通过 `Object.defineProperty` 实现属性转发
|
||||
|
||||
2. **数据劫持**:
|
||||
- 解决的是响应式问题(数据变化触发视图更新)
|
||||
- 在 `vm._data` 上实现,通过重写 getter/setter
|
||||
|
||||
3. **协作流程**:
|
||||
- 模板访问 `{{name}}` → 触发代理 getter
|
||||
- 代理 getter 访问 `_data.name` → 触发劫持 getter
|
||||
- 建立依赖收集关系
|
||||
|
||||
## 七、注意事项
|
||||
|
||||
1. **新增属性**:
|
||||
- 直接 `vm.newProp = value` 不会成为响应式
|
||||
- 必须使用 `Vue.set` 或预先声明
|
||||
|
||||
2. **性能影响**:
|
||||
- 每个代理属性都会产生一定的内存开销
|
||||
- 大型项目应考虑分模块管理数据
|
||||
|
||||
3. **调试技巧**:
|
||||
- 通过 `vm._data` 查看原始数据
|
||||
- 使用 Vue Devtools 观察数据变化
|
||||
|
||||
4. **与 Vue3 区别**:
|
||||
- Vue3 使用 Proxy 实现更完善的代理
|
||||
- 可以检测属性添加/删除操作
|
||||
|
||||
## 八、扩展应用
|
||||
|
||||
### 1. 自定义代理逻辑
|
||||
```javascript
|
||||
// 在Vue实例上添加自定义代理
|
||||
created() {
|
||||
Object.defineProperty(this, 'fullName', {
|
||||
get() {
|
||||
return `${this.firstName} ${this.lastName}`;
|
||||
},
|
||||
set(value) {
|
||||
const parts = value.split(' ');
|
||||
this.firstName = parts[0];
|
||||
this.lastName = parts[1] || '';
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 代理模式应用
|
||||
```javascript
|
||||
// 实现组件间的数据代理
|
||||
const proxyMixin = {
|
||||
methods: {
|
||||
proxy(prop) {
|
||||
return {
|
||||
get: () => this[prop],
|
||||
set: (val) => this[prop] = val
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="js/vue@2.7.16.js"></script>
|
||||
<title>事件处理</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<h1>Vue2-事件处理</h1>
|
||||
<button @click="showinfo1">函数不传参</button>
|
||||
<button @click="showinfo2($event,66)">函数传参</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
const vm = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
showinfo1() {
|
||||
alert("函数不传参");
|
||||
},
|
||||
showinfo2(event, val) {
|
||||
alert("函数传参")
|
||||
console.log(event, val);
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,158 @@
|
|||
# Vue2 事件处理机制文档
|
||||
|
||||
## 一、基本概念
|
||||
|
||||
Vue2 提供了 `v-on` 指令(简写为 `@`)用于监听 DOM 事件并执行相应的 JavaScript 代码。本示例展示了 Vue2 中事件处理的基本用法,包括不传参和传参两种场景。
|
||||
|
||||
## 二、代码示例解析
|
||||
|
||||
```html
|
||||
<div id="app">
|
||||
<h1>Vue2-事件处理</h1>
|
||||
<button @click="showinfo1">函数不传参</button>
|
||||
<button @click="showinfo2($event,66)">函数传参</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const vm = new Vue({
|
||||
el: "#app",
|
||||
methods: {
|
||||
showinfo1() {
|
||||
alert("函数不传参");
|
||||
},
|
||||
showinfo2(event, val) {
|
||||
alert("函数传参")
|
||||
console.log(event, val);
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
## 三、核心特性说明
|
||||
|
||||
### 1. 事件绑定语法
|
||||
|
||||
| 语法形式 | 示例 | 说明 |
|
||||
| -------- | ---------------------- | ----------------- |
|
||||
| 完整写法 | `v-on:click="handler"` | 使用 `v-on:` 前缀 |
|
||||
| 简写形式 | `@click="handler"` | 更简洁的写法 |
|
||||
|
||||
### 2. 方法定义位置
|
||||
|
||||
所有事件处理函数应定义在 Vue 实例的 `methods` 选项中:
|
||||
```javascript
|
||||
methods: {
|
||||
handler1() { /* ... */ },
|
||||
handler2() { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 参数传递方式
|
||||
|
||||
| 场景 | 示例 | 说明 |
|
||||
| -------------- | ------------------------------- | ------------------------------ |
|
||||
| 不传参 | `@click="showinfo1"` | 自动传入事件对象 |
|
||||
| 传参 | `@click="showinfo2($event,66)"` | 使用 `$event` 传递原生事件对象 |
|
||||
| 仅传自定义参数 | `@click="showinfo2(66)"` | 事件对象将不可用 |
|
||||
|
||||
## 四、事件对象详解
|
||||
|
||||
### 1. 获取事件对象的方式
|
||||
- **不传参时**:自动作为第一个参数传入
|
||||
```javascript
|
||||
methods: {
|
||||
showinfo1(event) {
|
||||
// event 可用
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **传参时需要**:必须显式传递 `$event`
|
||||
```html
|
||||
<button @click="showinfo2($event,66)">按钮</button>
|
||||
```
|
||||
|
||||
### 2. 常用事件对象属性
|
||||
| 属性/方法 | 类型 | 说明 |
|
||||
| ----------------------- | -------- | -------------- |
|
||||
| event.target | Element | 触发事件的元素 |
|
||||
| event.currentTarget | Element | 绑定事件的元素 |
|
||||
| event.preventDefault() | Function | 阻止默认行为 |
|
||||
| event.stopPropagation() | Function | 停止事件冒泡 |
|
||||
|
||||
## 五、最佳实践建议
|
||||
|
||||
1. **方法命名**:
|
||||
- 使用动词开头(如 `handleClick`、`submitForm`)
|
||||
- 保持名称语义化
|
||||
|
||||
2. **参数处理**:
|
||||
- 需要事件对象时确保正确传递 `$event`
|
||||
- 复杂参数建议使用对象形式:
|
||||
```html
|
||||
<button @click="handleClick({id: 1, name: 'test'})">按钮</button>
|
||||
```
|
||||
|
||||
3. **方法组织**:
|
||||
- 相关功能的方法放在一起
|
||||
- 大型组件可考虑按功能分模块
|
||||
|
||||
## 六、扩展应用
|
||||
|
||||
### 1. 事件修饰符
|
||||
Vue 提供了特殊的事件修饰符:
|
||||
|
||||
```html
|
||||
<!-- 阻止默认行为 -->
|
||||
<form @submit.prevent="onSubmit"></form>
|
||||
|
||||
<!-- 停止事件冒泡 -->
|
||||
<div @click.stop="doThis"></div>
|
||||
|
||||
<!-- 按键修饰符 -->
|
||||
<input @keyup.enter="submit">
|
||||
|
||||
<!-- 串联修饰符 -->
|
||||
<button @click.stop.prevent="doThat"></button>
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 2. 自定义事件
|
||||
|
||||
组件间通信时使用:
|
||||
|
||||
```javascript
|
||||
// 子组件
|
||||
this.$emit('my-event', payload);
|
||||
|
||||
// 父组件
|
||||
<child-component @my-event="handleEvent"></child-component>
|
||||
```
|
||||
|
||||
### 3. 原生事件绑定到组件
|
||||
使用 `.native` 修饰符:
|
||||
|
||||
```html
|
||||
<my-component @click.native="handleClick"></my-component>
|
||||
```
|
||||
|
||||
## 七、注意事项
|
||||
|
||||
1. **避免内联计算**:
|
||||
```html
|
||||
<!-- 不推荐 -->
|
||||
<button @click="counter++">增加</button>
|
||||
|
||||
<!-- 推荐 -->
|
||||
<button @click="increment">增加</button>
|
||||
```
|
||||
|
||||
2. **this 指向**:
|
||||
- methods 中的方法自动绑定到 Vue 实例
|
||||
- 避免使用箭头函数定义方法,会导致 this 指向错误
|
||||
|
||||
3. **性能考虑**:
|
||||
- 频繁触发的事件(如 scroll)建议使用防抖/节流
|
||||
- 大量事件监听应考虑事件委托
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="js/vue@2.7.16.js"></script>
|
||||
<title>键盘事件</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
键盘事件:<input type="text" @keydown.huiche="showinfo">
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
Vue.config.keyCodes.huiche = 13
|
||||
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data: {},
|
||||
methods: {
|
||||
showinfo() {
|
||||
alert("showinfo")
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,153 @@
|
|||
# Vue2 键盘事件处理文档
|
||||
|
||||
## 一、基本概念
|
||||
|
||||
Vue2 提供了对键盘事件的支持,允许开发者监听特定的按键操作。本示例展示了如何自定义键盘事件别名并处理回车键事件。
|
||||
|
||||
## 二、代码示例解析
|
||||
|
||||
```html
|
||||
<div id="app">
|
||||
键盘事件:<input type="text" @keydown.huiche="showinfo">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 自定义按键别名
|
||||
Vue.config.keyCodes.huiche = 13; // 13是回车键的keyCode
|
||||
|
||||
new Vue({
|
||||
el: "#app",
|
||||
methods: {
|
||||
showinfo() {
|
||||
alert("回车键被按下");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## 三、核心机制说明
|
||||
|
||||
### 1. 键盘事件绑定语法
|
||||
|
||||
| 语法形式 | 示例 | 说明 |
|
||||
| ---------- | --------------------------- | ------------------ |
|
||||
| 基础写法 | `@keydown="handler"` | 监听所有按键 |
|
||||
| 按键修饰符 | `@keydown.enter="handler"` | 仅监听回车键 |
|
||||
| 自定义别名 | `@keydown.huiche="handler"` | 使用自定义按键别名 |
|
||||
|
||||
### 2. 按键修饰符类型
|
||||
|
||||
Vue 提供了这些常用内置按键别名:
|
||||
- `.enter`
|
||||
- `.tab`
|
||||
- `.delete` (捕获"删除"和"退格"键)
|
||||
- `.esc`
|
||||
- `.space`
|
||||
- `.up`
|
||||
- `.down`
|
||||
- `.left`
|
||||
- `.right`
|
||||
|
||||
### 3. 自定义按键别名
|
||||
|
||||
通过 `Vue.config.keyCodes` 对象添加:
|
||||
```javascript
|
||||
// 语法
|
||||
Vue.config.keyCodes.自定义名称 = 按键keyCode;
|
||||
|
||||
// 示例:将F1键(112)别名为help
|
||||
Vue.config.keyCodes.help = 112;
|
||||
```
|
||||
|
||||
## 四、键盘事件对象
|
||||
|
||||
在方法中可以访问原生事件对象:
|
||||
```javascript
|
||||
methods: {
|
||||
showinfo(event) {
|
||||
console.log(event.key); // 按键名称(如'Enter')
|
||||
console.log(event.keyCode); // 按键代码(如13)
|
||||
console.log(event.target); // 触发事件的元素
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 五、最佳实践建议
|
||||
|
||||
1. **优先使用内置别名**:
|
||||
- 提高代码可读性
|
||||
- 避免记忆keyCode数字
|
||||
|
||||
2. **复杂按键组合**:
|
||||
```html
|
||||
<!-- Ctrl + Enter -->
|
||||
<input @keydown.ctrl.enter="submit">
|
||||
|
||||
<!-- Alt + C -->
|
||||
<input @keydown.alt.67="copy">
|
||||
```
|
||||
|
||||
3. **系统修饰键**:
|
||||
- `.ctrl`
|
||||
- `.alt`
|
||||
- `.shift`
|
||||
- `.meta` (Mac是Command键,Windows是Windows键)
|
||||
|
||||
## 六、扩展应用
|
||||
|
||||
### 1. 自动聚焦示例
|
||||
```html
|
||||
<input @keyup.enter="nextInput" ref="currentInput">
|
||||
|
||||
methods: {
|
||||
nextInput() {
|
||||
this.$refs.nextInput.focus();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 表单提交优化
|
||||
```html
|
||||
<form @submit.prevent>
|
||||
<input @keyup.enter="submit">
|
||||
<button @click="submit">提交</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
### 3. 游戏控制示例
|
||||
```javascript
|
||||
// 监听方向键控制游戏角色
|
||||
created() {
|
||||
window.addEventListener('keyup', this.handleKeyup);
|
||||
},
|
||||
methods: {
|
||||
handleKeyup(e) {
|
||||
switch(e.keyCode) {
|
||||
case 37: this.moveLeft(); break;
|
||||
case 38: this.moveUp(); break;
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 七、注意事项
|
||||
|
||||
1. **keyCode已废弃**:
|
||||
- 现代浏览器建议使用 `event.key` 代替
|
||||
- Vue3 已移除对keyCode的支持
|
||||
|
||||
2. **输入法问题**:
|
||||
- 某些输入法下可能无法正确触发事件
|
||||
- 中文输入时考虑使用 `@keyup` 代替 `@keydown`
|
||||
|
||||
3. **移动端适配**:
|
||||
- 虚拟键盘行为可能不一致
|
||||
- 建议配合触摸事件使用
|
||||
|
||||
4. **事件冒泡**:
|
||||
- 使用 `.stop` 修饰符阻止冒泡
|
||||
```html
|
||||
<div @keydown.enter.stop="handleEnter">
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
Loading…
Reference in New Issue