1.vue解决了哪些问题
①虚拟dom:dom操作时非常耗性能,不再使用原生的dom操作节点,极大的解放dom操作,但具体操作的还是dom,只是换了一种方式。
**②视图、数据、结构分离:**使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作。
③**组件化:**把一个单页应用中的各种模块拆分到单独的组件中,便于开发,以及后期的维护
2.MVVM的理解
MVVM就是Model-View-ViewModel的缩写,MVVM将视图和业务逻辑分开。
在MVVM框架下,View和Model之间没有直接的联系,而是通过ViewModel进行交互,
因此view数据的变化会同步到Model中,而Model数据的变化也会立即反映到View上
ViewModel通过双向数据绑定把View层和Model层连接了起来,因此开发者只需要关注业务逻辑,不需要手动操作DOM,也不需要关注数据状态的同步问题,这些都由MVVM统一管理。
3.如何实现一个自定义组件,不同组件之间是如何通信的
3-1. 自定义组件
在子组件中创建模版,使用props接收父组件中的数据,在父组件中引入子组件,中components写入子组件名称,最后挂载到父组件中的template。
3-2. props和$emit
父组件通过props在子组件中接收数据
子组件通过this.$emit向父组件中触发事件
3-3. parent
this.$children[0].msg = "hello world" //父组件修改子组件data中的数据
this.$parent.mag //子组件拿到父组件data中的数据
$children的值是数组,$parent的值是个对象
3-4. refs
ref:如果在普通的dom元素上使用,引用指向dom元素,如果在子组件上使用,引用指向组件的实例
//父组件
<template>
<component-a ref="comA"></component-a>
</template>
<script>
export default{
mounted(){
const comA = this.$refs.comA;
console.log(comA.name)//Vue.js
comA.sayHello() //hello
}
}
</script>
//子组件
export default{
data(){
return {
name:"Vue.js"
}
},
methods:{
sayHello(){
console.log("hello")
}
}
}
3-5. eventBus(Bus总线)
1. 在src中新建一个bus.js,导入空的vue实例
2.在传输数据的一方引入bus.js,然后通过Bus.emit()的参数形式来传递
3.在接受的数据的一方引入 Bus.js ,然后通过 Bus.$on("事件名",(data)=>{data是接受的数据})
3-6. listeners
将数据挂在到子组件的标签上,在子组件中使用this.$attrs直接获取到所有挂载的数据,返回的是一个对象。
4. nextTick的理解
**使用nextTick的原因:**Vue是异步修改DOM的,并且不鼓励开发者直接接触DOM,但是有时候需要必须对的DOM元素做相应的处理,这就需要this.$nextTick();
**原理:**Vue通过异步队列控制DOM更新的和nextTick回调函数先后的顺序。
//HTML
<button @click="change()">按钮</button><h1 ref="gss">{{msg}}</h1>
//JS
export default{
name:"app",
data(){
return {
msg:"123"
}
},
methods:{
change(){
this.msg = "456";
console.log(this.refs["gss"].innerHTML)//123
this.$nextTick(function(){
console.log(this.refs["gss"].innerHTML)//456
})
}
}
}
5. Vue的生命周期(11个钩子函数)
1. beforeCreate(创建前):
在此生命周期函数执行的时候,data和methods中的数据都还没有初始化。
2. created(创建后):
在此生命周期函数中,data和methods都已经被初始化好了,最早只能在created中操作。
3. beforeMount(载入前):
在此生命周期函数执行的时候,模板已经在内存中编译好了,未挂载到页面中去,此时页面还是旧的。
4. mounted(载入后):
此时页面和内存中都是最新的数据,最早可以操作dom节点的方法。
5. beforeUpdate(更新前):
此时页面中显示的数据还是旧的,但是data中的数据是最新的。
6. Updated(更新后):
此时页面显示数据和最新的data数据同步。
7. beforeDestroy(销毁前):
并没有真正执行销毁,数据还可以使用。
8.destroyed(销毁后):
数据已经销毁完毕
9. activated:
组件激活时
10. deactivated:
组件未激活时
11. errorCaptured(错误调用):
当捕获一个来自后代组件的错误时调用
6.虚拟dom原理
虚拟dom就是用对象的方式取代真实的DOM操作,把真实的DOM操作放在内存当中,
在内存中的对象里做模拟操作,打开时浏览器会解析HTML元素,构建一颗DOM树,
在内存当中模拟DOM操作,操作完后又会生成一颗dom树,两颗DOM树进行比较,根据diff算法比较两颗DOM树不同的地方,只渲染一次不同的地方。
7.双向绑定的原理?数据劫持?
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式。
通过Object.defineProperty()来劫持属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调
数据劫持:****当我们访问或设置对象的属性的时候,都会触发相对应的函数,然后在这个函数里返回或设置属性的值。我们可以在触发函数的时候动一些手脚做点我们自己想做的事情,这也就是**“劫持”操作**。
8.Proxy相比于defineProperty的优势
Vue3.0摒弃了Object.defineProperty,改为基于Proxy的观察者机制探索
proxy相对于defineproperty的优点:
- 可以劫持整个对象,并返回一个新对象。
- 有多种劫持操作(13种)
Object.defineProperty的缺点:
无法监控到数组下标的变化,使通过数组的下标的设置值,不能实时响应。
Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历
如果能劫持一个完整的对象才是更好的选择。
补充:
Proxy是ES6新增的一个属性,意思就是代理,它来“代理”某些操作。Proxy让我们能够以简洁的控制外部对象的访问,类似于设计模式中的代理模式。
使用Proxy的核心优点是可以交由它来处理一些非核心逻辑(如:读取或设置对象的某些属性前记录日志)
9. watch、computed和methods的区别
watch 监听属性 没有缓存性,属性值发生变化时就会执行,可以利用它做一些异步操作
computed具有缓存性,依赖于属性值,只要属性发生变化时就会重新调用
methods 没有缓存性,只要调用就会执行
10. virtual-dom原理实现(虚拟dom)
virtual-dom(简称vdom)的概念大规模的使用于react相比于频繁的手动去操作dom而带来性能问题,virtual-dom也是react这个框架的非常重要的特性之一
vdom关于dom的创建节点,删除节点,添加节点等dom操作都放到vdom中,
通过操作vdom来提高直接操作的dom的效率和性能。