vue 前端面试题

说说你对SPA单页面的理解,它的优缺点分别是什么?

SPA(single-page application,单页应用程序)。就是只有一个Web页面的应用,是加载单个HTML页面,并在用户与应用程序交互时动态更新该页面的Web应用程序。

优点:

  • 用户体验好,内容的改变不需要重新加载整个页面
  • 良好的前后端分离,分工更明确

缺点:

  • 不利于搜索引擎的抓取
  • 首次渲染速度相对较慢

v-show与v-if的区别

v-if 与 v-show 都能控制dom元素在页面的显示

v-if 相比 v-show 开销更大的(直接操作dom节点增加与删除)

如果需要非常频繁地切换,则使用 v-show 较好

如果在运行时条件很少改变,则使用 v-if 较好

Vue的生命周期

Vue的生命周期是指vue的实例从创建、运行、到销毁的整个过程。

创建期间的生命周期函数

  • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 属性和 methods方法
  • created:实例已经在内存中创建完成,此时data 和 methods已经创建好,但是还没有开始编译模板
  • beforeMount:此时已经完成了模板编译,但是还没有挂载到页面中
  • mounted:此时已经将编译好的模板,挂载到了页面指定的容器中显示

运行期间的生命周期函数

  • beforeUpdate:状态更新之前执行函数,此时 data 中的状态值是最新的,但是页面显示的数据还是旧的,因为此时还没有开始重新渲染 DOM 节点
  • updated:实例更新完毕之后调用此函数,此时 data 中的状态值和页面上显示的数据都已经完成了更新,页面已经被重新渲染好了
  • beforeDestroy:实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例
  • destroyed:实例销毁后调用,调用后,Vue实例指向的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

webpack打包的基本配置

  • yarn init -y,创建package.json,用来记录依赖包,之后就可以安装webpack依赖包
  • yarn add webpack webpack-cli -D,安装webpack依赖包,生成node_modules文件(-D表示只是开发中需要用的依赖,实际上线是不需要的)
  • 到package.json中配置script,“scripts”: {“build”:“webpack --config webpack.config.js”}
  • 新建一个webpack.config.js,配置webpack文件,entry(入口)、output(出口)、mode(模式)
  • 在index.js中引入多个js文件(require)
  • yarn build,最后执行webpack打包,多个js文件打包成一个js文件

为什么data属性是一个函数而不是一个对象?

  • 根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况
  • 组件实例对象data必须为函数,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染。
    采用函数的形式,initData时会将其作为工厂函数都会返回全新data对象

组件间的通信

  • 父组件通过 props 的方式向子组件传递数据,子组件设置 props 属性,定义接收父组件传递过来的参数。子组件可以通过 $emit 触发父组件的自定义事件
  • ref属性定义在父组件中 (写在子组件标签身上),就相当于给子组件取了一个名字。 this.$refs.child 就是 Child 组件的 Vue 实例,可以读取 Child 子组件的各种数据和执行方法
  • 通过 $parent 和 $children 可以访问组件的实例,其中 c h i l d r e n 是数组, children 是数组, children是数组,parent 是对象
  • 兄弟组件传值,创建一个中央事件总线EventBus,兄弟组件通过 e m i t 触发自定义事件, emit触发自定义事件, emit触发自定义事件,emit第二个参数为传递的数值,另一个兄弟组件通过$on监听自定义事件

双向绑定的原理是什么

双向绑定由三个重要部分构成

  • 数据层(Model):应用的数据及业务逻辑
  • 视图层(View):应用的展示效果,各类UI组件
  • 业务逻辑层(ViewModel):框架封装的核心,它负责将数据与视图关联起来

当数据变化后更新视图,当视图变化后更新数据。通过监听器对所有数据的属性进行监听,
通过解析器对每个元素节点的指令进行扫描跟解析,根据指令模板替换数据,以及绑定相应的更新函数。

插槽

  • 默认插槽:子组件中提供给父组件使用的一个占位符,用 表示
  • 具名插槽:在父组件中使用 v-solt 属性给插槽传个参数,在子组件中使用 name 属性接收参数
  • 作用域插槽:子组件提供内容或者数据,在父组件中显示。也就是子组件在作用域上绑定属性来将子组件的信息传给父组件使用,
    这些属性会被挂在父组件 v-slot 接收的对象上

什么是虚拟dom

所谓的虚拟DOM,其实就是用JS来模拟DOM结构,把DOM的变化操作放在JS层来做,尽量减少对DOM的直接操作。
当数据有变化时,对比前后两次虚拟DOM的变化,只重新渲染变化了的部分,而没有变化的部分则不会重新渲染

什么是diff算法

diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。

vuex

Vuex是实现组件全局状态 (数据) 管理的一种机制,可以方便的实现组件之间的数据共享。核心概念有:

State提供唯一的公共数据源,所有共享的数据都要统一放到State中进行存储
mutations是用来修改 state 中的数据
actions是发起异步请求
Getters是用于对Store中的数据进行加工处理,形成新的数据,类似Vue的计算属性
modules是用来拆分模块的,当一个项目中要使用多个store 时,可用modules来拆分模块

vue 首页白屏解决方法

  • 路由懒加载
    懒加载即组件的延迟加载,通常vue的页面在运 行后进入都会有一个默认的页面,而其他页面只有在点击后才需要加载出来。使用懒加载可以将页面中的资源划分为多份,从而减少第一次加载的时候耗时。

  • 使用CDN加载
    通过在index.html 中直接引入第三方资源来缓解我们服务器的压力,其原理是将我们的压力分给了其他服务器站点。

  • 服务器开启gzip
    gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。

  • 在webpack打包的过程中,将多余文件去掉,如 map 文件

实现响应式布局的方式有如下:

页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整

  • 媒体查询
  • 百分比
  • vw/vh
  • rem

apply、call、bind三者的区别在于:

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的函数,apply、call 则是立即执行
  • 总结:bind 方法可以让函数想什么时候调用就什么时候调用,apply、call方法只是临时改变了 this 指向

v-model和v-bind的区别

  • v-model用在表单控件上的,用于实现双向数据绑定
  • v-bind单项绑定,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind:你要动态变化的值=“表达式”

冒泡排序和快速排序

  • 遍历数组,每个元素都与后一个元素比较,如果大于下一个元素,则两个元素位置调换。
    否则的话当前元素再与下下个元素比较,一直到 跟后面的元素都比较完。这个是升序的排序,降序则相反。

  • 快速排序:
    1.选择数组中间数作为基数,并从数组中取出此基数;
    2.准备两个数组容器,遍历数组,逐个与基数比对,较小的放左边容器,较大的放右边容器;
    3.递归处理两个容器的元素,并将处理后的数据与基数按大小合并成一个数组,返回。

防抖和节流

  • 防抖:防止抖动,单位时间内事件触发会被重置,避免频繁触发事件。代码实现重在清零 clearTimeout
  • 节流:控制流量,单位时间内事件只能触发一次。代码实现重在开锁关锁

js 深浅拷贝

  • 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用地址。例如浅拷贝其实就把 a 对象复制了一份给了 b 对象,
    当修改了 b 对象的某个元素的值后,a 对象对应的元素的值一并跟着修改。因为浅拷贝只拷贝了对象最外层的数据,
    而更深层次的对象只拷贝了对象的内存地址。
  • 深拷贝是拷贝多层,每一级别的数据都会拷贝。例如深拷贝其实就是把 a 对象复制一份给 b 对象,当修改了 b 对象的某个属性值后,
    a 对象对应的属性值并不受影响,都是单独的。

promise async await

promise 是为了解决异步嵌套而产生,让代码更易于理解。它有三种状态:
Pending:对象创建的初始状态
Resolved:成功的状态,then 接收
Rejected:失败的状态,catch 接收

状态一旦决定就不会改变

async/await 是写异步代码的新方式,使用的方式看起来像同步,它是基于promise实现的,但它不能用于普通的回调函数。

箭头函数和普通函数的区别

箭头函数是“=>”,普通函数是“function”。箭头函数不能作为构造函数,不能使用new。箭头函数不绑定arguments,但普通函数可以。
箭头函数中的this代表上层对象,如果上层对象没找到,则 this 指向 Window。普通函数中的this代表当前对象。

对keep-alive的理解

在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,
也不会进行重新初始化组件。 也就是说,keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存

闭包

闭包就是能够读取其他函数内部变量的函数。
闭包的缺点:滥用闭包函数会造成内存泄露

盒子模型

盒子模型:盒子模型分为4个板块,分别是:margin,border,padding,content。
margin:可以设置盒子的外边框与其他盒子之间的距离。
border:可以设置盒子边框的属性,例如边框的高度之类的。
padding:可以设置盒子里的内容与盒子内边框的距离,也就是content与内边框的距离。
content:这个就是盒子里边的内容区域,例如可以放 标签之类的。

原型和原型链

原型是构造函数制造出的对象的公共祖先
构造函数会继承祖先
原型只有function才有
自己身上如果有属性,则取自己的,如果自己没有就继承原型.(原型可以提取公有属性)

原型链
后代继承了父代的原型,无法增删父代的原型

vue 中 nextTick的用法

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

vue 单项数据流

通俗点来说,就是数据是单一方向传输的,
父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子 组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解

1、所有状态的改变可记录、可跟踪,源头易追溯;
2、所有数据只有一份,组件数据只有唯一的入口和出口,使得程序更直观 更容易理解,有利于应用的可维护性;
3、一旦数据变化,就去更新页面(data-页面),但是没有(页面-data);
4、如果用户在页面上做了变动,那么就手动收集起来(双向是自动),合并 到原有的数据中。

computed 和 watch 的区别

  • computed:
    1、支持缓存,只有依赖数据发生改变,才会重新进行计算
    2、不支持异步,当computed内有异步操作时无效,无法监听数据的变化

  • watch:
    1、不支持缓存,数据变,直接会触发相应的操作;
    2、watch支持异步;

说说你对 vue.js 框架的理解

1、Vue.js 的组件化机制
组件就是对一个功能和样式进行独立的封装,让HTML元素得到扩展,从而使得代码得到复用,使得开发灵活,更加高效

2、Vue.js 的响应式系统原理

3、Vue.js 中的 Virtual DOM及Diff 原理
Diff算法的作用是用来计算出 Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面。

get 和 post 的区别

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。

事件委托

利用冒泡原理(子向父一层层穿透),把事件绑定到父元素中,以实现事件委托

js 数据类型

基本数据类型:String,Boolean,number,undefined,object,Null
可以用typeof判断

引用数据类型:Object(Array,Date,RegExp,Function)
可以用instanceof判断,返回值为布尔值

两者都可以用Object.prototype.String判断

事件循环

js是一种单线程的语言,事件循环是为了解决js单线程不会阻塞的一种机制。

由三个部分来工作:

  • 调用栈。存放任务,等待着主线程来执行,执行完就弹出,后进先出。
  • 宏任务队列。存放宏任务,遵循先进先出。
  • 微任务队列。存放微任务,遵循先进先出。

MVVM 模式

也就是 Model-View-ViewModel 模式。

Model 层: 对应数据层的模型,主要⽤于抽象出 ViewModel 中视图的 Model
View 层: 视图,主要负责数据绑定的声明、 指令的声明、 事件绑定的声明
ViewModel 层: 把 View 层需要的数据进行暴露,当 ViewModel 中数据发生变化,View 层会得到更新

git 常用命令

1、初始化仓库:git init
2、添加文件到仓库:git add
3、执行文件提交到仓库:git commit
4、查看当前仓库的状态:git status
5、版本回退:git reset
6、合并分支:git merge
7、从本地推送分⽀:git push origin branch
8、切换分支:git checkout
9、把最新提交的代码从远程仓库中拉取下来:git pull

vuex 中如何进行代码性能优化

1、引入辅助函数

  • mapState用于帮助我们映射state中的数据为计算属性
  • mapGetters用于帮助我们映射getters中的数据为计算属性
  • mapActions用于帮助我们生成与actions对应的方法
  • mapMutations用于帮助我们生成与mutations对应的方法

2、模块化,为了让代码更好维护,让多种数据分类更加明确,我们可以选择将Vuex模块化。

vue new 对象的时候,底层都经历了什么

当执行new Vue时,实际上是执行了_init方法。_init方法会做一堆初始化工作,首先是对options的合并,然后是一系列 init 方法,对data进行proxy处理和响应式处理observe,最后调用$mount做挂载。

vue的响应式原理

Vue 的响应式是通过 Object.defineProperty 对数据进行劫持,并结合发布订阅者模式实现。 Vue 利用 Object.defineProperty 创建一个 observe 来劫持监听所有的属性,把这些属性全部转为 getter 和 setter。Vue 中每个组件实例都会对应一个 watcher 实例,它会在组件渲染的过程中把使用过的数据属性通过 getter 收集为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

原型链和作用域链的区别

(1)原型链
当访问一个对象的某个属性时,会先在这个对象本身的属性上找,如果没有找到,会去这个属性的__proto__属性上找,即这个构造函数的prototype,如果还没找到,就会继续在__proto__上查找,
直到最顶层,找不到即为undefined。这样一层一层往上找,彷佛是一条链子串起来,所以叫做原型链。

(2)作用域链
变量取值会到创建这个变量的函数的作用域中取值,如果找不到,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。

(3)区别
作用域是对变量而言,原型链是对于对象的属性而言
作用域链的顶层是window,原型链的顶层是Object

var、let、const之间的区别

var声明的变量会挂载在window上,而let和const声明的变量不会

var声明的变量存在变量提升,let和const不存在变量提升

同一作用域下var可以声明同名变量,let和const、不可以

let和const声明会形成块级作用域

let暂存死区

const一旦声明必须赋值,不能用null占位,声明后不能再修改,如果声明的是复合类型数据,可以修改属性

vue父子组件生命周期执行顺序

1.首先执行的是父组件的beforeCreate

2.执行的是父组件的created周期

3.执行的是父组件的beforeMount周期

4.执行的是子组件的beforeCreate周期

5.执行的是子组件的created周期

6.执行的是子组件的beforeMount周期

7.执行的是子组件的mounted周期

8.执行的是父组件的mounted周期

总结:

执行的先后顺序为 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted 。

父组件传值给子组件(异步)钩子函数

一、父子组件异步传值的坑
子组件的生命周期只会执行一次,但是当子组件渲染的时候父组件的数据还没接受完就会造成子组件没有任何
内容渲染。

二、解决父子组件异步传值的方法

  1. 给子组件添加渲染条件,使用v-if,当父组件数据接收完毕后在渲染子组件。
  2. 在子组件中添加watch监听,当父组件数据传输过来时,改变原有的默认数据,重新渲染页面。

你可能感兴趣的:(js,vue.js,前端,webpack,vue.js)