1、SPA的理解,有什么优缺点?
SPA(单页应用)是一种前端应用程序的架构模式,它通过在加载应用程序时只加载单个 HTML 页面,并通过使用 JavaScript 动态地更新页面内容,从而实现无刷新的用户体验。
优点
- 用户体验:
SPA提供了流畅、快速的用户体验,在页面加载后,只有需要的数据和资源会被加载,减少了页面刷新的延迟。 - 响应式交互:由于
SPA依赖于异步数据加载和前端路由,可以实现实时更新和动态加载内容,使用户可以快速地与应用程序交互。 - 代码复用:
SPA通常采用组件化开发的方式,提高了代码的可维护性和可扩展性。 - 服务器负载较低:由于只有初始页面加载时需要从服务器获取
HTML、CSS和JavaScript文件,减轻了服务器的负载。
缺点:
-
首次加载时间:
SPA首次加载时需要下载较大的JavaScript文件,这可能导致初始加载时间较长。 -
SEO(搜索引擎优化)问题:由于
SPA的内容是通过JavaScript动态生成的,搜索引擎的爬虫可能无法正确地获取和索引页面的内容。 -
内存占用:
SPA在用户浏览应用程序时保持单个页面的状态,这可能导致较高的内存占用。 -
安全性:由于
SPA通常使用API进行数据获取,因此需要特别注意安全性。
2、请简述您对vue的理解
vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。
vue是一个mvvm框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。
3、请简述vue的单向数据流
父级 prop 的更新会向下流动到子组件中,每次父组件发生更新,子组件 所有的 prop 都会刷新为最新的值
数据从父组件传递给子组件,只能单向绑定,子组件内部不能直接修改 父组件传递过来的数据,(可以使用 data 和 computed 解决)
4、Vue中组件怎么传值
父传子
- props
- $children
- $refs
子传父
- $emit
- $parent
兄弟组件
- provied
- inject
- eventBus
- Vuex
5、MVVM的理解
MVVM是一种软件架构模式,MVVM 分为 Model、View、ViewModel:
Model代表数据模型,数据和业务逻辑都在Model层中定义;View代表UI视图,负责数据的展示;ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步
6、双向数据绑定原理,Vue是如何收集依赖
采用数据劫持结合发布者-订阅者模式的方式,data数据在初始化的时候,会实例化一个Observe类,在它会将data数据进行递归遍历,并通过Object.defineProperty方法,给每个值添加上一个getter和一个setter。在数据读取的时候会触发getter进行依赖(Watcher)收集,当数据改变时,会触发setter,对刚刚收集的依赖进行触发,并且更新watcher通知视图进行渲染。
依赖收集发生在defineReactive()方法中,在方法内new Dep()实例化一个Dep()实例,然后在getter中通过dep.depend()方法对数据依赖进行收集,然后在settter中通过dep.notify()通知更新。整个Dep其实就是一个观察者,吧收集的依赖存储起来,在需要的时候进行调用。在收集数据依赖的时候,会为数据创建一个Watcher,当数据发生改变通知每个Watcher,由Wathcer进行更新渲染。
7、vue2与vue3的区别
-
Vue2使用的是optionsAPI,Vue3使用composition API,更好的组织代码,提高代码可维护性 -
Vue3使用Proxy代理实现了新的响应式系统,比Vue2有着更好的性能和更准确的数据变化追踪能力。 -
Vue3引入了Teleprot组件,可以将DOM元素渲染到DOM数的其他位置,用于创建模态框、弹出框等。 -
Vue3全局API名称发生了变化,同时新增了watchEffect、Hooks等功能 -
Vue3对TypeScript的支持更加友好 -
Vue3核心库的依赖更少,减少打包体积 -
vue3支持更好的
Tree Shanking,可以更加精确的按需要引入模块
8、Computed和Watch的区别
computed计算属性,通过对已有的属性值进行计算得到一个新值。它需要依赖于其他的数据,当数据发生变化时,computed会自动计算更新。computed属性值会被缓存,只有当依赖数据发生变化时才会重新计算,这样可以避免重复计算提高性能。
watch用于监听数据的变化,并在变化时执行一些操作。它可以监听单个数据或者数组,当数据发生变化时会执行对应的回调函数,和computed不同的是watch不会有缓存。
9、Vue组件中的data为什么是函数
Data 是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。如果是引用类型(对象),当多个组件共用一个数据源时,一处数据改变,所有的组件数据都会改变,所以要利用函数通过 return 返回对象的拷贝,(返回一个新数据),让每个实例都有自己的作用域,相互不影响。
10、对Vue中keep-alive的理解
概念:keep-alive 是 vue 的内置组件,当它动态包裹组件时,会缓存不活动的组件实例,它自身不会渲染成一个 DOM 元素也不会出现在父组件链中
作用:在组件切换过程中将状态保留在内存中,防止重复渲染 DOM,减少加载时间以及性能消耗,提高用户体验。
生命周期函数:Activated 在 keep-alive 组件激活时调用,deactivated在 keep-alive 组件停用时调用
11、Vue循环的key作用
key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,减少DOM操作量,提高性能。
12、对虚拟DOM的理解
虚拟DOM就是用JS对象来表述DOM节点,是对真实DOM的一层抽象。可以通过一些列操作使这个棵树映射到真实DOM上。
如在Vue中,会把代码转换为虚拟DOM,在最终渲染到页面,在每次数据发生变化前,都会缓存一份虚拟DOM,通过diff算法来对比新旧虚拟DOM记录到一个对象中按需更新,最后创建真实DOM,从而提升页面渲染性能。
13、$nextTick原理及作用
Vue 的 nextTick 其本质是对 JavaScript 执行原理 EventLoop 的一种应用。 nextTick是将回调函数放到一个异步队列中,保证在异步更新DOM的watcher后面,从而获取到更新后的DOM。
因为在created()钩子函数中,页面的DOM还未渲染,这时候也没办法操作DOM,所以,此时如果想要操作DOM,必须将操作的代码放在nextTick()的回调函数中。
14、路由守卫
- 全局前置钩子:
beforeEach、beforeResolve、afterEach - 路由独享守卫:
beforeEnter - 组件内钩子:
beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave
15、Vue跨域的解决方案
跨域本质是浏览器基于同源策略的一种安全手段 所谓同源(即指在同一个域)具有以下三个相同点
- 协议相同(protocol)
- 主机相同(host)
- 端口相同(port)
解决跨域的方法:JSONP、CORS、Proxy
CORS
CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应
CORS 实现起来非常方便,只需要增加一些 HTTP 头,让服务器能声明允许的访问来源
Proxy
代理(Proxy)也称网络代理,是一种特殊的网络服务,允许一个(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击
方案一:如果是通过vue-cli脚手架工具搭建项目,我们可以通过webpack为我们起一个本地服务器作为请求的代理对象
方案二:通过服务端实现代理请求转发
方案三:通过配置nginx实现代理
16、Vue首屏加载慢的原因,怎么解决
首屏加载慢的原因:第一次加载页面有很多组件数据需要渲染
解决方法:
1.路由懒加载、异步组件、图片懒加载
2.ui 框架按需加载
3.gzip 压缩
17、Vue性能优化有哪些
编码阶段
v-if和v-for不一起使用v-for保证key的唯一性- 使用
keep-alive缓存组件 v-if和v-show酌情使用- 路由懒加载、异步组件
- 图片懒加载
- 节流防抖
- 第三方模块按需引入
- 服务端与渲染
打包优化
- 压缩代码
- 使用CDN加载第三方模块
- 抽离公共文件
用户体验
- 骨架屏
- 客户端缓存
SEO优化
- 预渲染
- 服务端渲染
- 合理使用
meta标签
18、路由的hash和history模式的区别
hash模式 开发中默认的模式,地址栏URL后携带#,后面为路由。 原理是通过onhashchange()事件监听hash值变化,在页面hash值发生变化后,window就可以监听到事件改变,并按照规则加载相应的代码。hash值变化对应的URL都会被记录下来,这样就能实现浏览器历史页面前进后退。
history模式 history模式中URL没有#,这样相对hash模式更好看,但是需要后台配置支持。
原理是使用HTML5 history提供的pushState、replaceState两个API,用于浏览器记录历史浏览栈,并且在修改URL时不会触发页面刷新和后台数据请求。
19、插槽
slot插槽,一般在封装组件的时候使用,在组件内不知道以那种形式来展示内容时,可以用slot来占据位置,最终展示形式由父组件以内容形式传递过来,主要分为三种:
- 默认插槽:又名匿名插槽,当
slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。 - 具名插槽:带有具体名字的插槽,也就是带有
name属性的slot,一个组件可以出现多个具名插槽。 - 作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。
实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm.$slot中,默认插槽为vm.$slot.default,具名插槽为vm.$slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇到slot标签,使用$slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。
20、vue3.0新特性
(1)重写双向数据绑定
vue2基于Object.defineProperty()实现;vue3 基于Proxy
(2)优化VDOM 在Vue2中,每次更新diff,都是全量对比,Vue3则只对比带有标记的,这样大大减少了非动态内容的对比消耗
(3)Vue3 Fragment
vue3允许我们支持多个根节点
(4)Vue3 Tree shaking
Vue3源码引入tree shaking特性,将全局 API 进行分块。如果你不使用其某些功能,它们将不会包含在你的基础包中。
在Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到
(5)Vue 3 Composition Api
Setup 语法糖式编程