记录更新自己的踩坑之路!
1.Vue生命周期
说起Vue不得不提生命周期!
| 生命周期 | 描述 |
|---|---|
| beforeCreate | 组件实例被创建之初,组件的属性⽣效之前 |
| created | 组件实例已经完全创建,属性也绑定,但真实dom还没有⽣成, $el 还不可⽤ |
| beforeMount | 在挂载开始之前被调⽤:相关的 render 函数⾸次被调⽤ |
| mounted | el 被新创建的 vm.$el 替换,并挂载到实例上去之后调⽤该钩⼦ |
| beforeUpdate | 组件数据更新之前调⽤,发⽣在虚拟 DOM 打补丁之前 |
| update | 组件数据更新之后 |
| activited | keep-alive专属,组件被激活时调⽤ |
| deadctivated | keep-alive专属,组件被销毁时调⽤ |
| beforeDestory | 组件销毁前调⽤ |
| destoryed | 组件销毁后调⽤ |
2.MVVM是什么?和MVC有何区别呢?
MVVM和MVC都是架构设计模式
MVVM
- VM:也就是View-Model,做了两件事达到了数据的双向绑定 一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。
- 思想:实现了 View 和 Model 的自动同步,也就是当 Model 的属性改变时,我们不用再自己手动操作 Dom 元素,来改变 View 的显示,而是改变属性后该属性对应 View 层显示会自动改变(对应Vue数据驱动的思想)
MVC
- Model(模型):负责从数据库中取数据
- View(视图):负责展示数据的地方
- Controller(控制器):用户交互的地方,例如点击事件等等
- 思想:Controller将Model的数据展示在View上
3.组件通信
组件之间的传值方式有哪些?
- 父组件传值给子组件,子组件使用
props进行接收 - 子组件传值给父组件,子组件使用
$emit+事件对父组件进行传值 - 组件中可以使用
$parent和$children获取到父组件实例和子组件实例,进而获取数据 - 使用
$attrs和$listeners,在对一些组件进行二次封装时可以方便传值,例如A->B->C - 使用
$refs获取组件实例,进而获取数据 - 使用
Vuex进行状态管理 - 使用
eventBus进行跨组件触发事件,进而传递数据 - 使用
provide和inject,官方建议我们不要用这个,我在看ElementUI源码时发现大量使用 - 使用浏览器本地缓存,例如
localStorage
4. v-if和v-show有何区别?
- 1.
v-if是通过控制dom元素的删除和生成来实现显隐,每一次显隐都会使组件重新跑一遍生命周期,因为显隐决定了组件的生成和销毁 - 2.
v-show是通过控制dom元素的css样式来实现显隐,不会销毁 - 3.频繁或者大数量显隐使用
v-show,否则使用v-if
5. computed和watch有何区别?
- 1.
computed是依赖已有的变量来计算一个目标变量,大多数情况都是多个变量凑在一起计算出一个变量,并且computed具有缓存机制,依赖值不变的情况下其会直接读取缓存进行复用,computed不能进行异步操作 - 2.
watch是监听某一个变量的变化,并执行相应的回调函数,通常是一个变量的变化决定多个变量的变化,watch可以进行异步操作 - 3.简单记就是:一般情况下
computed是多对一,watch是一对多
6. 路由有哪些模式呢?又有什么不同呢?
- computed:
-
computed 是计算属性,也就是计算值,它更多⽤于计算值的场景
-
computed 具有缓存性,computed的值在getter执⾏后是会缓存的,只有在它依赖的属性值改变之后,下⼀次获取
computed的值时才会重新调⽤对应的getter来计算
- computed 适⽤于计算⽐较消耗性能的计算场景
- watch:
- 更多的是「观察」的作⽤,类似于某些数据的监听回调,⽤于观察 props $emit 或者本组件的值,当数据变化时来执
⾏回调进⾏后续操作
- ⽆缓存性,⻚⾯重新渲染时值不变化也会执⾏
⼩结:
-
当我们要进⾏数值计算,⽽且依赖于其他数据,那么把这个数据设计为computed
-
如果你需要在某个数据变化时做⼀些事情,使⽤watch来观察这个数据变化
7.Vue是如何实现双向绑定的?
利⽤ Object.defineProperty 劫持对象的访问器,在属性值发⽣变化时我们可以获取变化,然后根据变化进⾏后续响应,在vue3.0中通过Proxy代理对象进⾏类似的操作。
// 这是将要被劫持的对象
const data = {
name: '',
};
function say(name) {
if (name === '古天乐') {
console.log('给⼤家推荐⼀款超好玩的游戏');
} else if (name === '渣渣辉') {
console.log('戏我演过很多,可游戏我只玩贪玩懒⽉');
} else {
console.log('来做我的兄弟');
}
}
// 遍历对象,对其属性值进⾏劫持
Object.keys(data).forEach(function(key) {
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
console.log('get');
},
set: function(newVal) {
// 当属性值发⽣变化时我们可以进⾏额外操作
console.log(`⼤家好,我系${newVal}`);
say(newVal);
},
});
});
data.name = '渣渣辉';
//⼤家好,我系渣渣辉
//戏我演过很多,可游戏我只玩贪玩懒⽉
8.Proxy与Object.defineProperty的优劣对⽐?
Proxy的优势如下:
-
Proxy可以直接监听对象⽽⾮属性
-
Proxy可以直接监听数组的变化
-
Proxy有多达13种拦截⽅法,不限于apply、ownKeys、deleteProperty、has等等是 Object.defineProperty 不具备的
-
Proxy返回的是⼀个新对象,我们可以只操作新的对象达到⽬的,⽽ Object.defineProperty 只能遍历对象属性直接修改
-
Proxy作为新标准将受到浏览器⼚商重点持续的性能优化,也就是传说中的新标准的性能红利
Object.defineProperty的优势如下:
- 兼容性好,⽀持IE9