Skip to content

1.v-if 和 v-show 的区别?

都可以控制元素的显示和隐藏

  • v-show 时控制元素的 display 值来让元素显示和隐藏;v-if 显示隐藏时把 DOM 元素整个添加和删除
  • v-if 有一个局部编译/卸载的过程,切换这个过程中会适当的销毁和重建内部的事件监听和子组件;v-show 只是简单的 css 切换
  • v-if 才是真正的条件渲染;v-show 从 false 变成 true 的时候不会触发组件的声明周期,v-if 会触发声明周期
  • v-if 的切换效率比较低 v-show 的效率比较高

2.MVC 和 MVVM

MVC(Model-View-Controller)

  • Model:负责管理应用程序的核心数据和业务逻辑。
  • View:负责展示数据并与用户交互。
  • Controller:作为 Model 和 View 之间的桥梁,处理用户输入并更新 Model,同时通知 View 更新。

特点

  • 单向通信:Controller 更新 Model 后,View 需要从 Model 中获取数据来刷新。
  • 职责分离:Model、View 和 Controller 各自独立,便于维护。
  • 适用于:传统 Web 应用和桌面应用。

MVVM(Model-View-ViewModel)

  • Model:与 MVC 中的 Model 类似,负责管理数据。
  • View:负责展示数据并与用户交互。
  • ViewModel:作为 View 和 Model 之间的中介,负责处理 View 的展示逻辑和状态管理。

特点

  • 双向绑定:View 和 ViewModel 之间自动同步数据,View 变化时 ViewModel 更新,反之亦然。
  • 职责分离:View 专注于展示,ViewModel 处理逻辑,Model 管理数据。
  • 适用于:现代前端框架(如 Angular、Vue.js、React)和需要复杂交互的应用。

主要区别

  • 数据绑定:MVVM 支持双向绑定,MVC 通常为单向。
  • Controller vs ViewModel:MVC 的 Controller 处理用户输入并更新 Model,MVVM 的 ViewModel 负责 View 的展示逻辑和状态管理。
  • 适用场景:MVC 适合传统 Web 应用,MVVM 适合需要复杂交互的现代前端应用。

3.v-for 中的 key 值的作用是什么?

key 属性是 DOM 元素的唯一标识 作用:

  • 提高虚拟 DOM 的更新
  • 若不设置 key,可能会触发一些 bug
  • 为了触发过度效果

4.说一下你对 vue 生命周期的理解。

组件从创建到销毁的过程就是它的生命周期

创建

  • beforeCreat ​ 在这个阶段属性和方法都不能使用

  • created 这里时实例创建完成之后,在这里完成了数据监测,可以使用数据,修改数据,不会触发 updated,也不会更新视图

挂载

  • beforeMount 完成了模板的编译,虚拟 DOM 也完成创建,即将渲染,修改数据,不会触发 updated
  • Mounted 把编译好的模板挂载到页面,这里可以发送异步请求也可以访问 DOM 节点

​ 更新

  • beforeUpdate ​ 组件数据更新之前使用,数据是新的,页面上的数据时旧的,组件即将更新,准备渲染,可以改数据
  • updated render 重新做了渲染,这时数据和页面都是新的,避免在此更新数据

销毁

  • beforeDestroy 实例销毁前,在这里实例还可以用,可以清楚定时器等等
  • destroyed 组件已经被销毁了,全部都销毁

使用了 keep-alive 时多出两个周期

  • activited 组件激活时
  • deactivited 组件被销毁时

5.在 created 和 mounted 去请求数据,有什么区别?

  • created:在渲染前调用,通常先初始化属性,然后做渲染

  • mounted:在模板渲染完成后,一般都是初始化页面后,在对元素节点进行操作 ​ 在这里请求数据可能会出现闪屏的问题,created 里不会 一般用 created 比较多

  • 请求的数据对 DOM 有影响,那么使用 created

  • 如果请求的数据对 DOM 无关,可以放在 mounted

6.vue 中的修饰符有哪些?

事件修饰符

  • .stop 组织冒泡
  • .prevent 组织默认行为
  • .capture 内部元素触发的事件先在次处理
  • .self 只有在 event.target 是当前元素时触发
  • .once 事件只会触发一次
  • .passive 立即触发默认行为
  • .native 把当前元素作为原生标签看待

按键修饰符

  • .keyup 键盘抬起
  • .keydown 键盘按下

系统修饰符

  • .ctrl
  • .alt
  • .meta

鼠标修饰符

  • .left 鼠标左键
  • .right 鼠标右键
  • .middle 鼠标中键

表单修饰符

  • .lazy 等输入完之后再显示
  • .trim 删除内容前后的空格
  • .number 输入是数字或转为数字

7.elementui 是怎么做表单验证的?

  1. 在表单中加 rules 属性,然后再 data 里写校验规则
  2. 内部添加规则
  3. 自定义函数校验

8.vue 如何进行组件通信?

  1. 父传子 ​ props ​ 父组件使用自定义属性,然后子组件使用 props 引用信息会注册在父组件的$refs 对象上

  2. 子传父 ​ $emit ​ 子组件绑定自定义事件,触发执行后,传给父组件,父组件需要用事件监听来接收参数

  3. 兄弟传 ​ new 一个新的 vue 实例,用 on 和 emit 来对数据进行传输

  4. vuex 传值

9.keep-alive 是什么?怎么使用?

Vue 的一个内置组件,包裹组件的时候,会缓存不活跃的组件实例,并不是销毁他们 ​ 作用:把组件切换的状态保存在内存里,防止重复渲染 DOM 节点,减少加载时间和性能消耗,提高用户体验

10.axios 是怎么做封装的?

下载 创建实例 接着封装请求响应拦截器 抛出 最后封装接口

11.vue 路由时怎么传参的

  • params 传参

参数不会显示在 URL 中,适用于传递一些不需要暴露给用户或搜索引擎的参数

js
this.$router.push({name:'index',params:{id:item.id}})
this.$route.params.id
  • 动态路由匹配

更灵活的参数传递,适用于路径中包含动态部分的场景

js
{
  path: '/user/:id',
  component: UserComponent
}
this.$router.push({ path: `/user/${userId}` });
  • query 传参(可以解决页面刷新参数丢失的问题)

参数会显示在 URL 中,类似于 GET 请求的查询参数,适用于需要保留历史记录或分享链接的场景

js
this.$router.push({
 name:'index',
 query:{id:item.id}
})

12.vue 路由的 hash 模式和 history 模式有什么区别?

  1. hash 的路由地址上有#号,history 模式没有

  2. 在做回车刷新的时候,hash 模式会加载对应页面,history 会报错 404

  3. hash 模式支持低版本浏览器,history 不支持,因为是 H5 新增的 API

  4. hash 不会重新加载页面,单页面应用必备

  5. history 有历史记录,H5 新增了 pushState 和 replaceState()去修改历史记录,并不会立刻发送请求

  6. history 需要后台配置nginx

13.路由拦截是怎么实现的?

路由拦截 axios 拦截 ​需要在路由配置中添加一个字段,它是用于判断路由是否需要拦截

js
{
 name:'index',
 path:'/index',
 component:Index,
 meta:{
  requirtAuth:true
  }
}
router.beforeEach((to,from,next) => {
if(to.meta.requirtAuth){
 if( store.satte.token ){
  next()
 }else{
 }
 }
})

14.说一下 vue 的动态路由。

  1. 定义基础路由
  2. 定义动态路由或路由配置在数据库表中
  3. 添加路由导航守卫 再守卫中根据权限获取到指定的路由 并添加动态路由

15.如何解决刷新后二次加载路由?

  1. window.location.reload()
  2. matcher
    const router = createRouter()
    export function resetRouter(){
     const newRouter = creatRouter()
     router.matcher = newRouter.matcher
    }

16.vuex 刷新数据会丢失吗?怎么解决?

vuex 肯定会重新获取数据,页面也会丢失数据

  1. 把数据直接保存在浏览器缓存里 vuex数据变化时实时更新缓存中的值 给vuex初始值
  2. 监听浏览器的刷新事件,在刷新前把数据保存到sessionstorage中,刷新后请求数据,请求到则用Vuex的数据,如果没有那就用sessionstorage中的数据

17.computed 和 watch 的区别?

  1. computed 是计算属性,watch 是监听,监听的是 data 中数据的变化

  2. computed 是支持缓存,依赖的属性值发生变化,计算属性才会重新计算,否则用缓存;watch 不支持缓存

  3. computed 不支持异步,watch 是可以异步操作

  4. computed 是第一次加载就监听,watch 是不监听

  5. computed 函数中必须有 return watch 不用

18.vuex 在什么场景会去使用?属性有 些?

  • state 存储变量

  • getters state 的计算属性

  • mutations 提交更新数据的方法

  • actions 和 mutations 差不多,他是提交 mutations 来修改数据,可以包括异步操作

  • modules 模块化 vuex

使用场景: ​ 用户的个人信息、购物车模块、订单模块、需要共享数据的业务都可以

19.vue 的双向数据绑定原理是什么?

vue2

通过数据劫持和发布订阅者模式来实现

  1. Object.defineProperty

使用 Object.defineProperty 来实现数据劫持。Object.defineProperty 可以拦截对象属性的读取和设置操作 2. 依赖收集

在组件渲染过程中,会触发数据的 get 操作,此时会收集依赖(即 Watcher)。每个响应式数据都有一个 dep 实例,用于管理所有依赖该数据的 Watcher。 3. 派发更新

当数据发生变化时,会触发 set 操作,此时会通知所有依赖该数据的 Watcher,这些 Watcher 会重新执行更新操作,从而更新视图

vue3

  1. Proxy Vue 3 使用 Proxy 对象来实现数据劫持。Proxy 可以拦截对象的所有操作,包括属性的添加、删除、读取和设置等

  2. 依赖收集

在组件渲染过程中,会触发数据的 get 操作,此时会收集依赖(即 Effect)。每个响应式数据都有一个 ReactiveEffect 实例,用于管理所有依赖该数据的 Effect。

  1. 派发更新

当数据发生变化时,会触发 set 操作,此时会通知所有依赖该数据的 Effect,这些 Effect 会重新执行更新操作,从而更新视图。

特性Vue 2Vue 3
数据劫持Object.definePropertyProxy
支持的操作仅支持对象属性的读取和设置支持所有操作(包括数组方法)
动态属性需要使用 Vue.setVue.delete自动检测属性的添加或删除
性能对于大量数据或深层嵌套的对象性能较差提供更好的性能
兼容性支持所有现代浏览器,包括 IE不支持 IE,但提供兼容性支持

20.了解 diff 算法和虚拟 DOM 吗?

虚拟 DOM,描述元素和元素之间的关系,创建一个 JS 对象 如果组件内有响应的数据,数据发生改变的时候,render 函数会生成一个新的虚拟 DOM,这个新的虚拟 DOM 会和旧的虚拟 DOM 进行比对,找到需要修改的虚拟 DOM 内容,然后去对应的真实 DOM 中修改 ​ diff 算法就是虚拟 DOM 的比对时用的,返回一个 patch 对象,这个对象的作用就是存储两个节点不同的地方,最后用 patch 里记录的信息进行更新真实 DOM

步骤:

  1. JS 对象表示真实的 DOM 结构,要生成一个虚拟 DOM,再用虚拟 DOM 构建一个真实 DOM 树,渲染到页面
  2. 状态改变生成新的虚拟 DOM,跟就得虚拟 DOM 进行比对,这个比对的过程就是 DIFF 算法,利用 patch 记录差异
  3. 把记录的差异用在第一个虚拟 DOM 生成的真实 DOM 上,视图就更新了。

21.vue 和 jquery 的区别是什么?

  1. 原理不同

    vue 就是数据绑定;jq 是先获取 dom 再处理

  2. 着重点不同

vue 是数据驱动,jq 是着重于页面

  1. 操作不同

  2. 未来发展不同

22.vuex 的响应式处理。

vuex 是 vue 的状态管理工具 ​vue 中可以直接触发 methods 中的方法,vuex 是不可以的。未来处理异步,当触发事件的时候,会通过 dispatch 来访问 actions 中的方法,actions 中的 commit 会触发 mutations 中的方法从而修改 state 里的值,通过 getter 把数据更新到视图 ​ Vue.use(vuex),调用 install 方法,通过 applyMixin(vue)在任意组件内执行 this.$store 就可以访问到 store 对象。 ​ vuex 的 state 是响应式的,借助的就是 vue 的 data,把 state 存到 vue 实例组件的 data 中

23.vue 中遍历全局的方法有哪些?

  1. forEach

  2. map

  3. filter

  4. findindex

24.vue2 data为什么是函数

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

25.如何封装一个组件?

  1. 使用 Vue.extend()创建一个组件

  2. 使用 Vue.components()方法注册组件

  3. 如果子组件需要数据,可以在 props 中接收定义

  4. 子组件修改好数据,要把数据传递给父组件,可以用 emit()方法

原则: ​ 把功能拆开 ​ 尽量让组件原子化,一个组件做一件事情 ​ 容器组件管数据,展示组件管视图

26.封装一个可复用的组件,需要满足什么条件?

  • 低耦合,组件之间的依赖越小越好

  • 最好从父级传入信息,不要在公共组件中请求数据

  • 传入的数据要进行校验

  • 处理事件的方法写在父组件中

27.vue 的过滤器怎么使用?

vue 的特性,用来对文本进行格式化处理 使用它的两个地方,一个是插值表达式,一个是 v-bind 使用

js
<div>{{33 | add}}</div>

全局过滤器

js
Vue.filter('add',function(v){
 return v < 10 ? '0' + v : v
})

组件过滤器

js
和 methods 同级
filter:{
 add:function(v){
  return v < 10 ? '0' + v : v
  }
}

28.vue 中如何做强制刷新?

  • localtion.reload()

  • this.$router.go(0)

29.vue3 和 vue2 有哪些区别?

详情见

  1. 双向数据绑定的原理不同
  2. 是否支持碎片
  3. API 不同
  4. 定义数据变量方法不同
  5. 生命周期的不同
  6. 传值不同
  7. 指令和插槽不同
  8. main.js 不同

30.vue 的性能优化怎么做?

  1. 编码优化 ​ 不要把所有数据都放在 data 中 ​ v-for 时给每个元素绑定事件用事件代理 ​ keep-alive 缓存组件 ​ 尽可能拆分组件,提高复用性、维护性 ​ key 值要保证唯一 ​ 合理使用路由懒加载,异步组件 ​ 数据持久化存储的使用尽量用防抖、节流优化
  2. 加载优化 ​ 按需加载 ​ 内容懒加载 ​ 图片懒加载
  3. 用户体验 ​ 骨架屏
  4. SEO 优化 ​ 预渲染 ​ 服务端渲染 ssr
  5. 打包优化 ​ CDN 形式加载第三方模块 ​ 多线程打包 ​ 抽离公共文件
  6. 缓存和压缩 ​ 客户端缓存、服务端缓存 ​ 服务端 Gzip 压缩

31.首屏优化该如何去做?

  1. 使用路由懒加载
  2. 非首屏组件使用异步组件
  3. 首屏不中要的组件延迟加载
  4. 静态资源放在 CDN 上
  5. 减少首屏上 JS、CSS 等资源文件的大小
  6. 使用服务端渲染
  7. 简历减少 DOM 的数量和层级
  8. 使用精灵图请求
  9. 做一些 loading
  10. 开启 Gzip 压缩
  11. 图片懒加载

32.vue3 的性能为什么比 vue2 好?

  1. diff 算法的优化
  2. 静态提升
  3. 事件侦听缓存

33.vue3 为什么使用 proxy?

  1. proxy 可以代理整个对象,defineproperty 只代理对象上的某个属性
  2. proxy 对代理对象的监听更加丰富
  3. proxy 代理对象会生成新的对象,不会修改被代理对象本身
  4. proxy 补兼容 ie 浏览器

34.说一下你对组件的理解。

  • 可以重复使用的 vue 实例,独一无二的组件名称
  • 可以抽离单独的公共模块
  • 提高代码的复用率

35.你是如何规划项目文件的?

public ​图标、index.html、img ​src ​api ​assets ​components ​按分类再次划分子目录 ​ plugins ​ router ​ static ​ styles ​ utils