[直接收集]前端VUE高级面试问题(1)
2025-04-08 07:02:27发布 浏览24次 信息编号:206408
平台友情提醒:凡是以各种理由向你收取费用,均有骗子嫌疑,请提高警惕,不要轻易支付。
[直接收集]前端VUE高级面试问题(1)
1。谈论VUE的动态许可绑定渲染列表(权限列表渲染)
首先,请求服务器获取当前用户的权限数据,例如请求此。$ http.get(“/list”);
获得权限数据后,使用列表中的V-IF V-IF-IF-ELSE组合显示不同的内容
<template>
<div>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页el-breadcrumb-item>
<el-breadcrumb-item>权限管理el-breadcrumb-item>
<el-breadcrumb-item>权限列表el-breadcrumb-item>
el-breadcrumb>
<el-card>
<el-table :data="rightsList" border stripe>
<el-table-column type="index" label="#">el-table-column>
<el-table-column label="权限名称" prop="authName">el-table-column>
<el-table-column label="路径" prop="path">el-table-column>
<el-table-column label="权限等级" prop="level">
<template slot-scope="scope">
<el-tag v-if="scope.row.level === '0'">一级el-tag>
<el-tag type="success" v-else-if="scope.row.level === '1'">二级el-tag>
<el-tag type="danger" v-else>三级el-tag>
template>
el-table-column>
el-table>
el-card>
div>
template>
<script>
export default {
data() {
return {
// 权限列表
rightsList: []
};
},
created() {
this.getRightsList();
},
methods: {
async getRightsList() {
//获取权限列表数据
const { data: res } = await this.$http.get("rights/list");
if (res.meta.status !== 200) {
return this.$message.error("获取权限列表失败!");
}
this.rightsList = res.data;
}
}
};
script>
<style lang='less' scoped>
style>
2。VUE中使用了哪种设计模型?
它属于发布订阅模式。它使用两种方法的组合来递归劫持数据。然后,该属性是通过手表类订阅的。 DEP类用于解次配合。当数据更改时,首先触发数据的集合方法,然后将DEP触发通知以更新视图。
3。谈论VUE操作的真正DOM性能瓶颈
VUE性能瓶颈的几种情况
当一次渲染大量数据时,当存在大量数据并且具有复杂类型时,它将导致数据劫持时间和VUE呈现时间更长。 JS的持续执行时间将太长,这将导致页面无法互动很长时间,并且渲染时间太慢,因此用户的互动和反馈将太长。
优化解决方案:此方法可用于分割数据并分批渲染,从而减少JS的连续运行时间并加快渲染时间。总运行时间用于交换渲染时间。用户可以快速获得反馈,并且由于JS运行时间太长,他们将无法与页面互动。
当页面中有大量数据时,只有一小部分会导致页面口吃,因为VUE的更新是在组件的粒度上更新的。只要修改当前组件中使用的数据,该组件将整体更新,从而导致大量时间浪费。
优化解决方案:将不同的模块分为不同的组件,从而有效地减少了虚拟DOM的过长差异操作时间的问题。例如,将一个单独数据的模块和另一个组件放在另一个数据中。由于Vue用该组件更新为粒度,因此修改其他组件不会导致表重新降低,并且页面响应速度将增加数百次。
更新动态插槽范围或静态插槽
用插槽范围替换这两种操作方法也可以提高性能,因为在使用插槽范围后,插槽内容将被封装到一个函数中,并由子组件而不是组件渲染
4。如何获取DOM,操作DOM和更新VUE中的DOM
如何获得DOM?获得DOM的一种特殊方法是在VUE中提供的,即将REF属性添加到DOM中,然后可以通过此获得DOM元素。$ refs。姓名。
如何操作和更新DOM?您可以通过Refs获得相应的真实DOM。名称,然后您可以使用本机JS进行操作和更新。当然,VUE框架本身不需要DOM操作。通过修改相应的数据并与说明和模板语法合作,可以轻松地操作和更新DOM。
5。vue中双向数据绑定的原理是什么
在vue2.x中,双向数据绑定是通过数据劫持与发布和订阅模式相结合的,即数据和视图的同步,数据更改,查看更改以及数据也会更改。核心:关于vue双向数据结合,其核心是。()方法。
Vue3.x使用ES6语法代理对象实现。
()的缺点:
它只能收听对象(),无法听取数组中的更改,并且不能触发推动,弹出,移动,,
您必须穿越对象的每个属性
您只能劫持当前对象属性。如果您想深入劫持,则必须深处遍历嵌套的对象。
代理人:
代理可以直接收听对象而不是属性。
代理可以直接收听数组中的更改。
代理具有多达13种拦截方法,不限于 申请,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,, ,,, ,,,,,,,,,,,,,,,, ,, ,, ,, ,, ,, ,,, ,, ,, ,, ,, ,,,,,,,,,,,,,,, ,, ,,, ,,,,,,,,,,,,,,,, ,, ,, ,, ,, ,, ,,, ,, ,, ,, ,, ,,,,,,,,,,,,,,,
代理返回一个新对象,我们只能操作新对象以实现目的,并且只能穿越对象属性并直接修改它们。
作为新标准,代理将受到浏览器制造商的持续性能优化,这是传奇新标准的性能股息。
let arr = [];
let proxy = new Proxy(arr, {
get: function(obj, prop){
return obj[prop];
},
set: function(obj, prop, value){
obj[prop] = value; //可以被监听到变化
return true;
}
});
setTimeout(()=>{
proxy.push(1);
}, 2000)
6。什么是MVVM框架
MVVM是模型视图的缩写。它本质上是MVC(Model-View-)的改进版本。在开发过程中,由于需求的变化或增加,项目的复杂性变得越来越高,代码的数量变得更大。目前,我们会发现MVC很难维护,尤其是控制层非常厚,很难维护。
因此,有些人想从它们中提取数据和逻辑处理零件,并使用特殊对象管理它们,而此对象是。它是由前端开发人员生成和维护的视图数据层。在此层上,前端开发人员将转换从后端获得的模型数据,并执行辅助封装,以生成符合视图层使用的期望的视图数据模型。
由于实现了双向绑定,因此内容将实时显示在视图层中,这是令人兴奋的,因为前端开发人员不再需要以一种效率低下且麻烦的方式来更新视图。 MVVM框架已经使最肮脏,累人的部分成为了。我们开发人员只需要处理和维护它们,更新数据视图将自动进行相应的更新,从而真正实现数据驱动的开发。
7。谈论Vue的令牌存储
当前端和后端完全分开时,在VUE项目中实施令牌验证的一般思想如下:
1。首次登录时,前端会调整后端的登录接口并发送用户名和密码。
2。当后端收到请求时,请验证用户名和密码。如果验证成功,请将令牌返回到前端。
3。将令牌放在前端,将令牌存储在和Vuex中,然后跳到路由页面
4。每次前端跳到路线时,都会确定其中是否有令牌。如果没有,它将跳到登录页面。如果是这样,它将跳到相应的路由页面。
5。每次调整后端接口时,都必须将令牌添加到请求标头中。
6。后端确定请求标题中是否有令牌。如果有令牌,请获取令牌并验证令牌。如果验证成功,将返回数据。如果验证失败(例如,令牌到期),它将返回401。如果请求标头中没有令牌,则将返回401。
7。如果前端获取状态代码401,请清除令牌信息并跳到登录页面
8。您知道功能吗?告诉我我对它的理解,它是什么以及如何使用它
当您设置VM时。 ='new',该组件将不会立即放置。刷新队列时,将在下一个事件循环“ tick”中更新组件。在大多数情况下,我们不需要关心此过程,但是如果您想根据更新的DOM状态做某事,可能会有些棘手。虽然Vue.js通常会鼓励开发人员以“数据驱动”的方式思考以避免与DOM直接接触,有时我们必须这样做。为了等待VUE在数据更改后完成DOM的更新,VUE。()可以在数据更改后立即使用。这样,在完成DOM更新后,将调用回调函数。例如:
<div id="example">{{message}}div>
var vm = new Vue({
el: '#example',
data: {
message: 'old message'
}
})
vm.message = 'new message' // 更改数据
vm.$el.textContent // 'old message'
Vue.nextTick(function () {
vm.$el.textContent // 'new message'
})
9。和差异
首先,在更新DOM时,VUE是异步执行的,这意味着数据更改,并且DOM不会立即更改。那么,我们怎么知道DOM何时会改变呢?换句话说,您如何知道异步后的触发时机?
您可以使用该方法。在源代码中,该方法首先监视它是否具有.THE并使用它进行监视。如果当前的环境不支持它,则将降级。如果不支持它,则将降级。如果不支持它,则将使用它(FN,0)。
因此,差异的摘要是:我将尝试使用这些技术首先监视,如果不支持它们,将使用它们
10.为什么在VUE中使用虚拟DOM,而不是操作真实的DOM
首先,当我们使用JS/时,我们不可避免地操作了很多DOM,并且DOM的更改会导致反流或重新绘制,从而降低页面渲染性能。那么如何减少DOM的操作?目前,虚拟DOM应用程序诞生了,因此虚拟DOM的主要目的是减少频繁操作引起的性能问题,并导致反流和重新绘制!
虚拟DOM(DOM)本质上是开始的JS对象。当数据更改时,我们不会直接操作真实的DOM。因为它非常昂贵,所以当我们操作此JS对象时,我们不会触发大量的回流和重新粉刷操作。此外,DIFF算法可以找到两个虚拟DOM之间更改的零件,以最少更新真实的DOM,而不是经常操作DOM,因此性能得到了极大的改进。
虚拟DOM具有另一个优势,可以将其渲染到DOM以外的其他平台,并实现高级功能,例如SSR和同构渲染。此功能由Weex等框架应用。
11。如何传递VUE的值
父会将值传递给子组件,并可以使用Prop方法。
孩子将价值传递给父组件,并可以使用自定义事件$ emit方法。
可以使用多级组件传输值 /
使用VUEX状态管理传递无关的组件值
12.谈论Vue中的父子交流
父 - > sub:通过道具将数据传递给儿童组件,以及子组件通过道具属性接收。
<blog-post title="My journey with Vue">blog-post>
Vue.component('blog-post', {
props: ['title'],
template: '{{ title }}
' //获取父组件的值
})
儿童 - >父级:父组件自定义事件,孩子组件使用$ emit即可完成。
<blog-post v-on:enlarge-text="postFontSize += $event">blog-post>
Vue.component('blog-post', {
props: ['title'],
template: '<h3 v-on:click="$emit('enlarge-text', 0.1)">{{ title }}h3>'
})
13.谈论如何实施VUE组件的通信和价值传输方法(相同答案的两个问题是不同的)
这类问题 首先分类 表明了解的比较多 具体就没说完 或者漏了 面试官也不会计较很多
组件通信的四大类 父与子 子与父 子与子 跨层级
在细说各种方式 加入自己的理解
1、props和$emit
父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件
2、$attrs和$listeners
3、中央事件总线 bus
上面两种方式处理的都是父子组件之间的数据传递,而如果两个组件不是父子关系呢?这种情况下可以使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。
4、provide和inject
父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
5、v-model
父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值
6、$parent和$children
7、boradcast和dispatch
8、vuex处理组件之间的数据交互 如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。
14.谈论关键价值在VUE中的作用
关于这个可以的key的作用 首先表明 key 不是一定要有的 不写可以代码也可以跑 但是建议加上
然后指出可以用的地方 key在v-for循环可以用用 在表单元素中也可以用key 减少缓存
一般说key 只要说配合v-for的使用
key是为Vue中的vnode标记的唯一id,通过这个key,我们的diff操作可以更准确、更快速
diff算法的过程中,先会进行新旧节点的首尾交叉对比,当无法匹配的时候会用新节点的key与旧节点进行比对,然后超出差异能讲清楚diff算法就继续讲
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)
讲完以后 还要补充一点自己的看法
建议使用主键比如id
15。谈论VUE中的虚拟DOM和差异算法
Virtual DOM 其实就是一棵以 JavaScript 对象( VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实的DOM上
下面就是一个真实DOM映射到虚拟DOM的例子:
- Item 1
- Item 2
- Item 3
var element = {
tagName: 'ul', // 节点标签名
props: { // DOM的属性,用一个对象存储键值对
id: 'list'
},
children: [ // 该节点的子节点
{tagName: 'li', props: {class: 'item'}, children: ["Item 1"]},
{tagName: 'li', props: {class: 'item'}, children: ["Item 2"]},
{tagName: 'li', props: {class: 'item'}, children: ["Item 3"]},
]
}
在补充点虚拟DOM的好处
具备跨平台的优势
由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。
操作原生DOM慢,js运行效率高。我们可以将DOM对比操作放在JS层,提高效率。
因为DOM操作的执行速度远不如Javascript的运算速度快,因此,把大量的DOM操作搬运到Javascript中,运用patching算法来计算出真正需要更新的节点,最大限度地减少DOM操作,从而显著提高性能。
Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘,既然硬盘这么慢,我们就在它们之间加个缓存:既然 DOM 这么慢,我们就在它们 JS 和 DOM 之间加个缓存。CPU(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)
提升渲染性能
Virtual DOM的优势不在于单次的操作,而是在大量、频繁的数据更新下,能够对视图进行合理、高效的更新。
diff算法
vdom因为是纯粹的JS对象,所以操作它会很高效,但是vdom的变更最终会转换成DOM操作,为了实现高效的DOM操作,一套高效的虚拟DOM diff算法显得很有必要
diff算法包括一下几个步骤:
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文
档当中
当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较(diff),记录两棵树差异
把2所记录的差异应用到步骤1所构建的真正的DOM树上(patch),视图就更新了
diff算法是通过同层的树节点进行比较而非对树进行逐层搜索遍历的方式,所以时间复杂度只有O(n),是一种相当高效的算法
实施虚拟DOM的过程
16。您了解VUE3.0吗?您认为Vue3.0很好吗?有什么好处?
这种问题是开放的,而且交谈更多,这是可以的。您可以谈论差异或新知识点。
例如,常用的API非常有用
参考,托里夫,以伊斯
function useUpdBoxStyle() {
const el = ref(null)
const updateStyle = color => {
el.value.style.color = color
}
return [el, updateStyle]
}
,,,,
function useObj() {
const obj = { a: 1, b: { c: { d: 2 }}}
const obj1 = ref(obj)
const obj2 = shallowRef(obj)
// console.log('obj1', obj1)
// console.log('obj2', obj2)
const changeObj = (obj, newD) => {
本文链接:https://chahouw.com/detail/id/206408.html
提醒:请联系我时一定说明是从茶后生活网上看到的!