笔记内容来自于 b 站教学视频 尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通 张天禹老师
Vue 监测数据的原理
模拟 Vue 监测数据
- 定义一个监视方法
Observer,里面逻辑后续添加 - 创建一个监视的实例对象 obs,用于监视 data 中属性的变化
- 添加监视方法
Observer中的逻辑 - 汇总对象中所有的属性形成一个数组
keys - 遍历数组的
key,用Object.defineProperty给每一个 key 添加get和set方法 - 如果 data 中的变量
name被改变了,那么就会调用obs中name对应的setter方法,接着就会触发模板解析,生成新的虚拟 dom,然后与旧的虚拟 dom 使用 diff 算法对比,接着渲染新的页面 - 这是一个简单的模拟的 vue 监测数据的模式,真正的源码会比这更复杂
构造器中的
this,指向的是被 new 出来的实例对象
Vue 监视数据的原理
- Vue 会监视 data 中所有层次的数据
- 如何监测对象中的数据?
- 通过
setter实现监视,且要在new Vue时就传入要监测的数据- 对象中后追加的属性,Vue 默认不做响应式处理
- 如需给后添加的属性做响应式,请使用如下 API:
Vue.set(target, propertyName/index, value)vm.$set(target, propertyName/index, value)
- 通过
- 如何监测数组中的数据?
- 通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进而更新页面
- 通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 在 Vue 修改数组中的某个元素一定要用如下方法:
- 使用这些 API:
push(),pop(),shift(),unshift(),splice(),sort(),reverse() Vue.set()或vm.$set()
- 使用这些 API:
特别注意:
Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性!
Vue 对数组的监测
- Vue 对数组的监测,其实是靠包装数组身上的常用修改数组的方法实现的
- 意思是,在 Vue 中,对 data 中的数组使用以下七种数组操作时,操作的并不是 Object 原型对象上的 push 等方法,而是经过 Vue 包装之后的方法。我们调用了这几种方法,Vue 首先帮我们调用对象原型链上的对应方法,然后会重新解析模板渲染到页面上
- 因此,如果使用了这七种方法外操作数组的方法,Vue 实例并不能监测到数组变化,也就不会触发页面重新渲染
- 下图可以说明,我们对数组操作 push,并不是直接操作 Array 原型链上的 push
收集表单数据
- 若:
<input type="text"/>,则v-model收集的是value值,用户输入的就是 value 值 - 若:
<input type="radio"/>,则v-model收集的是value值,且要给标签配置 value 值 - 若:
<input type="checkbox"/>- 没有配置 input 的
value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值) - 配置 input 的
value属性:v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)v-model的初始值是数组,那么收集的就是value组成的数组
- 备注:v-model 的三个修饰符:
lazy:失去焦点再收集数据number:输入字符串转为有效的数字trim:输入守卫空格过滤
- 没有配置 input 的
<form @submit.prevent="demo">
账号:<input type="text" v-model="userInfo.account"><br/><br/>
密码:<input type="password" v-model="userInfo.password"><br/><br/>
年龄:<input type="number" v-model.number="userInfo.number"><br/><br/>
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"><br/><br/>
爱好:
学习<input type="checkbox" v-model="userInfo.hobby" value="study">
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat"><br/><br/>
所属校区
<select v-model="userInfo.city">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
其它信息:
<textarea v-model="userInfo.other"></textarea><br/><br/>
<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.baidu.com">
<button>提交</button>
</form>
v-pre
- 跳过其所在节点的编译过程
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
自定义指令
- 定义语法
- 局部指令:
new Vue({ directives: {指令名: 配置对象} }) 或 new Vue({ directives{指令名: 回调函数} })- 全局指令
Vue.directive(指令名, 配置对象) 或 Vue.directive(指令名, 回调函数)
- 配置对象中常用的三个回调:
bind:指令与元素成功绑定时调用inserted:指令所在元素被插入页面时调用update:指令所在模板结构被重新解析时调用
- 备注:
- 指令定义时不加
v-,但使用时要加v- - 指令名如果是多个单词,要使用
kebab-case命名方式(如user-name),不要用camelCase命名(如userName) - 指令回调中的 this 对象指的是 window 对象,并不是 Vue 对象
- 回调函数的两个入参,分别为
指令绑定的真实 dom 元素和指令和标签的绑定关系
- 指令定义时不加
生命周期详解
就是把老师的笔记复述了一下,因为没有完整的截图和文档