1.Object.defineProperty 方法
2.数据代理
3.Vue中的数据代理
4.事件的基本使用
5.事件修饰符
6.键盘事件
一.Object.defineProperty 方法
(1)学习Object.defineProperty为下一节数据代理做准备
(2)更加高级的给对象添加属性方法
(3)用法
let person = {
name: '张三',
gender: '男'
}
// 添加属性 age属性不参与遍历
Object.defineProperty(person, 'age', {
value: 18,
enumerable: true, // 控制属性是否可以枚举,默认为false
writable: true, // 控制属性是否可以被修改
configurable: true, // 控制属性是否可以被删除
})
-
value:赋值
-
enumerable:控制属性是否可以枚举
-
writable:控制属性是否可以被修改
-
configurable:控制属性是否可以被删除
(4)get() 和 set()属性
get():当有人读取age属性时,get函数就会被调用,返回值就是age的值
let number = 18
let person = {
name: '张三',
gender: '男'
}
// 添加属性 age属性不参与遍历
Object.defineProperty(person, 'age', {
get () {
console.log('有人读取age属性了')
return number
},
set (value) {
console.log('有人修改age属性了')
number = value
}
})
get属性验证
set属性验证
Object.defineProperty 将两个无关的数据联系起来了,修改了person的age属性,number也跟着修改了
二. 数据代理
数据代理:通过一个对象代理对另一个对象中的属性的操作
通过obj2也可以操作obj中的x
<script type="text/javascript">
let obj = { x: 100 }
let obj2 = { y: 200 }
Object.defineProperty(obj2, 'x', {
get () {
console.log('有人访问了obj2的x属性')
return obj.x
},
set (value) {
console.log('有人修改了obj2的x属性')
obj.x = value
}
})
</script>
三.Vue中的数据代理
- vue将vm._data的name和address,映射到vm.name和vm.address
- vm._data.name改变,vm.name也会改变
- 通过 Object.defineProperty 中的get和set 方法实现数据代理
总结:
- Vue中的数据代理,通过vm对象来代理data对象中属性的操作
- Vue中数据代理的好处:更加方便的操作data中的数据
- 基本原理:通过Object.defineProperty() 把data对象中的所有属性添加到vm上
- 为每一个添加到vm上的属性都会指定一个getter和setter
- 在getter/setter内部操作data中对应的属性
四. 事件的基本使用
(1)绑定事件
- 使用v-on绑定点击事件
<button v-on:click="showInfo">点我提示信息</button>
- v-on可以简写为@形式
<button @click="showInfo">点我提示信息</button>
- 绑定的showInfo事件需要写到methods配置项中
- methods中配置的函数,不要用箭头函数,否则this就不是vm了
- methods中配置的函数,都是被Vue管理的函数,this 的指向是vm或者组件实例对象
<div id="root">
<h2>欢迎来到{{name}}学习</h2>
<button v-on:click="showInfo">点我提示信息</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data: {
name: '尚硅谷'
},
methods: {
showInfo (event) {
console.log(event.target.innerText)
console.log(this) // 此处的this指的是vm
}
}
})
</script>
- 如果不需要传参数就可以按照上面的写法
- 如果需要传参数,就在函数名后面加小括号,把参数传进去
- 函数本身会自己带一个event参数,如果需要这个event,就可以把自己需要的参数写到后面
- 在Vue中,如果你想传一个实参event对象,不能直接写event,而是应该写$event
- 如果在methods中需要调用data配置的数据,使用this.就可以访问到
<button @click="showInfo2($event, 66)">点我提示信息2</button>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
// 只有写在data里面的数据才会做数据代理
data: {
name: '尚硅谷'
},
methods: {
showInfo2 (event, number) {
console.log(event, number)
alert('同学你好!!')
}
}
})
</script>
五. 事件修饰符
Vue中常用的事件修饰符
① prevent:阻止默认事件(常用)
② stop: 阻止事件冒泡(常用)
③ once:事件只触发一次(常用)
④ capture:使用事件的捕获模式
⑤ self: 只有event.target 是当前元素时才触发事件
⑥ passive:事件的默认行为立即执行,无需等待事件回调执行完毕
(1) prevent:阻止默认事件(常用)
如果click后面不加prevent的话,点击之后执行完showInfo中的逻辑,就会跳到href指定的链接
<a href="http://www.baidu.com" @click.prevent="showInfo">点我提示信息</a>
(2)stop: 阻止事件冒泡(常用)
如果click后面不加stop的话,showInfo会执行两次,如果加stop,showInfo只会执行一次,就是阻止了事件向上冒泡
<div class="demo1" @click="showInfo">
<button @click.stop="showInfo">点我提示信息</button>
</div>
(3)once:事件只触发一次(常用)
点击之后,事件只触发一次,再点的话不会生效
<button @click.once="showInfo">点我提示信息</button>
(4)capture:使用事件的捕获模式
如果不加capture:点击box2的时候会输出 2, 1 (冒泡模式)
如果加上capture:点击box2的时候会输出1, 2 (捕获模式)
capture的作用就是使用捕获模式
<div class="box1" @click="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">div2</div>
</div>
(5)self: 只有event.target 是当前元素时才触发事件
如果没有加self的话,点击按钮,showInfo会执行两次
如果加上self的话,点击按钮,showInfo只会执行一次
只有点击的是div(当前元素)的之后,上面的showInfo才会执行
<div class="demo1" @click.self="showInfo">
<button @click="showInfo">点我提示信息</button>
</div>
(6)passive:事件的默认行为立即执行,无需等待事件回调执行完毕
如果不加passive的话,会先将demo中的逻辑执行完毕,再执行滚轮的默认事件
加上passive之后,会立即执行滚轮的默认事件,无需等待demo回调执行完毕
<ul @wheel.passive="demo" class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
(7) 事件修饰符可以连着写(先阻止事件冒泡,再阻止默认事件)
<a href="http://www.baidu.com" @click.stop.prevent="showInfo">点我提示信息</a>
六. 键盘事件
(1)Vue中常用的按键别名
<input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo">
键盘事件 | 按键别名 |
回车 | enter |
删除 | delete(捕获‘删除’和‘退格’) |
退出 | esc |
空格 | space |
换行 | tab(特殊,必须配合keydown使用) |
上 | up |
下 | down |
左 | left |
右 | right |
(2) 未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
<input type="text" placeholder="按下回车提示输入" @keyup.caps-lock="showInfo">
console.log(e.key, e.keyCode) <--可以用key获取按键名-->
(3)Tab键必须配合keydown使用,如果写keyup会切换焦点,按键没有用
(4)系统修饰键(用法特殊):ctrl alt shift meta
① 配合keyup使用,按下修饰键的同时,再按下其他键,最后释放其他键,事件才会被触发
② 配合keydown使用,正常触发事件
(5)也可以使用keyCode去指定具体的按键,但是不推荐(该特性已经从Web标准中删除)
(6)自定义键名: Vue.config.keyCodes.自定义键名 = 键码, 可以定制按键名(不推荐)
<div id="root">
<input type="text" placeholder="按下回车提示输入" @keyup.huiche="showInfo">
</div>
<script type="text/javascript">
Vue.config.keyCodes.huiche = 13 // 定义了一个按键别名
new Vue({
el: '#root',
data: {
name: '尚硅谷'
},
methods: {
showInfo (e) {
console.log(e.key, e.keyCode)
}
}
})
</script>