每个前端都要掌握的[Vue 基本知识] 金三银四 求职必备
Vue的优缺点?
优点:渐进式,组件化开发,虚拟dom,单页面路由,数据视图分离
缺点:单页面不利于SEO,不兼容IE,首屏加载时间长
1.渐进式的意思就是Vue的全家桶有很多,你可以选择不用,或者选择几样去用,或者只用一个,比如不用vuex
2.组件化开发就是可以封装复用组件
3.虚拟DOM是因为频繁操作真实DOM是很昂贵的,所以要虚拟DOM解决浏览器性能问题,加入一次操作中有十次更新DOM的动作虚拟DOM不会立即操作DOM,而是将这十次更新的内容保存到本地js对象中,通过js对象渲染到DOM树,避免大量无谓的计算。
4.单页面路由意思就是只在一个页面写内容,一个页面写路由入口。
5.数据视图分离就是MVVM模式,Vue的数据响应式就是MVVM的更新模式 它有三个层级,分别是数据层model 视图层 view 视图模型层ViewModel。 ViewModel通过Observer监听model的数据变化,自动同步更新到view视图层上。 ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
优点:分离view和model层,降低代码耦合,提高视图逻辑复用性,自动更新DOM利用双向绑定原理,让数据更新后视图也自动更新。 缺点:出现问题很难调试,因为使用了双向数据绑定,页面出现问题很难判断是view层还是model层,数据长期持久不会释放内容,虽然保证了数据一致性,可能造成性能开销,消耗更多内存。
Vue和React的异同点
相同点:都是单向数据流,都是用了虚拟DOM技术,组件化开发 不同点:
1.前者template,后者JSX。
2.数据变化,前者响应式,后者手动setState,
3.React单向绑定,VUE双向绑定。
4.React状态管理工具,Redux,Moobx,Vue状态管理工具,Vuex
Vue和JQuery的区别?为什么不用JQuery而用VUE?
JQuery直接操作DOM,而Vue不直接操作DOM,而是只需操作数据
Vue的虚拟DOM技术,能适配多端
Vue集成了一些库,大大提高开发效率,例如Route、Vuex等等
为什么data是一个函数?为什么要返回一个对象?
如果data是一个函数就类似于每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据,如果单纯写成对象的形式会导致一个变了全都会变的结果,返回一个对象可以防止组件被多个页面使用时,造成的变量互相污染
使用过什么修饰符?
trim去前后空格 number 转换数字类型 stop阻止事件冒泡 captrue 事件之间捕获 self 点击事件绑定本身才触发 once 事件只触发一次 prevent 阻止事件默认行为 native绑定事件在自定义组件上 passive 给移动端滚动事件加.lazy camel 确保变量被识别成驼峰命名 sync 简化子修改父值得步骤
路由模式有几种
hash:哈希模式,根据hash值的更改进行组件切换,而不刷新页面
history:历史模式,依赖于HTML5的pushState和replaceState
abstract:适用于Node
路由的钩子函数
beforeEach 前置守卫 afterEach后置守卫
回调函数:to要进入的路由对象,from要离开的路由对象,next 执行跳转的方法
router.push,router.replace,router-go的区别
router.push:跳转,并向history栈中加一个记录,可以后退到上一个页面
router.replace:跳转,不会向history栈中加一个记录,不可以后退到上一个页面
router.go:传正数向前跳转,传负数向后跳转
路由独享钩子怎么写?
routes: [
{
path: '/xxx',
component: xxx,
//在路由中写
beforeEnter: (to, from, next) => {
}
}
]
Vue的内部指令有哪些?
v-text:元素的textContentv-html:元素的innerHTMLv-show:通过样式display改变显隐v-if:通过操作DOM改变显隐v-else:配合v-ifv-else-id:配合v-elsev-for:循环渲染v-on:绑定事件,缩写@v-bind:绑定变量,缩写:v-model:双向绑定v-slot:插槽v-once:只渲染一次v-pre:跳过元素编译v-cloak:隐藏双括号,有值再显示
组件之间传值得方式有哪些?
- 父传子,子组件通过
props接收 - 子传父,子组件使用
$emit对父组件进行传值 - 父子之间通过
$parent和$chidren获取实例进而通信 - 通过
vuex进行状态管理 - 通过
eventBus进行跨组件值传递 provide和inject,官方不建议使用$ref获取实例,进而传值- 路由传值
- localStorage、sessionStorage
如何设置动态class对象,动态style数据?
- 动态class对象:
<div :class="{ 'is-active': true, 'red': isRed }"></div> - 动态class数组:
<div :class="['is-active', isRed ? 'red' : '' ]"></div> - 动态style对象:
<div :style="{ color: textColor, fontSize: '18px' }"></div>
v-if和v-show的区别
v-if 通过操作DOM来控制显隐,适用于按钮鉴权 v-show 通过改变样式display属性控制显隐,适用于频繁显隐的情况
computed和watch有何区别?
computed:依赖多个变量计算出一个变量,且具有缓存机制,依赖值不变的情况下,会复用计算值。computed中不能进行异步操作watch:通常监听一个变量的变化,而去做一些事,可异步操作
Vue的生命周期
初始化阶段: new Vue实例化,初始化事件和生命周期函数,钩子函数执行beforeCreate, 钩子函数执行完成实例创建created
挂载阶段: 编辑模板-是否有el选项: 如果有继续检查template选项,返回return函数。生命周期函数执行beforeMount, 真实Dom挂载完毕执行mounted。 如果没有,编译el选项对应的标签作为template,把虚拟>Dom和渲染的数据一并挂到 真实Dom上,真实Dom挂载完毕执行mounted。
更新阶段: data数据改变 更新Dom之前,生命周期钩子函数执行beforeUpdate,虚拟Dom重新渲染, 打补丁到真实Dom,生命周期函数执行updated。此时如果数据继续改变重复执行这个循环
销毁阶段: 当$destory被调用,比如组件Dom被移除v-if,生命周期钩子函数执行beforeDestory, 卸载事件监听器,手动销毁定时器,生命周期钩子函数执行Destoryed。
为什么V-if和V-for不建议在一起使用?
v-for优先级高于v-if,每项都通过v-for渲染出来后再去通过v-if判断显隐,做了很多无用操作,有点多余
vuex的属性有哪些?用处是什么?
state:定义初始状态getter:从store从取数据mutation:更改store中状态,只能同步操作action:用于提交mutation,而不直接更改状态,可异步操作module:store的模块拆分
不需要响应式的数据应该怎么处理?
定义在data的return之外
使用Object.freeze进行数据冻结
watch监听怎么使用有哪些属性
immediate:初次加载时立即执行
deep:是否进行深度监听
handler:监听的回调函数
wathc监听器中immediate属性有什么作用?
Vue实例初始化的时候立即调用watch监听回调函数
组件生命周期的执行顺序
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
对象属性无法更新视图,属性改变或删除不更新视图,原因及方案?
原因:Object.defineProperty没有对对象的新属性进行劫持 解决方法:
新增属性:Vue.set(target, key, value)
删除属性:Vue.delete(target, key)
直接arr[1] = xxx 无法更新视图怎么办?
这个原因是因为Vue对于性能考虑没有对数组下标进行劫持,而是通过改写成数组原型方法。
splice:arr.splice(index, 1, value)
Vue.set(target, index, value)
他一共有三个参数,分别是目前属性,新增属性,新增的值。
为什么不建议使用index/随机数作为key?
因为index和随机数每次更新他都在改变,会导致每个dom元素不是唯一的,做不到专一性,也很消耗性能, 所以我们选择id 唯一的。
自定义指令的钩子函数
bind指令绑定到指定元素时调用,只调用一次 inserted 指定元素插入父节点 update 所在组件的VNode更新时调用 componnetUpdated 所在组件及子组件VNode 全部更新后调用 unbind 只调用一次,指令与元素解绑时调用
说说nextTick的用处
修改数据不能马上得到最新的DOM信息,所以需要使用nextTick,在nextTick回调中可以获取最新DOM信息, 获取更新最新DOM后的元素。
宏任务和微任务
宏任务:异步AJAX请求,script中的js文件外层同步代码,文件操作,定时器,所有的事件处理,数据请求
微任务:Promise.then.catch,Proxy,async/await
JavaScript事件循环执行机制
Js的事件循环执就是Event-loop,是javascript为解决异步编程的一种机制。
1.进入到script标签,就进入了第一次事件循环
2.遇到同步代码立即执行
3.遇到宏任务,放到宏任务队列中
4.遇到微任务,放到微任务队列中
5.执行完所有同步代码,执行微任务代码
6.微任务代码执行完毕,本次队列清空
7.寻找下一个宏任务,重复步骤一,以此反复直到清空所有宏任务,这种不断重复的执行机制就叫事件循环。
Vue双向数据绑定怎么实现的?
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的 Vue2是采用Object.defineProperty劫持setter和getter数据变化发布消息给订阅者触发相应的回调来渲染视图。(也就是说数据和视图同步,数据变化视图变化,视图变化数据也随之变化。)
Vue3是采用Proxy劫持整个对象,而不是对象中的某个属性,Proxy的功能更强大,可以直接监听数组变化,还可以阻止对象上的默认行为。
为什么只对对象劫持,而要对数组进行方法重写?
数组的元素大概率是成百上千的,所以对数组下标进行劫持的话会非常消耗性能。Vue通过对数组原型上方法的重写,实现数组的响应式
Vue.set方法的原理?
Vue.set(target, key, value)
第一步:判断target是数组的话,则调用target.splice(key, 1, value)
第二步:判断target是对象的话,再判断传入的key是否已存在target中
是:直接target[key] = value
否:调用defineReactive(target, key, val)进行响应式处理
Vue.delete方法的原理?
Vue.delete(target, key) 第一步:判断target是否为数组,是的话调用target.splice(key, 1)
第二步:判断target是对象的话,调用delete关键字删除属性,并调用__ob__.dep.notify进行更新通知
nextTick的原理?
维护一个数组,每次调用时讲回调函数压入这个数组,然后优先选择微任务,在微任务回调中去执行数组中的所有回调,同时维护一个布尔值,确保每一次队列进行一次执行数组所有回调
计算属性中methods和computed哪个好?
computed比较好,computed有缓存机制,可以节省性能。而method则每次更新都会重新计算,不考虑缓存
自定义v-model
export default: {
model: {
event: 'change',
prop: 'checked'
}
}
动态指令和参数如何使用
<aButton @[someEvent]="handleSomeEvent()" :[someProps]="1000" />
Vue的el属性和$mount优先级
如果同时存在的话 el>$mount
props怎么自定义验证
props: {
num: {
default: 1,
validator: function (value) {
// 返回值为false则验证不通过,报错
return [1, 2, 3, 4, 5 ].indexOf(value) !== -1
}
}
}
}
如果子组件改变props里面的数据会发生什么?
基础类型:如果父传给子的是基础类型,修改则会报错 引用类型:如果父传给子的是引用类型,修改属性则会同时修改父组件的数据
插槽slot的理解
插槽就是一个占位符,将定义的内容展示出来,自定义的组件如果写内容是不会显示出来的,所以要用slot插槽来解决这个问题 分为三种,匿名插槽,具名插槽,作用域插槽
1.匿名插槽也是默认的,一个组件只有一个,没有指定name时默认展示这个插槽
2.具名插槽带有具体名字的在slot中定义name一个组件可以出现多个
3.作用域插槽和匿名,具名插槽类似只是可以传递数据给父组件,让父组件收到数据决定如何渲染该插槽。