介绍
# 1.传统的多页模式
传统的开发模式,使用jquery操作dom来开发网页的方式,在老式的多页设计方式下,页面在切换跳转时,网页应用会跳转一个全新的页面,原页面的所有数据都会被销毁,然后加载一个新的页面,假如在新页面和旧页面有共同的模块或数据的情况下,需要发起重复的请求,这时候会浪费页面性能,也无 法让数据在两个页面之间持久化
解决方案
目前的网页应用都是趋向于一种称为单页应用(SPA)的开发模式,不需要刷新或者跳转到不同的页面,甚至不需要重新加载页面,只需要在一个模板上加载和卸载不同的子模板来显示不同的页面
# 2.MVVM设计模式
数据驱动视图是vue最大的特点,当数据发生变化的时候,用户界面发生相应的变化,不需要手动的去修改dom,数据驱动视图也称为mvvm模式;
MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层), VM(ViewModel,V与M连接的桥梁,也可以看作为控制器)
- M:模型层,主要负责业务数据相关;
- V:视图层,顾名思义,负责视图相关,细分下来就是html+css层;
- VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的
# 3.查看版本
// 查看vue版本
`npm list vue` 如果出现(empty)用这个命令 `npm list vue -g`
// 查看vue-cli版本
`vue -V` 或`vue --version`
1
2
3
4
2
3
4
# 4.模板视图
# 模板指令
v-text //使用v-text可以往节点中插入属性值,效果和插值类似
v-html //将数据解析普通字符串,也能html字符串`<span>ddd<span>`
v-bind //改变节点的属性 可以用:简写 :class :style
v-for //数组的循环
v-model //把Model展示到View,从View修改Model的能力,这种行为也叫双向数据绑定
v-if //页面显示与隐藏 频繁地切换,则使用 v-show 较好;反之用v-if。
v-show //页面显示与隐藏
v-on //绑定的事件
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 模板事件
focus: 获取焦点
blur 失去焦点
click 单击
dblclick 双击
mousemove 鼠标移动事件
mouseout 鼠标移出事件
mouseover 鼠标移入事件
keydown 键盘按下事件
keyup 键盘弹起事件
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
事件修饰符
prevent:阻止默认事件(常用);
stop:阻止事件冒泡(常用);
once:事件只触发一次(常用);
capture:使用事件的捕获模式;
self:只有 event.target 是当前操作的元素时才触发事件;
passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
1
2
3
4
5
6
2
3
4
5
6
# 5.响应式原理
# Vue2
let p = {
name: '张三',
age: 20
}
let person = {}
Object.defineProperty(person,'age',{
value:"", // 值
enumerable:true, // 控制属性是否可以枚举,默认值为false
writable:true, // 控制属性是否可以被修改,默认值为false
configurable:true, // 控制属性是否可以被删除,默认值为false
// 当有设置person.age时,set(setter)就会被调用
set(value){
number = value;
},
// 当有读取person.age时, get函数(getter)就会被调用
get(value){
return number;
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
实现原理
- 对象类型,通过
Object.defineProperty()
对属性的读取,修改进行拦截(数据劫持) - 数组类型,通过重写数组的方法,对数组的操作进行拦截(数据劫持)
- 对象类型,通过
存在问题
- 无法检测属性的增加或删除:Vue 不能检测到对象属性的添加或删除。如果需要在实例创建之后添加属性到响应式对象上,需要使用 Vue.set 方法
- 无法检测数组索引和长度的变更:直接通过索引设置数组项,或修改数组的长度无法触发更新。Vue 提供了 Vue.set 和 Vue.delete 方法以及一些数组变异方法(如 push, pop, shift, unshift, splice, sort, reverse)来解决这个问题
- 基于依赖追踪的局限性:如果数据变化是异步的或者变化发生在 Vue 组件之外,Vue 的响应式系统可能无法检测到这些变化,因此可能需要使用 Vue 的 $nextTick 或者手动触发更新。
- 初始化时的性能问题:对于大对象或长数组,使用 Object.defineProperty 会有性能瓶颈,因为需要对每个属性进行遍历和设置
- 深度监听的问题:Vue 可以通过设置 deep: true 来对对象进行深度监听,但这会导致性能问题,因为任何深层次的变化都会触发更新。
- 递归监听可能导致栈溢出:如果数据结构过于复杂,或者存在循环引用,Vue 的响应式系统可能会抛出错误或导致栈溢出。
- 对 ES6 新特性的不支持:例如,Vue 2.x 的响应式系统不能直接检测到 Map、Set、WeakMap 和 WeakSet 这些 ES6 新集合类型的变化
- 不能监听原生类型的变更:例如,如果你直接修改一个非对象类型的响应式属性(如 string 或 number),Vue 无法检测这种变化。
# Vue3
let person = {
name: '张三',
age: 20
}
let proxy = new Proxy(person, {
// 读取
get(target, prop){
// 执行响应式相关的操作,例如通知更新
return Reflect.get(target,prop);
},
// 修改 追加
set(target, prop, value){
// 执行依赖收集
return Reflect.set(target,prop,value)
},
// 删除
deleteProperty(target,propName){
return Reflect.deleteProperty(target,propName)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 实现原理
- 通过Proxy(代理):拦截对象中任意属性的变化(包括读写,添加,删除)
- 通过Reflect(反射):对源对象的属性进行操作 使得操作对象的行为更加规范和一致
上次更新: 2024/10/09, 16:59:47