vue常见面试题库 长期更新

友情提示:小白购买需注意,程序不包安装,无技术支持,因资源可复制性,不接受任何理由退款。

本站资源仅供学习测试!不得用于非法用途!商业用途与本站无关!资源自行测试不做任何保证!

本站资源默认解压密码:www.itxen.cn或者自行在下载页面查询

4290d479a194

 

 ★★★如何监测动态路由的变化

可以通过watch方法来对$route进行监听,或者通过导航守卫的钩子函数beforeRouteUpdate来监听它的变化。

★★★ 对MVC,MVP,MVVM的理解

mvc 和 mvvm 其实区别并不大。都是一种设计思想。主要就是 mvc 中 Controller 演变成 mvvm 中的 viewModel。mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当 Model 频繁发生变化,开发者需要主动更新到 View 。

MVVM 是 Model-View-ViewModel 的缩写。mvvm 是一种设计思想。1:Model 层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑;View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来,ViewModel 是一个同步 View 和 Model 的对象。2:在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,而 Model 数据的变化也会立即反应到 View 上。3:ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而 View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

★★ 说一下$root,$parent,$refs

$root,和$parent都能访问父组件的属性和方法,区别在于如果存在多级子组件,通过parent 访问得到的是它最近一级的父组件,通过root 访问得到的是根父组件。通过在子组件标签定义 ref 属性,在父组件中可以使用$refs 访问子组件实例。

★★★★★ 你知道Vue响应式数据原理吗?Proxy 与 Object.defineProperty 优劣对比?

// 响应式原理vue的响应式实现主要是利用了Object.defineProperty的方法里面的setter 与getter方法的观察者模式来实现。在组件初始化时会给每一个data属性注册getter和setter,然后再new 一个自己的Watcher对象,此时watcher会立即调用组件的render函数去生成虚拟DOM。在调用render的时候,就会需要用到data的属性值,此时会触发getter函数,将当前的Watcher函数注册进sub里。当data属性发生改变之后,就会遍历sub里所有的watcher对象,通知它们去重新渲染组件。// proxy的优势如下:Proxy 可以直接监听对象而非属性,可以直接监听数组的变化;Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;// Object.defineProperty 的优势如下:兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill(垫片)来弥补

 ★★★★ Composition API 的出现带来哪些新的开发体验,为啥需要这个?

1:在Compostion API 中时根据逻辑相关组织代码的,提高可读性和可维护性,类似于react的hook写法。2:更好的重用逻辑代码,在Options API中通过MIxins重用逻辑代码,容易发生命名冲突且关系不清。3:解决在生命周期函数经常包含不相关的逻辑,但又不得不把相关逻辑分离到了几个不同方法中的问题,如在mounted中设置定时器,但需要在destroyed中来清除定时器,将同一功能的代码拆分到不同的位置,造成后期代码维护的困难。

★★★ 什么情况下使用 Vuex

如果应用够简单,最好不要使用 Vuex,一个简单的 store 模式即可,需要构建一个中大型单页应用时,使用Vuex能更好地在组件外部管理状态

★★★ Vuex可以直接修改state的值吗?

可以直接修改,但是极其不推荐,state的修改必须在mutation来修改,否则无法被devtool所监测,无法监测数据的来源,无法保存状态快照,也就无法实现时间漫游/回滚之类的操作。

★★★★ 为什么Vuex的mutation不能做异步操作

Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,否则无法被devtools所监测。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

 ★★★ v-model和vuex有冲突吗?

// 答案:

 ★★★ 解释单向数据流和双向数据绑定

对于 Vue 来说,组件之间的数据传递具有单向数据流这样的特性称为单向数据流,单向数据流(Unidirectional data flow)方式使用一个上传数据流和一个下传数据流进行双向数据通信,两个数据流之间相互独立,单向数据流指只能从一个方向来修改状态。

而双向数据绑定即为当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化,两个数据流之间互为影响。

★★ Vue 如何去除url中的

#将路由模式改为history

★★★★★ vue-router 路由实现原理

1.路由就是用来解析URL实现不同页面之间的跳转
vue-router通过hash与History interface两种方式实现前端路由,更新视图但不重新请求页面”是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有两种方式

const routes = [
{
path: '/',
redirect: '/recommend'
},
{
path: '/recommend',
component: () => import('../components/recommend/view.vue')
}
]
export default routes 

二、两种路由模式

1.hash模式:

在浏览器中符号的“#”,以及#后面的字符称之为hash,用window.location.hash读取;

特点:

hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,

hash不会重加载页面。

hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

import Vue from 'vue'
import Router from 'vue-router'
import routes from './routes'

Vue.use(Router)

export default new Router({
// mode: 'history',
routes
}) 

2.history模式

history采用HTML5的新特性;且提供了两个新方法:pushState(),

replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。

特点:

history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 地址后加上/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。

const router = new VueRouter({
mode: 'history',
routes: [...]
}) 

★★★ $route 和 $router 的区别

$route用来获取路由的信息的,它是路由信息的一个对象,里面包含路由的一些基本信息,包括name、meta、path、hash、query、params、fullPath、matched、redirectedFrom等。而$router主要是用来操作路由的,它是VueRouter的实例,包含了一些路由的跳转方法,钩子函数等。

★★ 对比 jQuery,Vue 有什么不同

jQuery 专注视图层,通过直接操作 DOM 去实现页面的一些逻辑渲染;Vue 专注于数据层,通过数据的双向绑定,最终表现在 DOM 层面,减少了 DOM 操作。Vue 使用了组件化思想,使得项目子集职责清晰,提高了开发效率,方便重复利用,便于协同开发

★★★ Vue 中怎么自定义指令

通过directive来自定义指令,自定义指令分为全局指令和局部指令,自定义指令也有几个的钩子函数,常用的有bind和update,当 bind 和 update 时触发相同行为,而不关心其它的钩子时可以简写。一个表达式可以使用多个过滤器。过滤器之间需要用管道符“|”隔开。其执行顺序从左往右。

 ★★★ Vue 中怎么自定义过滤器

通过filter来定义过滤器,过滤器分为全局和局部过滤器,过滤器的主体为一个普通的函数,来对数据进行处理,可以传递参数。当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用。

 ★★★ Vue 等单页面应用的优缺点

// 优点1单页应用的内容的改变不需要重新加载整个页面,web应用更具响应性和更令人着迷。2、单页应用没有页面之间的切换,就不会出现“白屏现象”,也不会出现假死并有“闪烁”现象3、单页应用相对服务器压力小,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍。4、良好的前后端分离。后端不再负责模板渲染、输出页面工作,后端API通用化,即同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端。// 缺点1、首次加载耗时比较多。2、SEO问题,不利于百度,360等搜索引擎收录。3、容易造成Css命名冲突。4、前进、后退、地址栏、书签等,都需要程序进行管理,页面的复杂度很高,需要一定的技能水平和开发成本高。

 ★★★ Vue-router 使用params与query传参有什么区别

// 用法上1:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。// 展示上2:query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示3:params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系。4:params、query不设置也可以传参,params不设置的时候,刷新页面或者返回参数会丢失

★★★ Vue中 keep-alive 的作用

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。一旦使用keepalive包裹组件,此时mouted,created等钩子函数只会在第一次进入组件时调用,当再次切换回来时将不会调用。此时如果我们还想在每次切换时做一些事情,就需要用到另外的周期函数,actived和deactived,这两个钩子函数只有被keepalive包裹后才会调用。

★★★ Vue如何实现单页面应用

通常的url 地址由以下内容构成:协议名 域名 端口号 路径 参数 哈希值,当哈希值改变,页面不会发生跳转,单页面应用就是利用了这一点,给window注册onhashchange事件,当哈希值改变时通过location.hash就能获得相应的哈希值,然后就能跳到相应的页面。

 ★★ Vue 生命周期通常使用哪些

常用的生命周期有,beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed

★★ Vue 深层次的组件怎么和父组件通讯

1、使用$attrs和$listeners

Vue.component('C', {
template: `
<div>
<p>我是C组件</p>
<input
type='text'
v-model='$attrs.msgc'
@input='$emit("getC", $attrs.msgc)'
/>
</div>
`})

Vue.component('B', { /**
给C组件绑定$attrs属性和$listeners事件,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的)
*/
template: `
<div>
<p>我是B组件</p>
<input
type='text'
v-model='mymsg1'
@input="$emit('getChild', mymsg1)"
/>
<C v-bind='$attrs' v-on='$listeners'/>
</div>
`,
props: ['msg1'],
data () { return {
mymsg1: this.msg1
}
}
})

Vue.component('A', {
template: `
<div id='app'>
<p>我是A组件</p>
<B
:msg1='msg1'
:msgc='msgc'
@getChild='getChild'
@getC='getC'
/>
</div>
`,
data () { return {
msg1: 'A',
msgc: 'hello c!'
}
},
methods: {
getChild (val) { console.log( val )
},
getC (val) { console.log( val )
}
}
})const app = new Vue({
el: '#app',
template: `
<A />
`})

★★★★★ Vue 响应式原理

1.观察者observer:首先通过观察者对data中的属性使用object.defineproperty劫持数据的getter和setter,通知订阅者,触发他的update方法,对视图进行更新

2.Compile:用来解析模板指令,并替换模板数据,初始化视图,初始化相应的订阅器

3.订阅者Watcher:订阅者接到通知后,调用update方法更新对应的视图

4.订阅器Dep:订阅者可能有多个,因此需要订阅器Dep来专门接收这些订阅者,并统一管理

但在vue3中抛弃了object.defineproperty方法,因为

1.Object.defineproperty无法监测对象属性的添加和删除、数组索引和长度的变更,因此vue重写了数组的push/pop/shift/unshift/splice/sort/reverse方法

2.Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历,这样很消耗性能

vue3中实现数据双向绑定的原理是数据代理,使用proxy实现。Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

★★★★ Vue proxy的原理

主要通过Proxy对对象进行绑定监听处理,通过new Map对对象的属性操作进行处理,将要执行的函数匹配到存到对应的prop上面,通过每次的访问触发get方法,进行存方法的操作,通过修改触发set的方法,此时执行回调监听的函数,这样达到修改数据和视图的

★★★ Vue $forceUpdate的原理

1、作用:

迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

2、内部原理:

Vue.prototype.$forceUpdate = function () {    const vm: Component = this
   if (vm._watcher) {
       vm._watcher.update()
   }
}
实例需要重新渲染是在依赖发生变化的时候会通知watcher,然后通知watcher来调用update方法,就是这么简单。

 ★★★ v-for key

key是为Vue中的vnode标记的唯一id,通过这个key,我们的diff操作可以更准确、更快速
diff算法的过程中,先会进行新旧节点的首尾交叉对比,当无法匹配的时候会用新节点的key与旧节点进行比对,然后超出差异.
diff程可以概括为:oldCh和newCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明oldCh和newCh至少有一个已经遍历完了,就会结束比较,这四种比较方式就是首、尾、旧尾新头、旧头新尾.

准确: 如果不加key,那么vue会选择复用节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产生一系列的bug. 快速: key的唯一性可以被Map数据结构充分利用,相比于遍历查找的时间复杂度O(n),Map的时间复杂度仅仅为O(1)

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容