Vue面试题

本文列举了Vue.js面试中常见的技术点,包括闭包的概念及其作用,防抖和节流的策略,Vue组件中的data为何使用函数,JavaScript的数据类型,null与undefined的区别,堆栈内存的运作机制,变量声明的var、let、const差异,解构赋值的示例,以及Promise、MVVM模式、v-model原理等核心概念。此外,还讨论了Vue的v-if与v-show、v-for与key的使用,以及组件间通信、事件总线、跨域解决方案和Git命令等开发实践。
摘要由CSDN通过智能技术生成

Vue面试题

js闭包:

能够读取其他函数内部变量的函数

  • 可以延长变量的生命周期 可以创建私有的环境

  • 将变量始终保存在内存中 可以封装对象的私有属性和方法

  • 坏处是消耗内存、内存溢出

防抖和节流

  • 防抖:触发事件后,在n秒内,事件只执行一次;n秒内再次触发,时间重新计算(下拉触底加载下一页)
  • 节流:连续发生的事件在n秒内,只执行一次(搜索查询)

vue中的data为什么是一个函数

  • 为了保证组件的独立性和可复用性,如果 data 是个函数的话,每复用一次组件就会返回新的 data,类似于给每个组件实例创建一个私有的数据空间,保护各自的数据互不影响

Js的数据类型

  • ES5的5种:*Null,undefined,Boolean,Number,String, ES6新增:Symbol表示独一无二的值 ES10新增:BigInt 表示任意大的整数*

null和undefined的区别

  • 在 if 语句中 null 和 undefined 都会转为false两者用相等运算符比较也是相等;首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
  • undefined 代表的含义是未定义;null 代表的含义是空对象

数据类型存储以及堆栈内存是什么

  • 基本数据类型**:**直接存储在栈内存中,占据空间小,大小固定,属于被频繁使用的数据。
  • 引用数据:类型将指针存在栈中,将值存在堆中。 当我们把对象值赋值给另外一个变量时,复制的是对象的指针,指向同一块内存地址

堆(heap)和栈(stack)有什么区别存储机制

栈: 是一种连续储存的数据结构,具有先进后出后进先出的性质

堆: 是一种非连续的树形储存数据结构,具有队列优先,先进先出

var let const区别

  • var: 存在变量提升;存在变量覆盖,已经被定义且赋值的变量,如果再次被赋值,则以后一次值为准;没有块级作用域;
  • const:定义的是常量,声明之后必须赋值;定义的值不能去修改,否则报错;有块级作用域;不存在变量提升和变量覆盖;对于数组和对象的元素修改,不算做对常量的修改,不会报错。
  • let: 有块级作用域;不存在变量提升和变量覆盖;let不允许在相同的作用域中重复声明,注意是相同作用域,不同作用域重复声明不会报错

解构赋值

  • let a=1;let b=2 交换变量 [a,b]=[b,a]

es6去重

  • let item = […new Set(arr)]

Promise面试题

  • promise的构造函数是同步执行的,当new Promise的一瞬间,1,2 就立刻被执行,而 .then方法是异步执行的,当执行完1和2之后,会执行输出4,最后执行输出3

MVC和MVVM

  • MVC:M(model数据)、V(view视图),C(controlle控制器)缺点是前后端无法独立开发,必须等后端接口做好了才可以往下走;前端没有自己的数据中心,太过依赖后台

  • MVVM:M(model数据)、V(view视图)、VM(viewModel控制数据的改变和控制视图)
    html部分相当于View层,可以看到这里的View通过通过模板语法来声明式的将数据渲染进DOM元素,当ViewModel对Model进行更新时,通过数据绑定更新到View。 Vue实例中的data相当于Model层,而ViewModel层的核心是Vue中的双向数据绑定,即Model变化时VIew可以实时更新,View变化也能让Model发生变化。

  • MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变

v-model原理

  • 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调从而达到数据和视图同步。

vue中的data

  • 实际上就是一个闭包,因为vue是单页面应用,是由很多组件构成,每一个组件中都有一个data,所以通过闭包给每一个组件创建了一个私有的作用域,这样就不会相互影响。

v-if和v-show

  • v-if是通过添加和删除元素进行显示或者隐藏
  • v-show是通过操作DOM修改display样式来修改元素的显示和隐藏

v-for为什么有key

  • key可以提高虚拟DOM的更新效率;key 只能是字符串或者number,其他类型不可以

  • key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新的虚拟DOM】与【旧的虚拟DOM】差异比较

  • 旧虚拟DOM找到了与新虚拟DOM相同的key:

    若虚拟DOM中内容没变,直接使用之前的真实DOM

    若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

用index作为key可能会引发的问题

  • 若对数据进行:逆序添加、逆序删除等破坏顺序的操作,会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
  • 如果结构中还包含输入类的DOM,会产生错误的DOM更新 ==> 界面有问题

打包后dist目录过大

  • dist打包生成的文件中有 .map 文件,可以删除。在 vue.config.js文件中配置:productionSourceMap: false
  • 组价和路由使用懒加载、按需引入等
  • 对于文件和图片进行压缩。

watch和computed的区别

  • computed能完成的功能,watch都可以完成

    watch能完成的小功能,computed不一定能完成。(watch可以进行异步操作)

  • 所有被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象

  • 所有不被vue管理的函数(定时器的回调、ajax的回调、promise的回调等),最好写成箭头函数,这样this的指向才是vm或组件实例对象

vue组件之间的数据传递

  • 父→子

    通过给子组件身上绑定自定义属性,然后再子组件里使用props属性来接收即可

  • 子→父

    通过父组件给子组件传递函数类型的props实现:子组件给父组件传递数据;通过父组件给子组件绑定一个自定义事件实现:子组件给父组件传递数据(子组件$emit);通过父组件给子组件绑定一个自定义事件实现:使用ref实现

全局事件总线

  • main.js:将全局事件bus,挂载到Vue的原型上,这样所有的组件都可以使用

消息订阅与发布

  • 一种组件间的通信方式,适用于任意组件间通信。

跨域

  • webpack 里的proxy
  • 配置多个域名在map中 只有配置过的允许跨域
  • jsonp(需要后端支持)

git命令

  • git init 初始化git仓库
  • git add 文件列表 追踪文件
  • git commit -m 提交信息 向仓库中提交代码
  • git log 查看提交记录
  • git status 查看文件状态

get与post区别

  • get是从服务器上获取数据,post是向服务器传送数据。
  • post比get安全,因为数据在地址栏上不可见。
  • get使用url、cookie传参

cookie、localStorage、sessionStorage

  • sessionStorage:仅在当前浏览器窗口关闭之前有效
  • localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据;
  • cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
  • sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;
  • localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在
  • 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在

async和await

  • async是来定义函数的,定义异步函数,打印函数名可以得到一个promise对象,言外之意可以通过这个 函数名称.then 这个方法
  • async 内部实现,有返回值 成功返回promise.resolve() ,出错返回promise.reject() 返回值用catch捕获
  • await 后面跟的是任意表达式,一般使用promise的表达式
  • async和await 属于es7语法
  • promise es6语法,promise中包含catch,async需要自己定义catch

setTimeout时间为0以及误差的原因

  • setTimeout,如果时间为0,则会立即插入队列,不是立即执行,等待前面的代码执行完毕。

js的数据类型

  • 基本数据类型:Boolean、Number、String、Null、Undefined
  • 复杂数据类型: Object、Array、Function、Date

js变量提升

  • 在js中,变量和函数的声明会被提升到最顶部执行

    函数提升高于变量的提升

    函数内部如果用var声明了相同名称的外部变量,A函数将不再向上寻找

    匿名函数不会提升

this指向

  • this总是指向函数的直接调用者。

    如果有new关键字,this指向new出来的对象

    在事件中,this指向触发这个事件的对象

普通函数和箭头函数区别

  • 箭头函数没有原型,原型是undefined
  • 箭头函数this指向全局对象,而函数指向引用对象
  • call,apply,bind方法改变不了箭头函数的指向

slot插槽

  • slot插槽,可以理解为slot在组件模板中提前占据了位置,当复用组件时,使用相关的slot标签时,标签里的内容就会自动替换组件模板中对应slot标签的位置,作为承载分发内容的出口

  • 主要作用是:复用和扩展组件,做一些定制化组件的处理

map和forEach

  • forEach方法,是最基本的方法,遍历和循环。默认有3个参数:分别是遍历的每一个元素item,遍历的索引index,遍历的数组array

    map方法,和foreach一致,不同的是会返回一个新的数组,所以callback需要有return返回值,如果没有会返回undefined

箭头函数和普通函数区别

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象

    不可以当作构造函数,也就是说不可以使用new命令,否则会报错

    不可以使用arguments对象,该对象在函数体内不存在,如果要用可以使用Rest参数代替

    不可以使用yield命令,因此箭头函数不能用作Generator函数

es6新增

  • 新增模版字符串

    箭头函数

    增加let、const来声明变量

    for-of用来遍历数据-例如数组中的值

    解构赋值

    新增简单数据类型Symbol,独一无二的,不会与其他属性名冲突

    将Promise对象纳入规范,提供了原生的Promise对象

attribute 和 property 的区别

  • attribute 是 dom 元素在文档中作为 html 标签拥有的属性
  • property 就是 dom 元素在 js 中作为对象拥有的属性。
  • 对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的
  • 但是对于自定义的属性来说,他们是不同步的

内存泄漏(堆内存无法释放)原因

  • 全局变量
  • dom 清空时,还存在引用
  • 定时器未清除
  • 子元素存在引起的内存泄露

script 引入方式

  • <script defer> : 异步加载,元素解析完成后执行
  • <script async> : 异步加载,但执行时会阻塞元素渲染

JS垃圾回收机制是怎样的

  • 垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉它所指向的内存。

  • 标记清除:大部分浏览器使用这种垃圾回收,当变量进入执行环境(声明变量)的时候,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,将其再度标记,随之进行删除。

    引用计数:这种方式常常会引起内存的泄露,主要存在于低版本的浏览器。它的机制就是跟踪某一个值得引用次数,当声明一个变量并且将一个引用类型赋值给变量得时候引用次数加1,当这个变量指向其他一个时引用次数减1,当为0时出发回收机制进行回收。

逐进增强和优雅降级

  • 逐进增强

    针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高版本浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

  • 优雅降级
    一开始就构建完整的功能,然后再针对低版本浏览器进行兼容

让CSS只在当前组件中起作用

  • scoped

<keep-alive></keep-alive>的作用是什么

  • 主要是用于需要频繁切换的组件时进行缓存,不需要重新渲染页面

如何获取dom

  • 给dom元素加ref=‘refname’,然后通过this.$refs.refname进行获取dom元素

vue-loader是什么

  • vue文件的一个加载器,将template/js/style转换为js模块

为什么用key

  • 给每个dom元素加上key作为唯一标识 ,diff算法可以正确的识别这个节点,使页面渲染更加迅速

$nextTick的使用

  • 在data()中的修改后,页面中无法获取data修改后的数据,使用$nextTick时,当data中的数据修改后,可以实时的渲染页面

单页面应用和多页面应用区别及缺点

  • 单页面应用(SPA),通俗的说就是指只有一个主页面的应用,浏览器一开始就加载所有的js、html、css。所有的页面内容都包含在这个主页面中。但在写的时候,还是分开写,然后再加护的时候有路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多用于pc端。

  • 多页面(MPA),就是一个应用中有多个页面,页面跳转时是整页刷新

  • 单页面的优点:用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离,页面效果会比较酷炫

  • 单页面缺点:不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。初次加载时耗时多;页面复杂度提高很多。

vue和jQuery的区别

  • jQuery是使用选择器( )选取 D O M 对象,对其进行赋值、取值、事件绑定等操作,其实和原生的 H T M L 的区别只在于可以更方便的选取和操作 D O M 对象,而数据和界面是在一起的。比如需要获取 l a b e l 标签的内容: )选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容: )选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:(“lable”).val();,它还是依赖DOM元素的值。
  • Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。

vue获取数据在一般在哪个周期函数

  • created
    beforeMount
    mounted

vue生命周期

vuex有哪几种属性

  • 有五种,State、 Getter、Mutation 、Action、 Module
    state: 基本数据(数据源存放地)
    getters: 从基本数据派生出来的数据
    mutations : 提交更改数据的方法,同步!
    actions : 像一个装饰器,包裹mutations,使之可以异步。
    modules : 模块化Vuex

vue路由跳转

  • 声明式导航router-link
  • this.$router.push():query传参;不带参数;params传参;直接path
  • query类似 get,跳转之后页面 url后面会拼接参数,类似?id=1。
    非重要性的可以这样传,密码之类还是用params,刷新页面id还在。
    params类似 post,跳转之后页面 url后面不会拼接参数。

如何解决数据层级结构太深的问题

如以下代码: span 'v-text="a.b.c.d">, 可以使用vm.$set手动定义一层数据: vm.$set("demo",a.b.c.d)

Vue.js页面闪烁

Vue. js提供了一个v-cloak指令,该指令一直保持在元素上,直到关联实例结束编译。当和CSS一起使用时,这个指令可以隐藏未编译的标签,直到实例编译结束。

$route$router的区别

  • $route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
  • $router是“路由实例”对象包括了路由的跳转方法,钩子函数等

Vue.set 方法原理

在两种情况下修改 Vue 是不会触发视图更新的。

在实例创建之后添加新的属性到实例上(给响应式对象新增属性)

直接更改数组下标来修改数组的值。

### CSS选择器以及优先级的理解

ID选择器、类选择器、标签选择器、属性选择器、伪类选择器、后代选择器

!important > 内联样式 > ID选择器 > 类选择器 > (标签选择器、伪类选择器、属性选择器)

安全性问题

  • XSS 攻击: 注入恶意代码
    • cookie 设置 httpOnly
    • 转义页面上的输入内容和输出内容
  • CSRF : 跨站请求伪造,防护:
    • get 不修改数据
    • 不被第三方网站访问到用户的 cookie
    • 设置白名单,不被第三方网站请求
    • 请求校验

浏览器内核

HTML和HTML5有什么区别

深拷贝和浅拷贝

深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。

1.浅拷贝:

将原对象或原数组的引用直接赋给新对象,新数组,新对象只是对原对象的一个引用,而不复制对象本身,新旧对象还是共享同一块内存

如果属性是一个基本数据类型,拷贝就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,

2.深拷贝:

创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

深拷贝就是把一个对象,从内存中完整的拷贝出来,从堆内存中开辟了新区域,用来存新对象,并且修改新对象不会影响原对象

3、赋值:

当我们把一个对象赋值给一个新的变量时,赋的是该对象在栈中的内存地址,而不是堆中的数据。也就是两个对象

立即执行函数

立即执行函数会形成一个单独的作用域,我们可以封装一些临时变量或者局部变量,避免污染全局变量。

arguments

arguments 当我们不知道有多少个参数传进来的时候就用 arguments 来接收,是一个类似于数组的对象,他有length属性,可以arguments[ i ]来访问对象中的元素, 但是它不能用数组的一些方法。

call、apply、bind

都是来改变this指向和函数的调⽤,实际上call与apply的功能是相同的,只是两者的传参方式不一样,

call⽅法跟的是⼀个参数列表,

apply跟⼀个 数组作为参数,call⽅法和apply使⽤后就直接调⽤

bind 传参后不会立即执行,而是返回一个改变了this指向的函数,这个函数可以继续传参,且执行,需要类似于bind()()两个括号才能调⽤。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值