掌握Vue技术:精选面试题及答案(4)

118 阅读4分钟

1.Vue 路由实现的底层原理

  • 在 Vue 中利用数据劫持 defineProperty 在原型 prototype 上初始化了一些 getter,

    • 分别是 router 代表当前 Router 的实例.
    • route 代表当前 Router 的信息。
  • 在 install 中也全局注册了 router-view, router-link, 其中的 Vue.util.defineReactive, 这是 Vue 里面观察者劫持数据的方法,劫持 _route,当 _route 触发 setter 方法的时候,则会通知到依赖的组件。

  • 接下来在 init 中,会挂载判断是路由的模式,是 history 或者是 hash,点击行为按钮,调用 hashchange 或者 popstate 的同时更新_route, _route 的更新会触发 route-view 的重新渲染。

2.用过插槽吗?用的是具名插槽还是匿名插槽

用过,都使用过。插槽相当于预留了一个位置,可以将我们书写在组件内的内容放入,写一个插槽就会将组件内的内容替换一次,两次则替换两次。为了自定义插槽的位置我们可以给插槽取名,它会根据插槽名来插入内容,一一对应。 举例来说,这里有一个 <FancyButton> 组件,可以像这样使用:

<FancyButton>
    Click me!
    <!-- 插槽内容 -->
</FancyButton>

<FancyButton> 的模板是这样的:

   <button class="fancy-btn">
        <slot></slot>
        <!-- 插槽出口 -->
    </button>

3. 双向数据绑定的原理

Vue 双向数据绑定的原理是基于 MVVM(Model-View-ViewModel)模式实现的。在 MVVM 模式中,模型(Model)负责管理数据,视图(View)负责展示数据,视图模型(ViewModel)负责连接模型和视图,实现数据的双向绑定。

Vue 使用数据劫持结合发布者-订阅者模式的方式来实现数据的双向绑定。在 Vue2 中,它利用 Object.defineProperty 去劫持对象属性的 getter 和 setter,当触发 getter 时进行依赖收集,触发 setter 时通知执行收集的对应依赖回调。

Vue3 版本则采用了更简单的实现方式,它使用 Object.defineProperty 直接监听对象属性的变化,而不需要依赖数据劫持和发布者-订阅者模式。

4.MVVM 、 MVC 、 MVP 的区别

MVVM(Model-View-ViewModel)、MVC(Model-View-Controller)和 MVP(Model-View-Presenter)是软件开发中常见的设计模式,它们的主要区别如下:

1. MVVM:MVVM 是一种前端架构模式,将应用程序分为模型(Model)、视图(View)和视图模型(ViewModel)三个部分。MVVM 强调数据和视图的绑定,通过自动更新视图来反映模型的变化。ViewModel 负责处理视图和模型之间的交互,将模型的状态转换为可供视图使用的数据。

2. MVC:MVC 是一种传统的软件设计模式,将应用程序分为模型(Model)、视图(View)和控制器(Controller)三个部分。模型负责处理数据和业务逻辑,视图负责展示数据,控制器负责处理用户交互和协调模型和视图之间的操作。

3. MVP:MVP 是一种基于事件驱动的设计模式,将应用程序分为模型(Model)、视图(View)和 presenter(Presenter)三个部分。Presenter 负责处理视图和模型之间的交互,它从模型获取数据并将其传递给视图进行展示,同时处理用户的交互并更新模型。

区别总结:

  • MVVM 强调数据和视图的自动绑定,通过ViewModel 实现数据的双向同步。

  • MVC 模式将模型和视图分离,通过控制器处理用户交互。

  • MVP 模式将视图和 Presenter 分离,Presenter 负责处理用户交互和数据展示。

选择哪种模式取决于具体的应用场景和需求。MVVM 常用于前端开发,特别是使用 MVVM 框架(如 Vue.js)的项目。MVC 和 MVP 主要用于传统的开发当中。

5. 常见的事件修饰符及其作用

在Vue.js中,事件修饰符是为了方便对事件进行处理而提供的一些修饰符。以下是常见的事件修饰符及其作用:

  1. .stop

    • 作用: 阻止事件冒泡。
    • 示例: <a v-on:click.stop="doSomething"></a>
  2. .prevent

    • 作用: 阻止默认行为。
    • 示例: <form v-on:submit.prevent="onSubmit"></form>
  3. .capture

    • 作用: 添加事件监听器时使用事件捕获模式。
    • 示例: <div v-on:click.capture="doSomething"></div>
  4. .self

    • 作用: 只当事件是从侦听器绑定的元素本身触发时才触发回调。
    • 示例: <div v-on:click.self="doSomething"></div>
  5. .once

    • 作用: 只触发一次。
    • 示例: <button v-on:click.once="doSomething"></button>
  6. .passive

    • 作用: 禁用默认事件的阻止行为。
    • 示例: <div v-on:touchstart.passive="doSomething"></div>
  7. .native

    • 作用: 监听组件根元素的原生事件。
    • 示例: <my-component v-on:click.native="doSomething"></my-component>
  8. .left.right.middle

    • 作用: 仅当点击鼠标左/右/中键时触发。
    • 示例: <div v-on:mousedown.left="doSomething"></div>
  9. .keyCode

    • 作用: 仅当按下特定键时触发。
    • 示例: <input v-on:keyup.13="submit"> (在这个例子中,.13 对应 Enter 键)
  10. .stop.prevent.capture 等的缩写:

    • 作用: 可以使用缩写,例如 @click.stop 代替 v-on:click.stop

这些事件修饰符可以组合使用,以实现更复杂的事件处理逻辑。在实际开发中,根据具体需求选择适当的事件修饰符,以简化代码并提高开发效率。