文章目录
- 1. 数据代理
- 1.1 回顾
- 1.2 开始
- 2. 事件处理
- 2.1 v-on:click 点击事件
- 2.2 事件修饰符
- 2.3 键盘事件
- 3. 计算属性
- 3.1 插值语法实现
- 3.2 methods实现
- 3.3 计算属性实现
- 4. 监视属性
- 4.1 深度监视
- 4.2 监视属性的简写形式
- 4.3 watch 与 computed 对比
1. 数据代理
在学习 数据代理 时 先来回顾一下 Object中的 defineProperty方法.
1.1 回顾
图一 :
图二 :
回顾完 defineProperty 方法后 下面来学习一下数据代理
1.2 开始
数据代理定义 : 通过一个对象代理对另一个对象中属性的操作 读 / 写
给以场景 : 有两个对象 obj 和 obj2 , obj 含有 x , obj2 含有 y , 我想要 obj2 可以读到 obj 的 x ,还能修改 obj 的 x , 请问如何做 ?
答 : 这里就可以使用 defineProperty 完成 ,这就是一个简单的数据代理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>理解数据代理</title>
</head>
<body>
<script>
let obj = {
x: 100
}
let obj2 = {
y: 200
}
// 通过 obj2 读到 x 和 修改 x
Object.defineProperty(obj2, 'x', {
get() {
return obj.x
},
set(value) {
obj.x = value
}
})
</script>
</body>
</html>
效果 :
此时我们就明白了啥是数据代理了 ,下面来看看 Vue 中的 数据代理
通过 : 修改 name 引出 vm_data 与 我们传递的 data 是 同一个
小补充 :
简单的流程图 :
总结 :
-
Vue中的数据代理 :
a.通过 vm 对象来代理 data 对象中属性的操作 (读 / 写)
-
Vue 中 数据代理的好处 :
a. 更方便的操作 data 中 的数据
-
基本原理 :
a. 通过Object。defineProperty() 把 data 对象中所有属性添加到 vm 伤
b.为每一个添加到 vm 上的属性 ,都指定一个 getter / setter
c. 在 getter / setter 内部 去操作 (读 / 写) data 中对应的属性
补充 : 展开_data
2. 事件处理
2.1 v-on:click 点击事件
另外 : 这里我们的 showInfo 是可以 接收参数的 ,
注意 : 这里 showInfo 里面写成了箭头函数 , 此时 this 就代表 window ,而不是 vm (vue 实例对象了)
ES6 语法 中的箭头函数
v-on:click 简写 :@clike
补充 : 这里指定的 回调函数 可以传递参数 , 不止是 event ,
总结: 事件的基本使用 :
- 使用 v-on:xxx 或 @xxx 绑定事件 , 其中 xxx 是事件名
- 事件的回调需要配置在 methods 对象中 ,最终会在 vm 上
- methods 中配置的函数 , 不要使用 箭头函数 ! 否则 this 就是是 vm了
- methods 中 配置的函数 , 都是 被 Vue 所管理的 函数 , this 的指向是 vm 或 组件实例对象
- @click = “demo” 和 @click = “demo($event)” 效果一致 , 但后者可以传参 .
2.2 事件修饰符
1. prevent : 阻止默认事件
2. stop : 阻止事件冒泡
3. once: 事件只触发一次
4. capture :使用事件的捕获模式
5. self : 只有 event.target
是 当前操作的 元素时才触发
6. passive :事件的默认行为立即执行,无序等待事件的回调执行完毕
注意 : 这里 主要掌握前 三个即可 ,后面这三个用的少
最后补充一下小技巧 : 我们的事件修饰符 是可以连着写的
比如 :
@click.stop.prevent 此时就相当于 先阻止冒泡 ,在阻止默认事件
2.3 键盘事件
关于键盘事件 常用的有两个 :
-
键盘按下事件:keydown() 是在键盘按下就会触发
-
键盘弹起事件:keyup() 是在键盘松手就会触发
简单说一下 Keyup与Keydown区别为:触发不同、焦点不同、用途不同。
一、触发不同
1、Keyup:Keyup的事件在键盘按键按下时立即触发。
2、Keydown:Keydown的事件在键盘按键放开时立即触发。
二、焦点不同
1、Keyup:Keyup事件触发的时候需要保证控件拥有焦点。
2、Keydown:Keydown事件触发的时候不需要保证控件拥有焦点。
图一 :
图二 :
3. 计算属性
通过一个代码案例 ,来显示出为啥需要计算属性 :
需要实现的效果 :
3.1 插值语法实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>姓名案例_插值语法实现</title>
<!-- 引入 vue -->
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="root">
姓 : <input type="text" v-model="firstName"><br /><br />
名 : <input type="text" v-model="lastName"><br /><br />
全名 : <span>{{firstName}} - {{lastName}}</span>
<!-- {{firstName.slice(0,3)}} slice(0,3) 只会读取前三位 -->
</div>
<script>
new Vue({
el: "#root",
data: {
firstName: '张',
lastName: '三'
}
})
</script>
</body>
</html>
3.2 methods实现
3.3 计算属性实现
图一 :
图二 :
总结:
计算属性 :
-
定义 : 要用的属性不存在 , 要通过已有属性计算得出
-
原理 : 底层借助了 object.defineproperty方法提供 getter 和 setter
-
get 函数什么时候执行 ?
a. 初次读取时会执行一次
b. 当依赖的数据发生改变时会被再次调用
-
优势 : 与 methods 实现相比 , 内部有缓存机制(复用) , 效果更高 ,调试方便.
-
备注 :
a. 计算属性最终会出现在 vm 上 , 直接读取使用即可 。
b. 如果计算属性要被修改,那必须写 set 函数去响应修改. 且 set 中 要引起计算时依赖的数据发生改变
计算属性 简写形式
计算属性 , 计算出的属性更多情况下是不会修改的 , 此时 set 就可以 写 (只考虑 读 不考虑 改)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>姓名案例_methods实现</title>
<!-- 引入 vue -->
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="root">
姓 : <input type="text" v-model="firstName"><br /><br />
名 : <input type="text" v-model="lastName"><br /><br />
全名 : <span>{{fullName}}</span><br /><br />
</div>
<script>
let vm = new Vue({
el: "#root",
data: {
firstName: '张',
lastName: '三'
},
computed: {
// 简写 :
// 这个函数就当作 get 使用
fullName: function () {
return this.firstName + " - " + this.lastName
}
}
})
</script>
</body>
</html>
此时 这个 fullName : function() {} 还可以简写一下
computed: {
// 简写 :
// 这个函数就当作 get 使用
fullName() {
return this.firstName + " - " + this.lastName
}
}
4. 监视属性
通过 一个代码案例 引出 监视属性 :
需要实现效果 :
图一 :
图二 :
图三 : 第二种方式 配置 监视
总结 :
监视属性 watch
:
-
当被监视的属性变化是 , 回调函数自动调用 ,进行相关操作
-
监视的属性必须存在 , 才能进行监视
-
监视的两种写法
a. new Vue 时 传入 watch 配置
b. 通过 vm.$watch 监视
总结完 ,下面来看看监视的扩展点 , 深度监视
4.1 深度监视
总结 :
深度监视 :
- Vue 中 的watch 默认不监测对象内部值的改变 (一层)
- 配置 deep: true 可以监测对象内部值改变 (多层)
备注 :
- Vue 自身可以监测 对象内部值的改变 , 但 Vue 提供的 watch 默认不可以
- 使用 watch时根据数据的具体结构 , 决定是否采用深度监视
4.2 监视属性的简写形式
当 我们 不需要 immediate (初始化执行一次) , deep (深度监视), 即 配置项中只有 handler 时 可以简写 。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例 : </title>
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很: {{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
<script>
new Vue({
el: "#root",
data: {
isHost: true,
},
computed: {
info() {
return this.isHost ? '炎热' : '凉爽';
}
},
methods: {
changeWeather() {
this.isHost = !this.isHost;
}
},
watch: {
isHost(newValue, oldValue) {
console.log('isHost 被修改了', newValue, oldValue)
}
}
})
</script>
</body>
</html>
通过 vm.$watch , 同样也可也i简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例 : </title>
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很: {{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
<script>
let vm = new Vue({
el: "#root",
data: {
isHost: true,
},
computed: {
info() {
return this.isHost ? '炎热' : '凉爽';
}
},
methods: {
changeWeather() {
this.isHost = !this.isHost;
}
},
})
vm.$watch("isHost", function (newValue, oldValue) {
console.log("isHost被修改了", newValue, oldValue);
})
</script>
</body>
</html>
4.3 watch 与 computed 对比
图一 :
图二 :
图三 :
总结 :
computed 和 watch 之间的区别 :
- computed 能完成的功能 , watch 都可以完成.
- watch 能完成的功能 , computed 不一定能完成, 列如 : watch 可以进行异步操作.
两个重要的小原则 :
- 所被 Vue 管理的函数 , 最好写成普通函数 ,这 this 的指向 才是 vm 或 组件实例对象
- 所有不被 Vue 所管理的函数 (定时器的回调函数 , ajax 的 回调函数 等) , 最好写成箭头函数 , 这样 this 的指向才是 vm 或 组件实例对象.