vue 面试

  • vue是什么
    是一个用于创建用户界面的开源JavaScript框架,也是一个创建单页应用的Web应用框架.vue 特性有数据驱动(MVVM),组件化,指令系统
  • 什么是spa
    • single page application 它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载,也不会将控制转移到其他页面
  • spa 和 mpa 的区别
    • 多页应用MPA MultiPage-page application 就是多页应用在MPA中,每个页面都是一个主页面,都是独立的当我们在访问另一个页面的时候,都需要重新加载html、css、js文件
  • 单页应用优缺点
    • 具有桌面应用的即时性、网站的可移植性和可访问性
      用户体验好、快,内容的改变不需要重新加载整个页面
      良好的前后端分离,分工更明确
    • 不利于搜索引擎的抓取
      首次渲染速度相对较慢
  • v-show 和 v-if 怎么理解
    • 控制手段:v-show隐藏则是为该元素添加css--display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除

    • 编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换

    • 编译条件:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染

  • vue挂载会发生什么
    • new Vue的时候调用会调用_init方法

    • 定义 setget 、deletewatch 等方法

    • 定义 onoff、emitoff等事件

    • 定义 _update、forceUpdatedestroy生命周期

    • 调用$mount进行页面的挂载

    • 挂载的时候主要是通过mountComponent方法

    • 定义updateComponent更新函数

    • 执行render生成虚拟DOM

    • _update将虚拟DOM生成真实DOM结构,并且渲染到页面中

  • 生命周期有哪些
    • 创建前后, 载入前后,更新前后,销毁前销毁后
  • 永远不要把 v-if 和 v-for 同时用在同一个元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断)
  • 减少首屏渲染时间的方法 资源加载优化 和 页面渲染优化
  • image info
  • data属性是一个函数而不是一个对象?
    • 根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况
      组件实例对象data必须为函数,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染。采用函数的形式,initData时会将其作为工厂函数都会返回全新data对象
  • 直接添加属性的问题
    • 发现结果不及预期,数据虽然更新了(console打印出了新属性),但页面并没有更新

    • vue2是用过Object.defineProperty实现数据响应式

    • obj的foo属性被设成了响应式数据,而bar是后面新增的属性,并没有通过Object.defineProperty设置成响应式数据

    • Vue.set()

    • Object.assign()

    • 如果为对象添加少量的新属性,可以直接采用Vue.set()

    • 如果需要为新对象添加大量的新属性,则通过Object.assign()创建新对象

    • 如果你实在不知道怎么操作时,可采取$forceUpdate()进行强制刷新 (不建议)

  • 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件
  • 插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种
    • 添加全局方法或者属性。如: vue-custom-element
    • 添加全局资源:指令/过滤器/过渡等。如 vue-touch
    • 通过全局混入来添加一些组件选项。如vue-router
    • 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
    • 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如vue-router
  • 组件间通信的分类可以分成以下
    -父子组件之间的通信
    -兄弟组件之间的通信
    -祖孙与后代组件之间的通信
    -非关系组件间之间的通信
    • 通过 props 传递
      通过 emit使refEventBusparent 或 $root
      attrs 与 listeners
      Provide 与 Inject
      Vuex

props

  • 监听器(Observer):对所有数据的属性进行监听
    解析器(Compiler):对每个元素节点的指令进行扫描跟解析,根据指令模板替换数据,以及绑定相应的更新函数

  • NextTick是什么 Vue 在更新 DOM 时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新

  • Mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类
    Mixin类通常作为功能模块使用,在需要该功能时“混入”,有利于代码复用又避免了多继承的复杂

  • 通过插槽可以让用户可以拓展组件,去更好地复用组件和对其做定制化处理

    如果父组件在使用到一个复用组件的时候,获取这个组件在不同的地方有少量的更改,如果去重写组件是一件不明智的事情

    通过slot插槽向组件内部指定位置传递内容,完成这个复用组件在不同场景的应用

    比如布局组件、表格列、下拉选、弹框显示内容等

  • slot可以分以下三种:

    默认插槽
    具名插槽
    作用域插槽

  • v-slot属性只能在<template>上使用,但在只有默认插槽时可以在组件标签上使用
    默认插槽名为default,可以省略default直接写v-slot
    缩写为#时不能不写参数,写成#default
    可以通过解构获取v-slot={user},还可以重命名v-slot="{user: newName}"和定义默认值v-slot="{user = '默认 值'}"

  • Observable 让一个对象变成响应式数据。Vue 内部会用它来处理 data 函数返回的对象

  • key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点

    • 如果不用key,Vue会采用就地复地原则:最小化element的移动,并且会尝试尽最大程度在同适当的地方对相同类型的element,做patch或者reuse。
      如果使用了key,Vue会根据keys的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destoryed用+new Date()生成的时间戳作为key,手动强制触发重新渲染
      当拥有新值的rerender作为key时,拥有了新key的Comp出现了,那么旧key Comp会被移除,新key
  • keep-alive
    -keep-alive是vue中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM, keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
    keep-alive可以设置以下props属性:

    include - 字符串或正则表达式。只有名称匹配的组件会被缓存

    exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存

    max - 数字。最多可以缓存多少组件实例
    缓存后如何获取数据 beforeRouteEnter,actived

  • 修饰符

    • 表单修饰符
      • lazy 在我们填完信息,光标离开标签的时候,才会将值赋予给value,也就是在change事件之后再进行信息同步
      • trim 自动过滤用户输入的首空格字符,而中间的空格不会过滤
      • number 自动将输入值转为数字类型,但这个值无法被parseFloat解析,则会返回原来的值
    • 事件修饰符
      • stop 阻止了事件冒泡,相当于调用了event.stopPropgation方法
      • prevent 阻止了事件默认行为,相当于调用envent.perventDefault方法
      • self 只当在event.target 是当前元素自身时触发处理函数
      • once 当绑定事件以后只能触发一次,第二次不会触发
      • capture 使事件从包含这个元素的顶层开始往下触发
      • passive 在移动端,当我们在监听元素滚动事件的时候,会一直触发onscroll事件会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符
      • native 让组件变成像html内置标签那样监听根元素的原生事件,否则组件上使用 v-on 只会监听自定义事件
    • 鼠标按键修饰符
      • left 左键点击
      • right 右键点击
      • middle 中键点击
    • 键值修饰符 键盘修饰符是用来修饰键盘事件(onkeyup,onkeydown)普通键(enter、tab、delete、space、esc、up...)系统修饰键(ctrl、alt、meta、shift...)
      • v-bind修饰符
      • async 能对props进行一个双向绑定
      • prop
      • camel
  • camel 将命名变为驼峰命名法,如将view-Box属性名转换为 viewBox
    自定义指令

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus() // 页面加载完成之后自动让输入框获取到焦点的小功能
}
})
  • 局部注册通过在组件options选项中设置directive属性
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus() // 页面加载完成之后自动让输入框获取到焦点的小功能
}
}
}
  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用

  • unbind:只调用一次,指令与元素解绑时调用

  • diff 算法是一种通过同层的树节点进行比较的高效算法

    • 比较只会在同层级进行, 不会跨层级比较
    • 在diff比较的过程中,循环从两边向中间比较
  • keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。include定义缓存白名单,keep-alive会缓存命中的组件;exclude定义缓存黑名单,被命中的组件将不会被缓存;max定义缓存组件上限,一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。

  • hash模式是通过onHashChange事件监听url变化

  • v-model 在每次 input 事件触发后将输入框的值与数据进行同步 。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:

    如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:如果这个值无法被 parseFloat() 解析,则会返回原始的值。

  • push()在该数组最尾添加新的元素,然后返回更新后的数组长度,方法将改变原始数组的长度;

    shift()删除该数组第一个元素,并且把该数组剩下的元素索引往前挪一位,然后返回删除的元素,方法将改变原始数组的长度;

    reverse()反转该数组中元素的顺序,方法将改变原始数组。

    concat()把两个以上的数字连接起来,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

    push(),shift(),reverse()改变原数组,会触发视图跟新;

    concat()不更改数组,会返回新数组,因此没有替换原数组,不触发视图更新,要用新数组替换原数组才能实现视图更新。
    for…in 语句以原始插入顺序迭代对象的可枚举属性(只能迭代出可枚举的属性)。---拿到的是下标

    for…of 语句遍历可迭代对象定义要迭代的数据(非自定义属性)。---拿到的是值

加载渲染过程:

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程
父beforeUpdate->父updated

销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

  • 全局路由守卫的钩子函数有:beforeEach(全局前置守卫)、beforeResolve(全局解析守卫)、afterEach(全局后置守卫)
    名字中间没有“Route”,
    组件级路由守卫的钩子函数才有“Route”

  • MutationObserver 接口提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。

  • Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。

  • 由于 JavaScript 的限制,Vue 不能检测数组和对象的变化,因而对象属性的添加或删除不可以监听到。
    Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在data对象上存在才能让 Vue 将它转换为响应式的

  • Vue组件的生命周期涉及到的钩子函数和执行顺序是:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed,activated和deactivated是组件设置了keep-alive时,进入组件和离开组件时分别触发的两个函数

  • watch
    immediate:在侦听器创建时立即触发回调。第一次调用时旧值是 undefined。
    deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调。参考深层侦听器。
    flush:调整回调函数的刷新时机。参考回调的刷新时机及 watchEffect()。
    onTrack / onTrigger:调试侦听器的依赖。参考调试侦听器。

  • Vuex属性包括state、mutations、actions、gettters、modules

  • vue2.2+版本新增了一个功能,可以在自定义组件上使用v-model实现双向绑定

  • Actions不可以直接修改状态,需要使用mutation改变。 Actions可包含任意异步。

  • props传过来的,改数字,改字符串会报错,改数组,对象里面的值不会报错

  • context是用在react中进行组件间的传值,Vue组件间传值可以通过props,$emit,Vuex,事件总线。

posted @   webzom  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示