vue面试题汇总 1

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: vue面试题汇总

1. 谈谈你对MVVM开发模式的理解?

MVVM是一种简化用户界面的实践驱动编程方式。在当前主流的前后端分离的开发模式中,MVVM模式的优越性日益体现,相较于经典的MVC模式,其对于程序模块的封装很好地解决了前后端信息交互的冗余和繁琐


MVVM分为Model、View、ViewModel三者。

Model 代表数据模型,数据和业务逻辑都在Model层中定义;

View 代表UI视图,负责数据的展示;

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

Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。

这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。


为什么使用MVVM:低耦合,可复用,独立开发,可测试


2. v-if 和 v-show 有什么区别?

手段

v-if是动态的向DOM树内添加或者删除DOM元素;

v-show是通过设置DOM元素的display样式属性控制显隐;

编译

v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译;

v-show是在任何条件下,无论首次条件是否为真,都被编译,然后被缓存,而且DOM元素保留;

性能消耗:

v-if有更高的切换消耗;

v-show有更高的初始渲染消耗

3.r o u t e 和 route和route和router区别

$route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数

$router 是“路由实例”想要导航到不同URL 对象包括了路由的跳转方法,钩子函数等。通过push、replace、go、back等方法,来实现页面间的跳转

4.vue自定义指令

vue指令


vue2


局部注册:directive选项

directives: {
 'focus': {
   bind(el, binding, vnode) {
     el.focus()
   }
 }
}

全局注册:main.js

Vue.directives('focus',{
  bind(el, binding, vnode) {
     el.focus()
   }
})

生命周期:


bind:只调用一次,指令第一次绑到元素调用,用于初始化

inserted:被绑定元素插入父节点时调用

update:所在组件vnode更新调用

componentUpdate:指令在组件的vnode及子组件的vnode全部更新完调用

ubind:只调用一侧,指令解绑

vue3


局部注册:引入 import { Directive , DirectiveBinding } from ‘vue’ 分别校验vFocus,binding

<template>
<input type="text" v-focus="{ color: 'red' }" />
</template>
<script setup>
const vFocus = {
created(el, binding) {
 el.style.backgroundColor = binding.value.color;
 console.log(el, binding.value.color); //<input type="text" style="background-color: red;"> 'red'
},
};
</script>

全局注册:main.js,app.vue如上引入

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.directive('focus', {
 created(el, binding) {
     el.style.backgroundColor = binding.value.color;
     console.log(el, binding.value.color); //<input type="text" style="background-color: red;"> 'red'
 }
})
app.mount('#app')

生命周期:


created 元素初始化的时候

beforeMount 指令绑定到元素后调用 只调用一次

mounted 元素插入父级dom调用

beforeUpdate 元素被更新之前调用

update 这个周期方法被移除 改用updated

beforeUnmount 在元素被移除前调用

unmounted 指令被移除后调用 只调用一次

5.vue项目优化

代码层面

长列表性能优化

事件销毁, beforeDestroy生命周期函数内执行销毁逻辑。

图片懒加载

路由懒加载

按需加载插件

v-if,v-for避免同时使用

v-if,v-show选择

keep-alive组件缓存

input防抖节流

基础的web技术优化

开启gzip压缩

浏览器缓存

CDN加速

webpack优化

6.vue模板如何编译

Vue的模板编译就是将“HTML”模板编译成render函数的过程。这个过程大致可以分成三个阶段:


解析阶段:将“HTML”模板解析成AST语法树;

核心 parseHTML( template ,{}) Vue定义了很多匹配HTML的正则表达式 ,parseHTML根据正则匹配

parseHTML是解析模板字符串的“主线程”,它的第一个参数是要解析的模板字符串, 也就是单文件组件中最外层 所包裹的部分;第二个参数是一个选项对象,它会包含一些回调,以及一些配置项。

选项对象:

start( tag, attrs, unary ) 匹配到开始标签时的回调,tag为当前标签的标签名,attrs为该标签上的属性列表,unary为当前标签是否为自闭合标签

end() 匹配到结束标签时的回调

chars(text) 匹配到文本节点的回调

comment(text) 匹配到注释节点的回调,其处理逻辑跟文本的处理逻辑类似

优化阶段:从AST语法树中找出静态子树并进行标记(被标记的静态子树在虚拟dom比对时会被忽略,从而提高虚拟dom比对的性能);

上面简单介绍过,优化阶段的工作就是标记静态子树,标记静态子树后主要有以下两个优点:

生成虚拟dom的过程中,如果发现一个节点是静态子树,除了首次渲染外不会生成新的子节点树,而是拷贝已存在的静态子树;

比对虚拟dom的过程中,如果发现当前节点是静态子树,则直接跳过,不需要进行比对。

标记静态子树的过程分为两个步骤:

遍历AST语法树,找出所有的静态节点并打上标记(注:当前节点及其所有子节点都是静态节点,当前节点才会被打上静态节点的标记)

遍历经过上面步骤后的树,找出静态根节点,并打上标记(注:静态根节点是指本身及所有子节点都是静态节点,但是父节点为动态节点的节点,找到了静态根节点也就找到了“静态子树”)

代码生成阶段:通过AST生成代码字符串,并最终生成render函数。

7.vue2响应式原理

vue 采用了几个核心部件 : Observer ,Dep, Watcher ,Scheduler


observer把一个普通的对象转换成响应式的对象

observer 把对象的每个属性通过 object.defineProperty 转换为带有 getter 和 setter 的属性

Dep 表示依赖, vue 会为响应式对象中的每一个属性,对象本身,数组本身创建一个 dep 实例,每个 dep 实例都可以做两件事情 :

记录依赖:是谁在用我

派发更新:我变了,我要通知那些用我的人

watcher 在函数执行的过程中,如果发生了依赖记录,那么 dep 就会把这个全局变量记录下来,表示有一个 wathcer 用到了我这个属性。

Scheduler 不会立即执行更新,通过nexttick异步更新

8.vue3响应式原理

通过Proxy(代理): 拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。


通过Reffect(反射): 对源对象的属性进行操作, Reflect不是一个函数对象,因此它是不可构造的。


9.刷新浏览器后,Vuex的数据是否存在?如何解决?

不存在


原因: 因为 store 里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值初始化。


我们有两种方法解决该问题:


使用 vuex-along

使用 localStorage 或者 sessionStroage

10.vue和react共同点?区别

共同点:


数据驱动视图

组件化

都使用 Virtual DOM

不同点:


核心思想不同

vue定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发。这就有了vue的主要特点:灵活易用的渐进式框架,进行数据拦截/代理,它对侦测数据的变化更敏感、更精确。

react 定位就是提出 UI 开发的新思路 React推崇函数式编程(纯组件),数据不可变以及单向数据流,当然需要双向的地方也可以手动实现, 比如借助onChange和setState来实现。

组件写法

React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中

Vue 推荐的做法是 template 的单文件组件格式(简单易懂,从传统前端转过来易于理解),即 html,css,JS 写在同一个文件(vue也支持JSX写法)

diff算法

响应式原理

vue2采用object.defineProperty ,vue3采用proxy,reflect

React基于状态机,手动优化,数据不可变,需要setState驱动新的state替换老的state。

11.vue双向数据绑定原理

简易实现:v-model分为两部分,通过v-bind绑定值,再通过v-on:input来通步修改值


原理:


需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化

通过dep来理清依赖关系,watcher在依赖中添加自身

compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

待属性变动dep.notice()通知时,能调动watcher自身的update方法,并处罚compile回调渲染视图

12.computed和watch区别

computed计算属性,watch监听属性


计算属性不在 data 中,它是基于data 或 props 中的数据通过计算得到的一个新值。watch 可以监听的数据来源:data,props,computed内的数据

component中有get和set方法,会默认缓存计算结果。watch不支持缓存,支持异步, immediate监听属性立即执行一次,deep开启深度监听

13.Vuex

Vuex是一种状态管理模式,存在的目的是共享可复用的组件状态。


主要包括以下几个模块:


State => 基本数据,定义了应用状态的数据结构,可以在这里设置默认的初始状态。

Getter => 从基本数据派生的数据,允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。

Mutation => 是唯一更改 store 中状态的方法,且必须是同步函数。

Action => 像一个装饰器,包裹mutations,使之可以异步。用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。

Module => 模块化Vuex,允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

14.vuex辅助函数

mapState, mapMutations, mapActions, mapGetters


mapState和mapGetters:


两者都放在 computed中,以mapState举例

import { mapState } from 'vuex'

import { mapState } from 'vuex'
computed中
computed:{
  ...mapState(['data'])  //data是vuex存放的state中的属性,此时{{data}}可使用
}

mapMutations, mapActions:


放在组件的methods属性中 。使用与上类似

15.vuex模块化使用

当我们开发的项目比较大时,store中的数据就可能比较多,这时我们store中的数据就可能变得臃肿,为了解决这一问题,我们就需要将store模块化(module)


前提:创建两份js文件,含有属性与vuex写法相同,需要通过 namespaced:true开启命名空间store/index.js:在modules中引入文件


使用:


访问state数据:

第一种方式:this.$store.state.moduleA.sum

第二种方式: ...mapState('moduleA',['sum','number'])

action提交mutation

第一种方式:需要传参this.$store.dispatch('moduleB/addZhang',{name:'小明',age:18}) ,无需传参this.$store.dispatch('moduleB/addServer')

第二种方式:...mapActions('moduleB',['addZhang'])

getters计算属性

第一种方式: this.$store.getters['moduleB/firstName']

第二种方式:...mapGetters('moduleB',['firstName'])

16.vue中mixin

mixin(混入): 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。


本质其实就是一个js对象,它可以包含我们组件中任意功能选项,如data、components、methods 、created、computed等等


我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来


具体使用:


创建mixins.js文件

let mixin = {
    created() {
        console.log('我是mixin中的');
    },
    methods: {
        hellow() {
            console.log('你好');
        },
    },
}
export default mixin

局部使用

import mixin from "./mixins";
export default {
  mixins: [mixin],
  mounted() {
    this.hellow();//你好
  },
};

全局使用main.js

import { createApp } from 'vue'
import App from './App.vue'
import mixins from "./mixins";
const app = createApp(App)
app.mixin(mixins)
app.mount('#app')
目录
相关文章
|
4月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
4月前
|
JavaScript
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
这篇文章深入探讨了Vue中的`slot`概念,包括它的定义、使用场景和分类(默认插槽、具名插槽和作用域插槽),并通过代码示例展示了如何在组件中使用插槽来实现内容的分发和自定义。同时,文章还对插槽的工作原理进行了分析,解释了`renderSlot`函数和`$scopedSlots`对象的角色。
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
|
4月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
4月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
4月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
3月前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
169 64
|
2月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
42 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
4月前
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
4月前
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
4月前
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?