目录
vue2.0相关
一、vue2.0 生命周期钩子
1.2 父子组件的生命周期顺序?
二、说说 MVC 与MVVM?
三、vue的实现原理?
四、vue的双向数据绑定原理?
四、v-modal的原理?
五、vue2中的watch 和computed的区别?
六、data为什么不能是对象而必须是函数?
七、vue中的mixins
八、v-for的key的作用?
九、vue中的组件通信
十、父组件如何获取子组件实例对象的方法?
十一、v-if和v-for能不能同时使用?需要注意什么?
十二、v-if和v-show的区别?
十三、vue响应式数据的添加?
十四、vue中的性能优化?
十五、vue-router的理解
十六、vue中的自定义事件
十七、说说对vuex的理解?
十八、vuex的工作流程?
十九、vuex如果在外部改变内部的值?
二十、vue项目中页面闪动怎么解决
vue3.0相关
1.vue3.0的特点?与vue2有什么区别?优化?
2.vue3.0的响应式原理?与vue2对比有什么优势?
3.vue3.0中的ref和reactive
4.composition API与option API的区别?
5.SetUp的执行时机?
6.说说watch与watchEffect?
7.vue3.0中的组件通信
8.teleport组件的作用?
9.路由的两种模式
10.toref和toRefs的作用
11.vue3.0中的自定义HOOKS?与vue2.0中的mixins的优势是什么?
12.什么是tree-shaking?
13.pinia状态管理器?
14.组合式API中的错误处理方法?
15.vue3中的性能优化
vue2.0相关
一、vue2.0 生命周期钩子
在整个生命周期过程中,一共有三个阶段:初始化显示阶段、更新阶段、卸载阶段;
会在特定的时刻执行某个回调函数;
初始化显示阶段:beforeCrate() 实例初始化之后调用,此时不能访问this\data\methods
created() 实例创建完成调用,此时可以发送最早的ajax请求
beforemount() 页面将要挂载,此时还不能通过ref获取到标签对象
mounted() 页面已经挂载,此时可以获取到标签对象,也可以发送请求
更新阶段: beforeUpdate() 页面更新之前,数据是新的,页面是旧的
updated() 页面更新完成,此时 页面和数据都是最新的;
卸载阶段: beforedistroy() 实例销毁前调用,此时可做收尾的工作关闭定时器和监听 事件
distroyed() 实例销毁之后调用,实例无法正常工作了;
缓存组件相关(keep-alive):是抽象组件,用于缓存不活动的组件实例,避免重复渲染
activated:被keep-alive缓存的组件激活时(进行页面)
deactivated:被keep-alive缓存的组件失活时(离开页面)
errorcaptured():用于捕获子组件的错误,return false 可以阻止错误向上冒泡传递
重点:最早的异步请求==》created ; 最早可操作DOM ==》mounted ;清除定时器、全局监听事件==》beforedistroy;
1.2 父子组件的生命周期顺序?
父beforeCreate==>父created==>子beforecreate==>子created ==>子mounted==>父mounted
二、说说 MVC 与MVVM?
首先MVC 是“modal-view-controller” =“模型-视图-控制器”,模型指的是后端传过来的数据,view视图是所看到的页面,controller 指的是页面的业务逻辑;MVC的目的就是将modal和view代码分离,MVC是单向数据流,即view和modal需要通过controller承上启下;
而MVVM指的是“modal-view-viewModal” = “模型-视图-视图模型”,模型知道是后端传过来的数据,视图是所看到的页面,视图模型是MVVM模式中的核心,它是连接view 和modal 的桥梁,通过数据绑定将modal转为view,也就是将数据转为可视化的页面,在通过事件监听将view转为modal,也就是将页面转为后台的数据;这个也就是双向数据绑定;
MVC与MVVM的区别 不是将viewModal代替了controller,而是在MVC的基础上添加了viewmodal,弱化controller,目的是抽离controller中的业务逻辑,而不是代替controller,从而实现业务逻辑组件的重用,使开发更高效更结构化,增加代码的复用性;
MVVM的优势:不需要操作dom, 数据是响应式的;
三、vue的实现原理?
vue的实现原理是“数据驱动视图”,所谓的数据驱动是指当数据发生变化的时候,界面也相应的发生改变,不需要手动修改dom;通过v-modal 双向数据绑定,实现modal层与view层交互效果;
四、vue的双向数据绑定原理?
核心是:通过数据劫持配合“发布-订阅模式”的机制来追踪依赖并在数据变化之后更新视图
具体的步骤是:
1.数据劫持
在vue初始化时,通过objcet.defineproperty()方法劫持 data中的所有属性;目的是 在读取属性值时,收集谁依赖了这个属性;在修改属性值时,通知所有的依赖者;
2.收集依赖
每个响应式的属性都有一个对应的依赖管理器---dep对象
当读取属性值时,会触发getter方法,在getter方法中,将watcher记录到对应的dep列表中,建立依赖关系;
3.派发更新
当修改属性值时,会触发sertter方法,在setter方法中,会通知dep,dep会去通知它列表中所有的watcher,watcher收到通知后,会触发视图更新;
四、v-modal的原理?
v-modal是vue提供的语法糖指令,将动态的data数据通过value属性传给input显示,实现数据到视图的绑定;再通过给input绑定监听事件,一旦输入发生变化,读取最新的值保存到data对象的属性上,实现视图到数据的更新;
本质上:v-modal的“双向”的效果还是建立在vue的响应式系统上,不论数据的传递还是事件的处理还是通过响应式数据的getter和setter
五、vue2中的watch 和computed的区别?
watch 是一个监听器,不需要有返回值,每次当监听的属性变化时执行,支持异步,默认不会立即执行,需要手动配置;使用场景:数据变化时执行异步或者复杂的操作;
computed:是一个计算属性,必须要有返回值,当依赖发生变化的时候重新计算,无变化就会读取缓存,它不支持异步,组件加载完后会立即执行;
六、data为什么不能是对象而必须是函数?
简单来说就是多个实例不能共享同一个data数据,避免状态污染;
如果data是对象,对象是引用类型,存的是地址,会出现多个实例共享同一个data数据;
如果是函数,每次通过函数都会返回一个新的数据对象,每个实例都会拥有一个独立的数据副本
七、vue中的mixins
用来定义公共变量和方法的选项式对象,在引入组件之后,变量是互相独立的,修改值在组件之间不会相互影响;缺点:会出现命名冲突、以整个选项对象为单位复用,强制接受所有逻辑,可能引入无关的功能,增大组件的体积;
八、v-for的key的作用?
key作为唯一标识能辅助diff算法更高效的复用dom节点,避免不必要的渲染,注意,尽量避免使用index作为key,因为如果要动态新增、删除操作数组,index会导致元素错位或数据状态混乱;
九、vue中的组件通信
父——子:props
子——父:自定义事件
任意组件:全局事件总线、消息订阅与发布、vuex
十、父组件如何获取子组件实例对象的方法?
通过ref\children
十一、v-if和v-for能不能同时使用?需要注意什么?
可以同时使用,但是不建议写在同一标签上,因为v-for的优先级比v-if高,如果在同一个变迁上,会先执行v-for遍历产生多个标签后,然后v-if再执行对多个标签进行判断,效率很低,尤其是在只对部分内容渲染新的时候,最好的办法是把v-if写到v-for的父级标签,这样只执行一次提高了效率,也可以用计算属性代替v-if;
十二、v-if和v-show的区别?
首先 v-if和v-show都是控制元素的显示和隐藏的,不同的是,v-if是直接通过删除dom对象来隐藏,隐藏时不占用内存空间,重新显示时需要重新加载,需要加载时间;而v-show是通过控制display样式实现隐藏或展示的,隐藏时占用内存空间
十三、vue响应式数据的添加?
首先响应式数据就是 数据变化会触发视图更新,非响应式数据就是数据变化不能触发视图更新;而响应式的原理底层就是通过object。defineproperty()对data中的数据添加数据劫持(getter和setter方法),当读取数据的时候,会触发getter,修改数据的时候会触发setter,setter再通知dep对象,dep会通知watcher触发视图更新;而我们如果动态的添加属性,它没有经历过数据劫持,就不会有get和set方法,所以数据变化而视图不变,可以使用vue提供的 vm.$set(对象,属性名,属性值)动态添加响应式的属性,它会触发视图更新;
十四、vue中的性能优化?
- 路由懒加载:在vuerouter中,使用动态导入语句实现路由懒加载,再使用webpack魔法注释将不同的路由拆分成不同的代码块,在需要时按需加载,可以减小初始包的体积和提高首次加载的速度;
- 图片懒加载:未出现在可视区内的图片先不加载,提高的页面的加载速度;
- 第三方插件按需引入,减小项目的体积
- 使用keep-alive缓存组件,防止组件频繁的创建和销毁,浪费性能
- 使用v-show 代替v-if
- key保证唯一性,提高dom-diff的复用性能
十五、vue-router的理解
首先vue-router是vue基于单页面应用的路由管理器,其功能包括:
- 配置路由,建立路由和组件的对应关系;
- 路由导航分为:
- 声明式路由导航 在模版中的导航 router-link
- 编程式路由导航 在js逻辑中跳.转 $router.push
- 路由的替换:$router.replace
- 返回上一页:router.go(-1)
- vue-router还包含路由守卫,作用是监视路由跳转、控制路由跳转;
- 全局前置守卫:router.beforeEach(to,from,naxt)
- 路由独享守卫:router.beforeEnter 在路由配置中定义
- 组件内路由守卫:作用于单独的组件,beforeRouteEnter\beforeRouteLeave
- 路由模式
- hash模式:url携带#号,兼容性好,原理是监听window.onhashchange事件
- history模式:URL不携带#号,美观;原理是基于history.pushState\history.replaceState
- 路由的高级特性
- 懒加载:通过配置import语句,可按需加载路由组件
- 返回页面恢复滚动位置:scrollbehavior()
- 附加权限或标题等属性,可以配置路由元信息:mate对象
- 路由切换时添加动画效果
十六、vue中的自定义事件
自定义事件是vue中子向父通信的一种方式;
自定义事件分为:绑定监听事件on('事件名称‘,data);分发事件emit('事件名称‘data)
使用$off解除绑定事件
十七、说说对vuex的理解?
vuex是vue的状态管理库,采用集中式管理状态数据;
包括五大核心:
- state:用来存储应用级的状态数据,不可以被直接修改;
- getters:类似于组件中computed 是状态的计算属性;
- mutations:唯一可以修改state状态的入口,必须是同步函数,通过commit触发的;
- actions:处理异步操作或者复杂的操作,支持异步函数,最终会commit 提交mutations,通过dispatch触发;
- moudules:分模块化管理状态,支持嵌套、命名空间;
包含了4个辅助函数,分别是:
mapState:直接访问store中的state;
mapgetter:将store中的getter直接映射为组件中的计算属性;
mapMutations和mapActions:将store中的mutations直接映射为组件的方法,可以直接在 组件内部调用触发;
辅助函数的主要作用就是 简化代码,避免重复书写;
十八、vuex的工作流程?
组件通过dispatch 触发 actions,actions中可以执行异步函数,并且提交 mutations,在mutations中修改state,state变化后,自动更新视图
十九、vuex如果在外部改变内部的值?
- 组件通过store的dispatch,分发给action,执行action后,可以通过context对象的commit属性触发mutation,在mutation中修改state;
- 组件通过store的commit方法直接提交mutation,从而修改state状态
二十、vue项目中页面闪动怎么解决
使用v-clock指令隐藏未编译的元素,结合骨架屏在数据加载前显示内容的轮廓;
还可以添加加载动画;把首屏的css关键样式直接引入到html的style标签中;
通过服务端渲染
vue3.0相关
1.vue3.0的特点?与vue2有什么区别?优化?
- 首先 vue3.0通过setUp()函数将逻辑按照公共模块聚合,而不是分散在data\methods中,解决了vue2.0的optionApi 代码碎片化的问题
- 更好的支持ts
- 支持tree-shaking,内存减少了54%,打包体积减小,打包和渲染的时间更快
- 使用proxy代替了defineproperty实现数据响应式
- 使用ref和reactive定义响应式数据,取代了data;
2.vue3.0的响应式原理?与vue2对比有什么优势?
在vue3.0中,使用proxy(代理)与 reflect(映射)代替了object.defineproperty进行数据劫持;proxy代理的是对象而不是对象中的属性,减少了递归,提高了性能;
代理的优势是 解决了vue2中的遗留问题, vue3中可以直接修改数据的长度或通过索引修改数组而保持响应式,支持动态的新增、删除属性保持数据的响应式;
3.vue3.0中的ref和reactive
ref:用来定义基本数据类型的,比如string\number,适用于简单的数据,通过.value访问,在模版中自动解包;
reactive:适用于对象或数组等深层嵌套的数据类型,直接访问,不需要.value,注意解构赋值会失去响应性,需要通过torefs 转换保持响应性;
4.composition API与option API的区别?
composition API 按照功能组织代码,而option API 是根据选项类型 组织代码;
composition API 更好的支持TS,
支持自定义HOOKS,便于代码复用,代替了option API中的mixins;
5.SetUp的执行时机?
在beforeCreate之前执行,无法访问this,获取实例的方法通过:getiCurrentInstance()
6.说说watch与watchEffect?
watch 与watchEffect都是用来监听响应式数据变化的;
watch:必须明确依赖源,可以获取旧值,默认不立即执行;
watchEffect:自动收集并追踪依赖,不能获取旧值,初始化后会立即执行;
7.vue3.0中的组件通信
父与子互相通信:父组件用props,子组件用emit自定义事件;
还可以在父组件中通过ref动态修改子组件中暴露出的响应式数据或方法;
跨层级通信:父组件用provide提供数据;子孙组件通过inject 接受数据;
任意组件通信:pinia;
8.teleport组件的作用?
它是vue3.0中的内置组件,用于将模版的内容移动到指定目标的位置,并不受DOM层级的影响;
有2个属性:to:指定的目标容器;
disabled 为true时,内容将保留到原位置;
9.路由的两种模式
hash模式:url携带#号,原理是基于监听windowonhashChange事件,兼容性好
history模式:url 不带#号,原理是基于history.pushState\history.replaceState,需要服务端配合;
10.toref和toRefs的作用
toref:将响应式对象的某个属性转为ref对象并保持响应式连接;
torefs:将响应式的对象转为普通对象,并将所有属性转为ref对象,保持响应式连接;用于解构reactive对象失去响应式后通过toRefs保持响应式;
11.vue3.0中的自定义HOOKS?与vue2.0中的mixins的优势是什么?
自定义hooks 基于composition API 的函数封装,约定以use开头命名,支持在内部嵌套其他hooks,通过import 动态引入
- 优点:按需引入,显式引用,可以灵活的拆分和组合使用
- 优点:支持重命名,避免了命名冲突
- 优点:通过解构可以获取状态和方法,更清晰数据的来源;
- 优点:支持TS类型推断
12.什么是tree-shaking?
是通过对代码的静态分析并在打包前移除未使用的模块的优化技术;可以减小框架的打包体积,提升打包速度
tree-shaking 在vue3中的通过对代码的静态分析,确保移除未使用的代码,又重构全局的API,将全局API转为实例方法、在vue3的compositionAPI的基础下,对于通过动态引入的方法和数据,对未使用的代码在打包前移除代码;
13.pinia状态管理器?
pinia 是vue3官方推荐的状态管理器,对比与vue2的vuex有以下特点:
首先通过defineStore创建一个独立的store,不需要嵌套命名空间,在创建时就保证了唯一性;
其次,移除了mutation,简化了流程,通过action进行同步和异步的操作;
支持 composition Api,与vue3语法更契合;在组件中通过import 引入store实例,可以直接调用其方法;
支持Ts类型推断;
体积更小,性能更好;
pinia的响应式是通过ref和reactive构建响应数据,底层还是基于代理实现的;
14.组合式API中的错误处理方法?
局部:try...catch...
全局:app.config.errorHandler
onErrorComputed钩子,在父组件中调用,捕获和处理所有子组件的错误,阻止错误继续向上冒泡;
15.vue3中的性能优化
- 响应式核心的升级:用proxy代替了object.defineproperty,初始化速度提升,减少了内存的占用;
- 解决了深层嵌套数据的响应式:可以直接修改数组的长度,新增、删除属性,无需通过set方法;
- 更好的tree-shaking支持,减小了打包的体积、提高了打包的速度
- 通过block-tree机制,在虚拟dom的Diff过程中,跳过静态节点,收集并直接对比动态节点,提高了更新和渲染的速度,静态节点只渲染一次,减少了vnode的内存占用,性能得到提升;