Vue
vue的优点和缺点
优点:渐进式,虚拟dom,响应式,轻量级,组件化,单页面路由,数据和视图分开
缺点:第一次加载页面慢,不兼容ie8以下的浏览器
2.MVC模式和MVVM模式的区别
mvc模式即model view controller,意思是模型,视图,控制器,将数据存放在模型中,view是用户看到的界面,controller是针对用户输入的数据做复杂的操作再传入数据库
mvvm模式即 model,view,viewmodel,model同样是数据模型,view为用户显示界面,该模式的关键在于viewmodel可以连接用户页面和数据模型,数据一旦改变可以通过viewmodel做处理后同步显示,以此达到数据双向绑定的目的.
mvvm比mvc不仅精简了很多,还将数据和视图隔离,这种低耦合的模式提高了代码的可复用性.
Vue和JQuery的区别在哪?为什么放弃JQuery用Vue?
1.jq是直接对dom进行操作,vue一般不需要对dom直接进行操作,它内部是使用响应式数据绑定来操作虚拟dom以此达到数据更新的目的,由于没有频繁的操作dom,对性能大大的进行了提高
2.vue有很便利的库使用,如vuex vuerouter可以更高效的对数据进行管理,大大提高开发效率,由于不需要操作don开发者可以吧经历都放在数据操作上面.
4.vue中使用过哪些修饰符
1.lazy,懒加载,使用该修饰符的input框会在失焦的时候才会更新data的数据,可以减少资源占用,提高性能.
2.trim
修饰符的作用类似于JavaScript中的trim()
方法,作用是把v-model
绑定的值的首尾空格给过滤掉。
3.number
修饰符的作用是将值转成数字,但是先输入字符串和先输入数字,是两种情况,先输入数字的话会把字符串过滤掉,先输入字符串的话该修饰符就会无效
4.stop
修饰符的作用是阻止冒泡
5.事件默认是由里往外冒泡
,capture
修饰符的作用是反过来,由外网内捕获
<div @click.capture="clickEvent(2)" style="width:300px;height:100px;background:red">
<button @click="clickEvent(1)">点击</button>
</div>
methods: {
clickEvent(num) {
不加 capture 点击按钮输出 1 2
加了 capture 点击按钮输出 2 1
console.log(num)
}
}
6.once
修饰符的作用是,事件只执行一次
7.prevent
修饰符的作用是阻止默认事件(例如a标签的跳转)
8.当父组件
传值进子组件
,子组件想要改变这个值时,可以这么做
父组件里
<children :foo="bar" @update:foo="val => bar = val"></children>
子组件里
this.$emit('update:foo', newValue)
sync
修饰符的作用就是,可以简写:
父组件里
<children :foo.sync="bar"></children>
子组件里
this.$emit('update:foo', newValue)
9.keyCode修饰符 配合@keyup @keydown使用
Vue提供的keyCode:
//普通键
.enter
.tab
.delete //(捕获“删除”和“退格”键)
.space
.esc
.up
.down
.left
.right
//系统修饰键
.ctrl
.alt
.meta
.shift
组件中的传值方式
- localstorage本地缓存传值
- 父向子传值
- 使用子组件时用v-bind绑定自定义元素,该自定义元素在子组件中用props定义.
- 使用父组件中this.$refs.子组件ref名字.子组件方法(父组件参数)也可向子组件传值
- 子向父传值
- 父组件自定义事件,使用该自定义事件的事件函数的形参获取子元素传的数据,子元素使用this.$emit(自定义事件名,要传递的参数)给父元素传参
- 使用子组件this.$parent.父组件的methods(子组件的参数)也可向父组件传值
- 在子组件上设置属性ref.属性=属性值’,父组件可以通过this.$refs.属性值来获取该子组件的上的属性和方法
- 用vuex进行状态管理
- 使用
provide
和inject
,官方建议我们不要用这个
路由切换的两种方式
1.hash模式,通过对#后面的内容更改,触发hashchange事件,实现路切换
2.history模式,切换url来切换路由,须有后端进行配置
computed和watch的区别
computed是计算属性,它通常是根据多个变量来计算出一个变量并返回,不过该属性的set方法可以设置当改变该变量时,与之相关的变量可以跟着改变,他只能执行同步操作,且该属性有缓存机制,当与之关联的变量未做改变时,可跳过计算直接读取缓存获取
watch是侦听器,它通常是监听某一个数据的改变,当这个数据改变时可以影响到其他多个数据,它可以执行异步操作,
设置deep:true可以深度侦听复杂类型内变化
vue声明周期理解
vue生命周期一共有11个钩子函数
创建:
beforecreate() 该钩子函数是在创建vue实例后执行,但是还没有进行数据初始化和响应式处理
created()该钩子函数执行时数据已经初始化完成,计算属性,methods等属性已经挂载在vue实例上,已经可以对数据做修改
挂载:
beforemouted(),render函数在这里被调用,后台已经生成虚拟dom树,但还未转换成真实dom树并挂载到el上
mounted(),该函数执行时,真实dom挂载完毕
更新:
beforeupdate() 对数据更新后该函数执行,此时新的虚拟dom生成,但还没跟旧的虚拟dom对比打补丁
updated() 此时新旧虚拟dom对比打补丁后更新到真实dom上
销毁:
beforedestroy()预备销毁实例前该函数执行,此时依然可以访问实例的数据
destroeyed()vue实例销毁后执行,该实例的所有指令被解绑,所有事件被移除,子组件被销毁,
除此之外还有与缓存路由子组件标签相关的两个钩子函数:
actived() 组件被激活调用
deactived()组件停用时调用
errorcapture(),当捕获一个子组件返回的错误时调用,此钩子函数会受到三个参数—错误对象,发生错误的组件,错误源信息字符串
为什么v-if不建议和v-for一起使用
因为v-for的优先级会高于v-if,如果同时使用,会先循环渲染标签,然后通过v-if判断该标签是否需要显示,如果不显示则销毁,这样会将已经渲染的标签销毁,增加了无用的dom操作,造成了资源的浪费
vue的ssr是什么?有什么好处?
- ssr就是服务端渲染
- vue项目运行后会在服务端渲染好html标签,发送给前端由前端激活,即可成为浏览器识别的html代码
- ssr首次加载更快,有更好的用户体验,有更好的seo优化,因为用户可以更快的看到整个页面,但是由于数据也需要时间解析,所以爬虫并不会等待数据加载完成,所以其实vue的项目seo体验并不是很好
说说nextTick的用处?
Vue采用的是异步更新
的策略,nextick可以在单个数据发生更新后执行的回调函数,由于vue中dom的更新会在事件队列的多个任务执行后仅更新一次,所以可以用nextick在每次数据更新后执行回调拿到最新的视图数据,该函数是一个微任务
JS运行机制
JS是一个单线程,异步,非阻塞IO模型,eventloop事件循环的执行机制
异步任务的返回结果会被放到一个任务队列中,根据异步事件的类型,这个事件实际上会被放到对应的宏任务和微任务队列中去。
在当前执行栈为空时,主线程会查看微任务队列是否有事件存在
- 存在,依次执行队列中的事件对应的回调,直到微任务队列为空,然后去宏任务队列中取出最前面的事件,把当前的回调加到当前指向栈。
- 如果不存在,那么再去宏任务队列中取出一个事件并把对应的回到加入当前执行栈;
当前执行栈执行完毕后时会立刻处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。
在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:
- 执行一个宏任务(栈中没有就从事件队列中获取)
- 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
- 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
- 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
- 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
简单总结一下执行的顺序:
执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环k
vue双向数据绑定的原理?
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
具体步骤:
第一步:需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的 update() 方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。