03 【数据代理 事件处理】

news/2025/1/12 19:07:47/

03 【数据代理 事件处理】

1.数据代理

了解数据代理需要js的一些知识:Object.defineProperty(),属性标志,属性描述符,getter,setter。。。

1.1数据代理

建议学习文章地址:

https://zh.javascript.info/property-descriptors

https://zh.javascript.info/property-accessors

这里简单介绍一下:

属性标志:

对象属性(properties),除 value 外,还有三个特殊的特性(attributes),也就是所谓的“标志”

  • writable — 如果为 true,则值可以被修改,否则它是只可读的
  • enumerable — 如果为 true,则表示是可以遍历的,可以在for… .in Object.keys()中遍历出来
  • configurable — 如果为 true,则此控制属性可以被删除,默认值是false

Object.defineProperty(obj, prop, descriptor)

obj:要定义属性的对象。

prop:要定义或修改的属性的名称

descriptor:要定义或修改的属性描述符

let number = 18
let person = {name: '张三',sex: '男',
}Object.defineProperty(person, 'age', {// value:18,// enumerable:true,		// 控制属性是否可以枚举,默认值是false// writable:true,			// 控制属性是否可以被修改,默认值是false// configurable:true	// 控制属性是否可以被删除,默认值是false// 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值get() {console.log('有人读取age属性了')return number},// 当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值set(value) {console.log('有人修改了age属性,且值是', value)number = value}})
// console.log(Object.keys(person))
console.log(person)

1.2vue中的数据代理

数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)

      let vm = {};let data = {name: 'ds',age: 18,};Object.defineProperty(vm, 'age', {get() {return data.age;},set(value) {data.age = value;},});

image-20220627121636057

使用{{}}插值语法获取vm的x时,触发get方法,将data的x赋值给vm的x

修改data中的age时并没有改变vm里的age的值,当{{}}获取vmage的值时,就会将dataage赋值给vmage

修改vm中的age,触发set方法,将修改的值赋值给data中的age

  1. Vue中的数据代理通过vm对象来代理data对象中属性的操作(读/写)
  2. Vue中数据代理的好处:更加方便的操作data中的数据
  3. 基本原理
  • 通过object.defineProperty()data对象中所有属性添加到vm
  • 为每一个添加到vm上的属性,都指定一个 getter,setter
  • getter,setter内部去操作(读/写)data中对应的属

image-20220627120432752

Vuedata中的数据拷贝了一份到_data属性中,又将_data里面的属性提到Vue实例中(如name),通过defineProperty实现数据代理,这样通过geter/setter操作 name,进而操作_data中的 name。而_data又对data进行数据劫持,实现响应式。

name被修改–>调用setter–>重新解析模板–>生成新的虚拟DOM–>新旧DOM对比(diff)–>更新页面

2.事件处理

2.1事件的基本用法

  1. 使用v-on:xxx@xxx绑定事件,其中 xxx 是事件名
  2. 事件的回调需要配置在methods对象中,最终会在vm上
  3. methods中配置的函数,不要用箭头函数,否则 this 就不是vm了
  4. methods中配置的函数,都是被 Vue所管理的函数,this 的指向是vm组件实例对象
  5. @click="demo"@click="demo($event)"效果一致,但后者可以传参
<!-- 准备好一个容器-->
<div id="root"><h2>欢迎来到{{name}}学习</h2><!-- <button v-on:click="showInfo">点我提示信息</button> --><button @click="showInfo1">点我提示信息1(不传参)</button><!-- 主动传事件本身 --><button @click="showInfo2($event,66)">点我提示信息2(传参)</button>
</div><script>const vm = new Vue({el:'#root',data:{name:'vue',},methods:{// 如果vue模板没有写event,会自动传 event 给函数showInfo1(event){// console.log(event.target.innerText)// console.log(this) //此处的this是vmalert('同学你好!')},showInfo2(event,number){console.log(event,number)// console.log(event.target.innerText)// console.log(this) //此处的this是vmalert('同学你好!!')}}});
</script>

2.2事件修饰符

Vue中的事件修饰符
1.prevent 阻止默认事件(常用)
2.stop 阻止事件冒泡(常用)
3.once 事件只触发一次(常用)
4.capture 使用事件的捕获模式
5.self 只有event.target是当前操作的元素时才触发事件
1.passive 事件的默认行为立即执行,无需等待事件回调执行完毕
修饰符可以连续写,比如可以这么用:@click.prevent.stop="showInfo"

    <style>* {margin-top: 20px;}.demo1 {height: 50px;background-color: skyblue;}.box1 {padding: 5px;background-color: skyblue;}.box2 {padding: 5px;background-color: white;}.list {width: 200px;height: 200px;background-color: skyblue;overflow: auto;}li {height: 100px;}</style><div id="root"><h2>欢迎来到{{ name }}学习</h2><!-- 阻止默认事件(常用) --><a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息</a><!-- 阻止事件冒泡(常用) --><div class="demo1" @click="showInfo"><button @click.stop="showInfo">点我提示信息</button><!-- 修饰符可以连续写 --><!-- <a href="http://www.qq.com" @click.prevent.stop="showInfo">点我提示</a> --></div><!-- 事件只触发一次(常用) --><button @click.once="showInfo">点我提示信息</button><!-- 使用事件的捕获模式 --><div class="box1" @click.capture="showMsg(1)">捕获到的时候就直接触发div1<div class="box2" @click="showMsg(2)">div2</div></div><!-- 只有event.target是当前操作的元素时才触发事件; --><div class="demo1" @click.self="showInfo"><button @click="showInfo">点我提示信息</button></div><!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; --><!-- scroll是滚动条滚动,passsive没有影响 --><!-- wheel是鼠标滚轮滚动,passive有影响 --><ul @wheel.passive="demo" class="list"><li>1</li><li>2</li><li>3</li><li>4</li></ul></div><script type="text/javascript">Vue.config.productionTip = falsenew Vue({el: '#root',data: {name: '尚硅谷'},methods: {showInfo(e) {alert('同学你好!')// console.log(e.target)},showMsg(msg) {console.log(msg)},demo() {for (let i = 0; i < 100000; i++) {console.log('#')}console.log('累坏了')}}})</script>

2.3键盘事件

键盘上的每个按键都有自己的名称和编码,例如:Enter(13)。而Vue还对一些常用按键起了别名方便使用

1.Vue中常用的按键别名
回车enter
删除delete捕获“删除”和“退格”键
退出esc
空格space
换行tab特殊,必须配合keydown去使用
up
down
left
right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(多单词小写短横线写法 NumLock(num-lock) CapsLock(caps-lock)
3.系统修饰键(用法特殊)ctrl、alt、shift、meta(meta就是win键)
3.1配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
指定 ctrl+y 使用 @keyup.ctrl.y
3.2配合keydown使用:正常触发事件
4.也可以使用keyCode去指定具体的按键**(不推荐)**
@keyup.13=xxx(@keyup.enter=xxx)

5.Vue.config.keyCodes 自定义键名 = 键码,可以去定制按键别名

    <div id="root"><h2>欢迎打开{{name}}笔记</h2><input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo"><br/><input type="text" placeholder="按下tab提示输入" @keydown.tab="showInfo"><br/><input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo"><br/></div><script type="text/javascript">Vue.config.productionTip = false	// 阻止 vue 在启动时生成生产提示。Vue.config.keyCodes.huiche = 13		// 定义了一个别名按键new Vue({el: '#root',data: {name: 'vue'},methods: {showInfo(e) {// console.log(e.key,e.keyCode)console.log(e.target.value)}},})</script>

http://www.ppmy.cn/news/139316.html

相关文章

php如何停止重启,取消正在执行的任务调度

前言:最近出现一个问题,同事误操作,开启了一个任务,找到我问能不能停止,我也是火急火燎查询方法帮忙解决,我觉得有必要做个记录,希望帮到有需要的人 之前我写过Laravel和thinkphp的定时任务的使用,不懂的人可以先去看看 Laravel定时任务 thinkphp开启定时任务的三种办法…

Redis学习手册(实例代码)

在下面的代码示例中&#xff0c;将给出两种最为常用的Redis命令操作方式&#xff0c;既普通调用方式和基于管线的调用方式。 注&#xff1a;在阅读代码时请留意注释。 1 #include <stdio.h>2 #include <stdlib.h>3 #include <stddef.h>4 #include <st…

同比增长超8倍!1-4月搭载量赶超去年全年,激光雷达赛道持续升温

尽管整体车市仍处于低迷周期&#xff0c;激光雷达前装赛道&#xff0c;却正在享受爆发式增长的红利。 高工智能汽车研究院监测数据显示&#xff0c;2023年1-4月中国市场&#xff08;不含进出口&#xff09;乘用车前装标配搭载激光雷达10.5万颗&#xff0c;已经接近去年全年的搭…

音箱的喇叭底噪问题

概述 最近项目中遇到一个模拟功放Codec 有底噪的问题&#xff0c;一步一步分析一步一步解决。 音源底噪&#xff0c;由于板子处理不好&#xff0c;导致音源本身就带有干扰信号&#xff0c;传给模拟功放&#xff0c;功放放大输出&#xff0c;导致底噪。&#xff08;较常见&…

音箱箱体的分类(三)

如今市面上常见的音箱主要以密闭式音箱和倒相式音箱为主&#xff0c;今天介绍一种设计更为复杂的音箱——迷宫式音箱。 迷宫式音箱也称曲径式音箱或传线式音箱&#xff0c;实际上就是在音箱内部安装几块障声板&#xff0c;通过障声板形成了一个曲折较长的放声管道&#xff0c;…

用TDA7377做一款立体声功放,DIY功放了解一下?

功率放大器芯片TDA7377常用于汽车音响上。 用该芯片制作功放很简单&#xff0c;芯片外围需要的元器件很少&#xff0c;而且音质不错。 芯片外观长这样&#xff1a; 它可以使用双桥接输出到两个喇叭上&#xff1a; 也可以使用非桥接四单端输出到四个喇叭上&#xff1a; TDA7377的…

二、音箱初始化

首先创建vim main.c初始化设备文件 #include <stdio.h> int g_buttonfd ; int g_ledfd; int g_mixerfd;int main() {InitDriver();return 0; }按键设备文件&#xff0c;用于操作硬件设备 vim deviece.c //用于操作硬件设备 #include <sys/types.h> #include <sy…

[转]音箱摆放位置

我们很容易理解&#xff0c;所谓音箱就是还原声音的&#xff0c;那么从音箱出来的自然就是录音现场的声音&#xff0c;也就是所谓的重现当时的场景。 人的耳朵是一个非常奇妙的东西&#xff0c;尤其是对于声波达到左右耳的时间差和强度差的感知非常灵敏。同时&#xff0c;如果…