首页 - 设备 - 2021年最新vue面试题

2021年最新vue面试题

2023-10-03 02:13

1.理解MVVM

MVVM分为Model、View、ViewModel。

Model 表示数据模型。数据和业务逻辑在Model层定义;一般是指后端执行的各种业务逻辑处理和数据操作。对于前端来说,就是后端提供的API接口。

View代表UI视图,负责数据的展示;视图层是用户界面。前端主要是用HTML和CSS构建的。

ViewModel负责监听Model中的数据变化并控制视图的更新和处理用户交互操作;

ModelView 没有直接关系,而是通过 ViewModel、 连接Model 和 ViewModel 有它们之间的双向数据绑定关系。因此,当Model中的数据发生变化时,会触发View层的刷新,View中的数据会发生变化,因为用户交互。此外,在模型 已同步。 +

该模式实现ModelView之间的数据自动同步。因此,开发者只需要专注于数据维护操作,而不需要自己操作dom。

ViewModel是由前端开发者组织生成和维护的视图数据层。在这一层,前端开发人员将从后端获取的Model数据进行转换并进行二次封装,生成符合View层期望的视图数据模型。需要注意的是,ViewModel封装的数据模型包括视图的状态和行为,而Model层的数据模型只包含状态,比如页面这部分显示什么,页面打开时会发生什么。已加载。点击这里 某个块发生了什么,以及这个块滚动时发生了什么,都属于视图行为(交互)。视图状态和行为封装在 ViewModel 中。这样的封装使得ViewModel能够完整地描述View层。

MVVM框架实现了双向绑定,这样ViewModel的内容就会实时显示在View层中。前端开发人员不再需要通过操作 DOM 来低效且麻烦地更新视图。 MVVM框架拿走了最脏、最累的部分。完成后,我们开发者只需要处理和维护ViewModel,更新的数据视图就会自动相应更新。这样View层显示的就不是Model层的数据,而是ViewModel的数据。 ViewModel 负责与 Model 层交互。这完全解耦了View层和Model层。这种脱钩至关重要。它是前端和后端分离计划实施的重要组成部分。

2。常用vue指令

1. v-text

v-text主要用于更新textContent,可以相当于JS的text属性。

两者是等价的:

插值表达式{{msg}}

2. v-html

双括号方法会将数据解释为纯文本,而不是 HTML。要输出真实的 HTML,请使用 v-html 指令。相当于JS的innerHtml属性。


该div的内容将被属性值rawHtml替换并直接呈现为HTML。

3。 v-pre

v-pre主要用于跳过该元素及其子元素的编译过程。可用于显示原始的 Mustache 标签。跳过大量无指令的节点以加快编译速度。

{{message}} //该语句不会被编译 {{留言}}

最后只显示第二个跨度的内容

4。 v-cloak

该指令用于保留在元素上,直到关联实例编译结束。

{{信息}}

页面加载时会闪烁(插值闪烁问题),首先显示:

{{信息}}

将被编译为:

你好世界!

可以使用v-cloak命令解决插值表达式的闪烁问题。使用css中v-cloak中的属性选择器将其设置为显示:none;

5。 v-once

与 v-once 关联的实例只会渲染一次。在随后的重新渲染中,该实例及其所有子级将被视为静态内容并被跳过。这可用于优化更新性能。

这永远不会改变:{{msg}} //单个元素
//有子元素

评论

{{msg}}

//组件
  • {{i}}

上面的例子中,msg和list即使发生变化也不会重新渲染。

6。 v-if

v-if可以实现条件渲染。 Vue 将根据表达式值的 true 和 false 条件来渲染元素。

yes

如果属性值 ok 为 true,则显示。否则,该元素将不会被渲染。

7。 v-else

v-else 与 v-if 一起使用。必须跟在v-if或v-else-if后面,否则不起作用。


8。 v-else-if
v-else-if 充当 v-if 的 else-if 块,可以在链中多次使用。 switch语句可以更方便地实现。

A
C
不是A、B、C

9。 v秀

hello world

也用于根据条件显示元素。与 v-if 的区别在于,如果 v-if 的值为 false,则该元素被销毁,不再在 dom 中。但v-show元素始终会被渲染并保存在dom中,它只是切换css dispaly属性。

注意:v-if 的切换开销较高,v-show 的初始渲染开销较高。因此,如果你想切换得非常频繁,最好使用v-show;如果条件在运行时不太可能改变,则 v-if 更好

10。 v-for
使用v-for指令按照遍历数组进行渲染
有两种遍历形式

//用在,index是可选参数,表示当前项的索引
//使用

这里有一个例子,在v-for中,拥有对父作用域属性的完全访问权限。

  • {{parent}}-{{item.text}}

将渲染为:

  • 父范围文本1
  • 父范围-text2
注意:当v-for和v-if在同一个节点时,v-for的优先级高于v-if。这意味着 v-if 将在每个 v-for 循环中运行

11。 v-bind

v-bind 用于动态绑定一个或多个功能。如果没有参数,它可以绑定到包含键值对的对象。常用于类和样式的动态绑定。和 href 等。缩写是冒号 [ : ]

<1>对象语法:

//类别切换示例

渲染结果:


<2>数组语法

12345

渲染结果:


<3>直接绑定数据对象

12345

渲染结果:


12。 v-model
此指令用于在表单上创建双向数据绑定
v-model 会忽略所有表单元素的 value、checked、selected 属性的初始值。因为它选择Vue实例数据作为具体值。

你好{{某人}}

在这个例子中,直接在浏览器输入中输入另一个名字,下面p的内容就会直接相应改变。这是双向数据绑定。

v-model 修饰符 <1> .lazy 默认情况下,v-model 会同步输入框的值和数据。您可以使用此修饰符在更改事件中切换到重新同步。

<2> .number
自动将用户输入的值转换为数值类型

<3> .trim
自动过滤用户输入的第一个和最后一个空格

13。 v-on
v-on主要用于监听dom事件,以便执行一些代码块。表达式可以是方法名称。
的缩写是:[ @ ]

事件修饰符

  • .stop​防止事件继续蔓延
  • .prevent​活动将不再重新加载页面 ​。 capture​ 使用事件捕获模式,即元素本身触发的事件先在这里处理,然后交给元素内部处理
  • .self​ 当元素触发事件时触发处理函数当前元素本身
  • .once​ 该事件只会触发一次
  • .passive​ 告诉浏览器您不想阻止事件默认行为


 

...
...
...

使用修饰符时,顺序很重要;将会按照相同的顺序生成相应的代码。因此,使用 v-on:click.prevent.self 阻止对 的所有点击,而 v-on:click.self.prevent 只会阻止 Click在元素本身上。

3。 v-if 和 v-show 有什么区别?

的共同点:​v-if​和v-show​都可以显示和隐藏元素

差异:​​

1. v-show 只是控制元素的显示属性,而 v-if 是条件渲染(条件为 true 则渲染元素,条件为 false 则销毁元素);

2. v-show 的首次渲染开销较高,而 v-if 的首次渲染开销要小得多;

3. v-if 切换开销较高,v-show 切换开销较小;

4. v-if 有匹配的 v-else-if 和 v-else,但 v-show 没有

5. v-if 可以与 template 配合使用,但 v-show 不能

4。 Vue核心思想:数据驱动、组件化

1。数据驱动

传统前端数据交互采用Ajax从服务器获取数据,然后操作DOM来改变视图;或者前端交互需要改变提取数据时,必须再次执行上述步骤,并且手动操作DOM是一个繁琐的过程并且容易出错。 Vue.js 是一个 Javascript 库,提供 MVVM 风格的双向数据绑定,重点关注 View 层。它可以让开发者省去操作DOM的过程,只需要改变数据。 Vue 会通过 Dircetives 指令封装 DOM。当数据发生变化时,会通知指令修改对应的DOM。数据驱动 DOM 变化。 DOM 是数据的自然映射。 Vue 还监控操作。当视图发生变化时,Vue 会监听这些变化并更改数据,从而形成数据的双向绑定。 Vue 是一个 MVVM 框架。 DOM 是数据的自然映射。传统的模式是通过Ajax请求向模型请求数据,然后手动触发DOM将数据传入页面进行修改。在 Vue 中,指令封装了视图。当模型中的数据发生变化时,Vue 会通过 Directives 指令修改 DOM。同时,视图也通过DOM Listener进行监听。当DOM发生变化时,会监听到,实现模型的变化和数据的双向绑定。

2。组件响应原理数据(模型)变化驱动视图(视图)自动更新

当你将一个普通的JavaScript对象传递给Vue实例的data选项时,Vue会遍历这个对象的所有属性并使用Object. DefineProperty 将所有这些属性转换为 getter/setter。 Object.defineProperty是ES5中无法被shimmed的功能,这就是Vue不支持IE8及更低版本浏览器的原因。 getter/setter 对用户不可见,但在内部它们允许 Vue 跟踪依赖项并在访问和修改属性时通知更改。这里需要注意的问题是,浏览器控制台在打印数据对象时对 getter/setter 的格式不同,因此您可能需要安装 vue-devtools 以获得更友好的检查界面。每个组件实例都有一个对应的watcher实例对象,该对象在组件渲染过程中将属性记录为依赖项。稍后,当调用依赖项的 setter 时,将通知观察者重新计算,从而导致其关联组件被更新。 。

3。组件化

扩展 HTML 元素并封装可重用的代码。每个组件对应一个ViewModel。页面上的每个独立的视觉/交互区域都可以被视为一个组件。每个组件对应一个项目目录,该目录中维护着组件所需的各种资源。页面是组件的容器,组件可以自由嵌套、组合,形成完整的页面。

组件化实现扩展的 HTML 元素并封装可用的代码。页面上每个独立的视觉/交互区域被视为一个组件;每个组件对应一个项目目录,就近维护该组件所需的各种资源;页面只不过是组件的容器,组件可以嵌套自由组合,形成完整的页面。

5。 Vue生命周期

//数据 数据() { 返回 { 消息:“子组件”, 孩子姓名:www.gsm-guard.net } } // 新的Vue 新Vue({el: '#app', 路由器, 模板: '', 组件:{应用程序} })

因为组件是为了复用,而JS中的对象是引用关系,如果组件中的数据是对象,那么作用域就不是隔离的,子组件中的数据属性值​​​​组件之间会互相影响。如果组件的 data 选项是一个函数,那么每个实例都可以维护一个独立的返回对象的副本,组件实例之间的 data 属性值不会互相影响;并且新的 Vue 实例将不会被重用。所以不存在引用对象的问题。

7。 Vue组件之间的通信方式有哪些?

Vue组件之间的通信是面试中常见的知识点之一。这个问题有点类似于开放式问题。你回答的方法越多,得到的分数就越多,这说明你对Vue更加熟练。 Vue组件之间的通信仅指以下三种通信:父子组件通信、代际组件通信、兄弟组件通信。下面我们分别介绍每种通信方式,并说明该方式可以应用于哪些类型的组件间通信。

(1) props / $emit 适用于父子组件通信

这个方法是Vue组件的基础。相信大多数同学都比较熟悉,这里就不举例介绍了。

(2) ref 和 $parent / $children 适合父子组件通信

  • ref:如果用在普通DOM元素上,则引用指向DOM元素;如果用在子组件上,引用指向组件实例
  • $parent / $children:访问父/子实例

(3) EventBus ($emit / $on) 适合父子,跨代和兄弟组件通信

该方法使用一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件并监听事件,从而实现任何组件之间的通信,包括父子组件、分代组件、兄弟组件。

(4) $attrs/$listeners 适合代际组件通信

  • $attrs:包含父范围中的 prop 无法识别(和获取)的属性绑定(类和样式除外)。当组件没有声明任何 props 时,所有父作用域绑定(类和样式除外)都将包含在此处,并且可以通过 v-bind="$attrs" 传递到内部组件中。通常与inheritAttrs 选项一起使用。
  • $listeners:包含父作用域中的 v-on 事件侦听器(不带 .native 修饰符)。可以通过 v-on="$listeners" 传入组件内部

(5)provider/inject 适合代际组件通信

在祖先组件中通过provider提供变量,然后在后代组件中通过inject注入变量。 Provide/Inject API主要解决跨级组件之间的通信问题,但其使用场景主要是子组件获取上级组件的状态,跨级组件之间建立主动提供和依赖注入的关系。

(6)Vuex 适合亲子、代际、兄弟组件通信

Vuex 是专门为 Vue.js 应用程序开发的状态管理模式。每个 Vuex 应用程序的核心是商店。 “存储”基本上是一个包含应用程序中大部分状态的容器。

  • Vuex 的状态存储是反应式的。当 Vue 组件从 Store 中读取状态时,如果 Store 中的状态发生变化,相应的组件将相应地高效更新。
  • 更改存储中状态的唯一方法是显式提交突变。这使我们能够轻松跟踪每个状态变化。

8。 Compute和Watch有什么区别以及使用场景?

compulated:是计算属性,依赖于其他属性值,计算值会被缓存。只有当其依赖的属性值发生变化时,下次获取计算值时才会重新计算计算值; watch:更多 是“观察”的功能,类似于某些数据的监听回调。每当监控到的数据发生变化时,就会执行回调进行后续操作;应用场景:

  • 当我们需要进行数值计算并且依赖于其他数据时,应该使用compute,因为compute的缓存特性可以避免每次获取值时都重新计算;
  • 当我们需要在数据变化时进行计算时,在执行异步或昂贵的操作时应该使用Watch。使用 watch 选项允许我们执行异步操作(访问 API),限制执行操作的频率,并在获得最终结果之前设置中间状态。这些是计算属性无法做到的事情。

9。虚拟 DOM

优点:

  • 保证性能下限:框架的虚拟DOM需要适应上层API可能产生的任何操作。它的一些DOM操作的实现必须是通用的,因此它的性能并不是最优的;但相比粗暴的 DOM 操作性能要好很多,所以框架的虚拟 DOM 至少可以保证你在不进行手动优化的情况下仍然可以提供良好的性能,也就是保证性能的下限;
  • 无需手动操作 DOM:我们不再需要手动操作 DOM,只需要编写 View-Model 的代码逻辑即可。框架会双向绑定虚拟DOM和数据,帮助我们以可预测的方式更新视图,大大提高我们的开发效率;
  • 跨平台:虚拟DOM本质上是一个JavaScript对象,DOM与平台强相关。相比之下,虚拟DOM可以进行更方便的跨平台操作,比如服务端渲染、weex开发等。

缺点:

  • 无法进行极致优化:虽然虚拟DOM+合理优化足以满足大部分应用的性能需求,但在一些性能要求极高的应用中,虚拟DOM无法优化到极致。

虚拟DOM实现原理:

虚拟DOM的实现原理主要包括以下3部分:

  • 使用JavaScript对象来模拟真实的DOM树,对真实的DOM进行抽象;
  • diff算法——比较两个虚拟DOM树之间的差异;
  • pach 算法 - 将两个虚拟 DOM 对象之间的差异应用于真实 DOM 树。

10。 vue-router有几种路由模式?

  1.  ​Hash​:使用URL的哈希值作为路由。支持所有浏览器。
  2.  ​History​:自 HTML5 History API 和服务器配置以来。参考官网​​HTML5 History模式
  3.  ​Abstract​:支持所有javascript运行模式。如果没有找到浏览器 API,路由器将自动强制进入此模式。

11。 delete和Vue.delete删除数组的区别

delete只是将删除的元素变为空/未定义,其他元素的键值保持不变。 Vue.delete 直接删除数组并更改数组的键值。

12。了解SPA单页,它的优缺点是什么?

SPA(单页应用程序)仅在网页初始化时加载相应的 HTML、JavaScript 和 CSS。页面一旦加载,SPA不会因用户操作而重新加载或跳转页面;相反,它使用路由机制来实现HTML内容的转换以及UI与用户之间的交互,以避免页面重新加载。优点:

  • 用户体验好,速度快。内容的改变不需要重新加载整个页面,避免不必要的跳转和重复渲染;
  • 基于以上几点,SPA对服务器的压力相对较小;
  • 前后端职责分离,架构清晰,前端执行交互逻辑,后端负责数据处理;

缺点:

  • 初始加载时间较长:为了实现单页面Web应用功能和显示效果,加载页面时需要统一加载JavaScript和CSS,部分页面按需加载;
  • 前进后退路由管理:由于单页应用程序将所有内容显示在一页上,因此无法使用浏览器的前进后退功能。所有页面切换都需要自己的堆栈管理;
  • SEO比较困难:由于所有内容都是动态替换并显示在一个页面上,所以在SEO方面有天然的弱点。

13。简单描述一下Vue的响应式原理

当创建Vue实例时,vue会遍历data选项的属性,使用Object.defineProperty将其转换为getter/setter,并在内部跟踪相关依赖关系。访问和修改属性时通知更改。每个组件实例都有一个对应的观察程序实例,该实例在组件渲染期间将属性记录为依赖项。稍后,当调用依赖项的 setter 时,将通知观察者重新计算,从而导致其关联组件被更新。 。

从“vue”导入Vue 常量组件 = { 道具:['值'], 模板:`

`, 数据 () { 返回 { } }, 方法: { 处理输入(e){ this.$emit('输入', e.target.value) } } } 新Vue({ 成分: { CompOne:组件 }, el: '#root', 模板:`
`, 数据 () { 返回 { 值:'123'} } })

可以看到,当输入数据时,父子组件中的数据同步变化:

模板:`

`

v-model实际上会帮助我们完成以上两个步骤。

15。如何在Vue中监控属性值的变化?

比如现在我们需要监控data中obj.a的变化。您可以像这样监视 Vue 中对象属性的变化:

观看:{
      对象:{
      处理程序(新值,旧值){
        console.log('对象已更改')
      },
      深:真实
    }
  }

deep属性代表深度遍历,但是这样写会监听obj的所有属性变化,这不是我们想要的效果,所以做一些修改:

观看:{
   'obj.a': {
      处理程序(新名称,旧名称){
        console.log('obj.a 已更改')
      }
   }
  }

还有一种方法,可以通过compute实现,只需要:

计算:{
    a1 () {
      返回 this.obj.a
    }
}

利用计算属性的特点来实现这一点,当依赖关系发生变化时,会重新计算一个新的值。

推荐好课程:vue2.x微课、Vue项目实战讲座、Vue.js三天实战教程