提供网站建设加工,泉州做网站建设,深圳做网站比较好,网上商城下载Vue2 相关面试题总结
1. 谈谈对Vue的理解
Vue是一种用于构建用户页面的渐进式JavaScript框架#xff0c;也是一个创建SPA单页面应用的Web应用框架#xff0c;Vue的核心是 数据驱动试图#xff0c;通过组件内特定的方法实现视图和模型的交互#xff1b;特性#xff1a;也是一个创建SPA单页面应用的Web应用框架Vue的核心是 数据驱动试图通过组件内特定的方法实现视图和模型的交互特性看自己要不要对每一项特性进行解释如果解释可能会牵扯出很多面试题 数据驱动试图 MVVM是一种双向数据绑定的模式用ViewModel来建立起Model数据层和View视图层的连接数据和视图的改变是双向的可能会问MVVM 和 MVC 的区别(见4) 组件开发 组件可以在项目中直接进行复用出现问题时可以实现快速定位能够提高代码可复用性和可维护性。可能会问如何封装一个组件见后面 指令系统 Vue内置很多 v- 系列的指令可以响应式的作用于DOM比如v-if条件渲染v-for列表渲染v-model双向数据绑定等。可能会问自定义封装指令的一些知识见后面 缺点 不利于SEO优化 解决办法 SSR服务器渲染静态化预渲染骨架屏 首屏加载速度慢加载时将所有的cssjs文件都进行加载不支持IE678IE也不用了有些数据不需要响应式但必须写在data里影响加载速度和性能Vue的响应式是通过Object.defineProperty: 无法监听ES6的Set、Map变化无法监听Class类型的数据属性的新加或删除无法监听数组元素的增加和删除无法监听
2. Vue最大优势
是一款轻量级框架简单易学数据双向绑定虚拟DOM组件化数据和结构相分离运行速度快等等文档都是中文的入门教程很多上手简单Vue是单页面应用使页面局部刷新不用每次跳转页面都去请求所有的数据和DOM加快了访问速度和提升用户体验相比传统的页面通过超链接实现页面的切换和跳转Vue使用路由不会刷新页面第三方UI库使用起来非常方便节省了很多开发时间从而提升了开发效率。
3. Vue 和 jQuery 的区别是什么
jQuery 应该算是一个插件里面封装了各种简单易用的方法它的本质就是使用更少的代码操作DOM节点它是使用选择器获取DOM对象对其进行赋值、取值、事件绑定等操作对数据的操作依赖于对应的DOM对象 Vue 一套渐进式的框架拥有自己的规则体系和语法特别是MVVM的设计思想让数据和视图进行双向绑定极少操作DOM对数据进行操作不再依赖于对应的DOM对象。
4. MVVM 和 MVC 区别是什么
MVC 一种设计模式是Model数据模型View视图Controller控制器在控制器这层里面编写代码控制数据和视图进行关联MVC是单向通信 MVVM 既Model-View-ViewModel的简写模型-视图-视图模型VM是整个设计模式的核心是用来连接视图和模型的桥梁模型指的是后端传递的数据视图指的是所看到的页面有两个方向 首先模型转换为视图将从后端请求回来的数据转换为网页 实现方式数据绑定 其次视图转换为模型将网页转化为后端的数据 实现方式监听DOM事件。 这两个方向都实现的我们称为数据的双向绑定。 区别 MVC是单向通信MVVM是双向通信主要是MVC中的Controller演变成了MVVM中的VMMVVM主要解决了MVC中大量的DOM操作导致的页面渲染性能降低加载速度慢影响用户体验。
5. Vue常用修饰符
事件修饰符 .stop 阻止事件冒泡.prevent 阻止事件默认行为.once 程序运行期间事件处理函数只执行一次.native 原生事件使用组件库的时候可能会用到按键修饰符 .enter ➡ 监测Enter键.esc ➡ 监测ESC键v-model修饰符 .number ➡ 尝试用parseFloat转数字.trim ➡ 去除字符串首尾两侧的空白字符.lazy ➡ 内容改变并且失去焦点触发特殊 .sync ➡ 可以在子组件内部直接修改父组件的值格式 父组件子组件 变量名.sync数据属性/this.$emit(update:对应的属性名, 值)注意此处的 update:对应的属性名 不能有空格见下图具体使用如下
父组件
templatediv classhomeHelloWorldmsgWelcome to Your Vue.js App:type.synctype:arr.syncarr:obj.syncobj//div
/templatescript
import HelloWorld from /components/HelloWorld.vue;export default {name: HomeView,data() {return {type: 1,arr: [1, 2, 3],obj: {a: 1,b: 2,},};},components: {HelloWorld,},
};
/script子组件
templatediv classhellobutton clickupdateData改变数据/buttonspan {{ type }} /spanspan {{ arr }} /spanspan {{ obj }} /span/div
/templatescript
export default {name: HelloWorld,props: {type: {type: Number,require: true,},arr: {type: Array,require: true,},obj: {type: Object,require: true,},},methods: {updateData() {this.$emit(update:type, 2);this.$emit(update:arr, [4, 5, 6]);this.$emit(update:obj, {a: 张三,b: 李四,});},},
};
/script6. Vue常用指令 v-bind:属性名 表达式 ➡ 给标签动态赋值简写:属性名 表达式v-on:事件名 少量代码 / 函数名 / 函数名(实参) ➡ 绑定事件简写 事件名 少量代码 / 函数名 / 函数名(实参)v-model 表达式 ➡ 将表单元素的 value属性 和 Vue数据属性 进行双向绑定可以使用v-model语法糖实现组件传值v-for (值, 索引) in 目标结构 ➡ 循环列表v-show 表达式 ➡ 控制元素显示隐藏v-if 表达式 ➡ 控制元素显示隐藏v-slot ➡ 插槽7. v-show 和 v-if 的区别
共同点 都可以控制元素的显示和隐藏效果一样 区别 原理不同 v-show本质就是通过CSS属性来让元素显示隐藏display: none;v-if动态的 向DOM树 添加 或 删除 元素 编译条件不同 v-show不管条件真假与否都会编译如果是false会将display设置为none但它也编译了v-if初始值为false就不会编译 性能不同 v-show 只编译一次后面就是控制CSS产生更大的首次加载消耗 v-if 不停的销毁和创建实例产生更大的切换消耗 优先级不同 v-if v-show
8. 为什么避免 v-if 和 v-for 一起使用非要在一起使用该怎么办
Vue避免同时使用v-if和v-for是因为这样会影响性能v-for 优先级高于 v-if当v-if和v-for同时存在时v-for会先执行然后才考虑v-if条件。如果列表很长这样会导致不必要的计算影响渲染性能。一起使用 可以先写if再使用template标签包裹需要循环的内容将循环写在template标签上如果非要在一起使用可以考虑使用计算属性来优化性能。计算属性可以先根据条件筛选出需要渲染的数据然后再使用v-for渲染这样可以避免不需要的计算和喧染提高性能。
templatedivdiv v-foritem in filteredList :keyitem.id{{ item.name }}/div/div
/templatescript
export default {data() {return {list: [{ id: 1, name: Apple, show: true },{ id: 2, name: Banana, show: false },{ id: 3, name: Orange, show: true },{ id: 4, name: Grape, show: false },],};},computed: {filteredList() {return this.list.filter((item) item.show);},},
};
/script9. 数组更新有时候v-for不渲染
因为Vue内部只能监测数组 顺序 / 位置 / 数量 的改变如果是某个值被重新赋值或者使用了不改变原始数组的方法没有将返回值对原数据进行赋值Vue是监测不到的 可能会问改变原始数组和不改变原始数组的方法有哪些 针对上述问题有两种解决方案 某个值被重新赋值 this.$set(更新的目标结构, 改变元素的索引 / 对象的属性, 更新的值); 使用不改变原始数组的方法 用得到的新数组替换旧数组。
10. Vue中 key 的作用
当Vue用v-for正在更新已渲染的元素列表时它默认采用“就地复用”策略。列表数据修改的时候它会根据key值去判断某个值是否修改如果修改了则在重新渲染这一项否则复用旧节点key 一段唯一不重复的数字或字符串为了更高效的更新虚拟DOM是给v-for循环生成标签办法唯一标识的key不会出现在真实DOM中 为什么不能使用索引 因为索引是连续的如果删除其中一个会导致最后一个被删除当我们在删除的时候key根据数据来把新旧的DOM做对比删除key不存在的对应的标签。
11. v-for后面为什么要加 :key
在重复渲染的dom上加key可以对dom进行回收利用标记每一个dom用来判断dom节点是否更新比对时第一步如果发现没有key会立即更新创建新的dom如果发现有key第二部就会比对dom结构如果dom结构发生变化那么仍然是就地更新如果dom结构也相同那么第三步就回去比较key利用diff算法看看是否可以重复利用该dom
12. 你知道 dom diff算法吗
dom结构的对比主要使用的是updateChildren方法4个 if-else判断头头比尾尾比头尾比尾头比因为diff主要比对是在循环的过程中而循环需要依赖数组数组的操作会引起视图变化的主要是从头增删、从尾增删、或者反转所以着4个比较的命中会比较高如果匹配新旧的索引都不匹配旧的dom起始索引会直到起始索引大与等于结束索引那么新的起始索引与旧的所有索引就算比较完成等到新的dom起始索引比结束索引大了整个对比就算结束
13. diff算法比较机制
根元素变化删除DOM树重新建立根元素未变 顺序改变 更新属性 子元素/子元素内容改变 按照key比较如果没有key或者key是索引尝试就地更新如果key是id新旧虚拟DOM做对比共有的部分不发生变化没有的就在对应的位置插入DOM节点 key使用规范 有id用id没有id用索引一段唯一不重复的数字或字符串。
14. 说说你对vue的template编辑的理解
简单来说就是先转换成 AST树经过 generate 得到 render 函数render 函数的返回值是 VNode首先通过 compile 编译器把 template 编译成 AST 语法树abstract syntax tree 即源代码的抽象语法结构的树状表现形式compile 是 createCompiler 的返回值createCompiler 是用以创建编译器的。另外 compile 还负责合并 option。然后AST 会经过 generate将 AST 语法树转化成 render funtion 字符串的过程得到 render 函数render 的返回值是 VNodeVNode 是 Vue 的虚拟 DOM 节点里面有标签名、子节点、文本等等
15. 怎么自定指令有哪些钩子函数对应的有哪些入参?
全局注册 在 Vue对象 的 directive 方法里面有两个参数一个指令名称一个回调 / 对象如果是个对象在对象内部必须指定 inserted方法。 // 注册一个全局自定义指令 v-focusVue.directive(focus, {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}})局部注册 组件中接受一个 directives选项。 // 注册局部指令directives: {// 指令名focus: {// 指令的定义inserted: function (el) {el.focus()}}}钩子函数 bind() ➡ 只调用一次指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置inserted() ➡ 被绑定元素插入父节点时调用仅保证父节点存在但不一定已被插入文档中update() ➡ 所在组件的VNode更新时调用但是可能发生在其子VNode更新之前指令的值可能发生变化也肯能没有。但是你可以通过比较前后的值来忽略不必要的模板更新componentUpdated() ➡ 指令所在组建的VNode及其子VNode全部更新后调用unbind() ➡ 只调用一次指令与该元素解绑时调用。钩子函数参数
16. 怎么封装一个组件具体的过程是咋样的
组件提升了整个项目的开发效率能够把页面抽离成相对独立的模块。解决了传统项目开发过程中的效率低、难维护、复用性差等问题组件的封装我们可以看作是一个函数的封装 根据业务需求把页面中可复用的template、script、style抽离到一个单独的 .vue文件 中实现复用上述步骤完成之后还需要考虑入参和出参 入参使用 props机制出参 使用 $emit机制使用 .sync修饰符见5使用 v-model语法糖实现 针对一些标签不确定的地方我们可以使用插槽实现至此组件的封装完成。 组件的使用步骤 封装组件导入组件 import 组件对象 from 组件路径 注册组件 全局注册 Vue.component(组件名, 组件对象) 局部注册常用 使用组件组件标签
17. Vue组件中 data 为什么是个函数
Vue中每个组件都是一个实例组件共享data属性当data的值是同一个引用数据类型的值时改变其中一个会影响其他的组件中的data写成一个函数数据以函数返回值的形式定义这样每复用一次组件就会返回一份最新的data类似于给每个组件实例创建一个私有的数据空间让各个组件实例维护自己的数据单纯的写成对象的形式就会使得所有的组件实例共享一份data就会造成一变全变的结果。
18. Vue组件如何进行传值
组件通信就是组件间的传值无非就是三种情况 父传子、子传父、任意组件间传值 父传子props子传父emitvue提供的方法能实现传值的还有$attr获取传递的所有属性$refs获取组件实例可以进行传值v-mdoel和sync修饰符也能进行传值还有主流的vuex只要写在vuex里面的数据任意组件都可以进行访问还有一些非主流的比如localStorage、sessionStorage、indexDB、WebSQL这种浏览器缓存里也可以做到这种效果不过这种方式有很大的弊端数据不是响应式的一般没什么人使用还有一种就是vuex的数据是挂载在vue对象实例上的而vue实例对象是挂载在window上的所以也可以直接挂载到window对象也能拿到使用基本上就这些传值的方式了
19. Vue该如何实现组件的缓存
为什么需要组件缓存 在面向组件开发中会把整个项目拆分成多个业务组件按照需求对组件进行整合存在组件频繁切换的问题在这个过程中组件的实例都是在不断的销毁和创建很是消耗性能并且如果需要该组件的数据的话我们是获取不到的所以需要对组件的状态进行缓存。 怎么实现组件的缓存 使用 keep-alive 标签包裹需要被缓存的组件会缓存不活动的组件实例主要用于保留组件状态或避免重新渲染优点提高渲染性能提升用户体验。 简单的说: 比如有一个列表和一个详情那么用户就会经常执行打开详情返回列表打开详情…这样的话列表和详情都是一个频率很高的页面那么就可以对列表组件使用keep-alive/keep-alive进行缓存这样用户每次返回列表的时候都能从缓存中快速渲染而不是重新渲染
20. 关于keep-alive说法
keep-alive可以通过include属性匹配要进行缓存的组件当组件在keep-alive内被切换它的activated 和 deactivated这两个钩子函数将会被执行max属性控制最多可以缓存几个组件一旦这个数字达到了在新实例被创建之前已缓存的组件中最久没有被访问的实例会被销毁。
21. Vue中 keep-alive 的作用
keep-alive是Vue内置的一个组件可以使被包裹的组件保留状态或避免重新渲染。一旦使用keep-alive激活组件此时mounted、created等钩子函数只会在第一次进入组件时调用当再次切换回来时将不会调用。此时如果我们还想在每次切换时做一些事情就需要用到另外的周期函数actived 和 deactived这两个钩子函数只有被keep-alive包裹后才会调用。
22. 组件中写 name 选项有什么用
项目中使用 keep-alive 时可以搭配组件 name 进行组件的缓存使用插槽时name 属性可以作为占位标签的名字供 template 使用Vue-devtools调试工具里显示的组件名称是由Vue组件内部的 name 属性决定的。
23. 谈谈对 Vue 生命周期的理解
Vue实例从创建到销毁的整个过程就是Vue的生命周期四个阶段 八个钩子函数初始化阶段 beforeCreate(): 此时data数据和methids方法还没有挂载到Vue实例身上无法使用如果使用了会报错undefined created(): data数据和methods方法已经挂载到Vue实例身上可以正常使用使用场景发起异步请求可以更早的获取数据渲染页面 挂载阶段 beforeMount(): 将App.vue文件中的所有标签编译完毕知识编译完毕还没有变成真实DOM mounted(): 虚拟DOM变成真实DOM此时可以获取DOM节点 更新阶段 beforeUpdate():、 data数据变化后更新此时数据是最新的但是DOM节点还不是最新的 updated(): 当组件渲染完毕后执行此时可以获取最新的DOM内容 销毁阶段 beforeDestroy(): 这一步Vue实例仍然可以使用 destroyed(): 实例销毁后调用该钩子函数被调用后对应的Vue实例的所有指令都被解绑所有的事件监听器被移除所有的子实例也都被销毁。使用场景销毁定时器 单个定时器直接调用 clearInterval() 或 clearTimeout()进行销毁多个定时器在data声明一个对象使用 Object.keys() 获取该对象的所有属性名进行循环销毁。
24. 第一次页面加载会触发哪几个钩子函数
beforeCreate()、created()、beforeMount()、mounted()第一次页面加载需要将data数据和methods方法挂载到Vue实例上并且需要将虚拟DOM变成真实DOM。
25. 父组件嵌套一个子组件第一次加载的时候钩子函数的触发顺序
父创建前后父挂在前子创建前后子挂载前后父挂载后
26. 怎样理解Vue的单向数据流
数据从父组件传递给子组件只能单向绑定子组件内部不能直接修改从父组件传递过来的数据所有的prop都使得其父子prop之间形成一个单向下行绑定 父级prop的更新会向下流动到子组件中但是反过来不行 这样会防止从子组件意外改变父组件的状态从而导致应用的数据流向难以理解额外的每次父组件发生更新时子组件中所有的prop都将会刷新为最新的值这意味着你不应该在一个子组件内部改变prop如果这样做了Vue会在浏览器的控制台中发出警告子组件想修改时只能通过$emit()派发一个自定义事件父组件接收后由父组件修改。
27. style 上加 scoped属性的原理 及 样式穿透原理
什么是scoped 在组件中为了使样式私有化不对全局造成污染可以在 style 标签上添加 scoped 属性以标示它只局限于当前组件 原理 给当前组件添加 data-v-开头的8位随机哈希值的属性Vue中scoped属性的效果主要通过PostCSS转译实现既PostCSS给当前组件内的所有标签添加一个唯一不重复的动态属性然后给选择器额外添加一个属性选择器这个属性选择器是添加到原有选择的后面的。 样式穿透的原理 和 scoped 的原理类似区别 scoped是给当前文件的每一个选择器的后面 添加 属性选择器 样式穿透是给对应的选择器的最前面 添加 属性选择器 28. Vue响应式数据原理双向数据绑定原理 / mvvm原理
原理就是数据劫持 发布订阅数据变化引起视图变化的原理是 数据劫持可以使用Object.definePrototype进行监听模型数据变化当数据变化时会触发set函数发布订阅则是解析模板指令的时候watcher收集所有模板用到的数据添加为订阅者当数据更新时会通知所有订阅者调用自身的update进行试图的更新试图变化引起数据更新的原理是在视图层绑定input事件监听到事件触发时修改对应value值就可以进行数据的更新了 实例代码
let input document.querySelector(input)
let p document.querySelector(p)//定义⼀个对象
let obj {}
let value Object.defineProperty(obj,txt,{//obj.txt属性赋值⽅法同时为input、p⽂本赋同⼀个值set(val) {//数据更新引起视图变化value valinput.value valp.innerHTML val},//获取txt属性的⽅法get() {return value;}
})//监听事件 触发的时候会给obj.txt重新赋值从⽽实现双向绑定
input.addEventListener(keyup,(e){//视图变化更新数据obj.txt e.target.value;
})29. computed、methods、watch之间的区别
computed计算属性 会被挂载到Vue实例身上一个计算属性的值依赖于另外的数据属性计算而来当依赖发生变化的时候计算属性也会发生变化计算属性具有缓存性基于依赖的值进行缓存依赖不发生变化都直接从缓存中取结果当依赖发生变化函数会自动执行并把最新的结果再次缓存所有getter和setter的this上下文自动地绑定为Vue实例不能写异步代码 定义的函数接收return的结果return属于同步执行是没办法拿到异步请求的结果的 methods 会被挂载到Vue实例身上方法中的this指向Vue实例不具有缓存特性 watch 观察和响应Vue实例上的数据变动Vue实例将会在实例化时调用$watch遍历warch对象的每一个属性 三者的加载顺序 computed是在html dom加载后马上执行的methods则必须要有一定的触发条件才能执行watch用于观察Vue实例上的数据变动 默认加载的时候 先computed后watch不执行methods 触发某一事件后 先computed再methods再到watch
30. 说一下$root、$parent、$refs
$root 和 $parent 都能访问父组件的属性和方法区别在于如果存在多级子组件通过$parent访问得到的就是它最近一级的父组件通过$root访问得到的就是根父组件。通过在子组件标签定义的ref属性在父组件中可以使用$refs访问子组件实例。
31. v-model原理
input v-modelusername typetext
input typetext :valueusername inputusername $event.target.value原理 v-model其实是个语法糖相当于用v-bind动态绑定了value属性实现数据驱动视图然后用input事件把视图的值再更新给绑定的valuev-model主要是给表单元素使用有的时候封装组件也可以使用v-model绑定数据比如定义一个组件用props接收value再用$emit()给input传值这个组件就可以被绑定v-model了 如何使用 v-model 封装组件
32. v-model 和 sync修饰符的区别
首先都是用来双向绑定数据的v-model只能使用一次sync修饰符可以给任何一个属性使用v-model传入的是input事件而sync修饰符传入的是update:属性名事件
33. 为什么更新了数据却不能操作dom如何解决
数据更新是同步的视图更新是异步的数据更新会发起一个更新视图的微任务试图不会立即更新所以不能在修改完数据之后立刻操作dom如果试图没有更新可能导致dom获取不到需要将操作dom的代码使用$nextTick()包裹也转换成异步就可以在更新完dom后实现dom操作
34. 什么是 Vue.nextTick()原理是什么
$nextTick是在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法获取更新后的DOM意思是 等你DOM加载完毕以后再去调用nextTick()里面的数据内容。原理 nextTick方法主要使用了宏任务和微任务定义了一个异步方法多次调用nextTick会将方法存入队列中通过这个异步方法清空队列。 作用 nextTick用于下次DOM更新循环结束之后执行延迟回调在修改数据之后使用nextTick用于下次DOM更新循环结束之后执行延迟回调在修改数据之后使用nextTick则可以在回调中获取更新后的DOM。 $nextTick本质是返回一个Promise
35. Vue中template的编译过程
vue template模板编译的过程经过parse()生成ast(抽象语法树)optimize对静态节点优化generate()生成render字符串之后调用new Watcher()函数用来监听数据的变化render函数就是数据监听的回调所调用的其结果便是重新生成Vnode如果是数据的更新那么Vnode会与数据改变之前的Vnode做diff对内容做改动之后就会更新到我们真正的DOM
36. new Vue的时候做了什么事 初始化 执行 init 操作。包括但不限于 initLifecycle、initState 等 挂载 执行 mounted 进行元素挂载 编译 compiler 对 template 属性进行编译通过 vue-loader 处理生成 render 函数 渲染 执行 render 函数生成 vnode 补丁 patch。新旧 vnode 经过 diff 后渲染到真实dom上 可以看看这位大佬写的
37. axios是什么怎么使用描述使用它实现登录功能的流程
axios是请求后台资源的模块。通过npm install axios -S来安装在大多数情况下我们需要封装拦截器在实现登录的过程中我们一般在请求拦截器中来加入token在响应拦截器中通过后端返回的状态码来对返回的数据进行不同的处理。
// TODO 封装请求拦截器
axios.interceptors.request.use(config {// TODO 在发送请求之前做一些事return config
}, error {// TODO 处理请求错误return Promise.reject(error)
})// TODO 封装响应拦截器
axios.interceptors.response.use(response {// TODO 位于2xx范围内的任何状态码都会触发此函数// TODO 对响应数据做处理return response
}, error {// TODO 任何超出2xx范围的状态码都会触发此函数// TODO 做一些响应错误的事情return Promise.reject(error)
})38. 对axios进行二次封装 import axios from axiosconst request axios.create({baseURL: ,timeout: 5000})// 参数是个函数// 请求拦截器request.interceptors.request.use()// 响应拦截器request.interceptors.response.use()export default request39. Vue中的路由模式
hash模式 url带有#号#以及#后面的称为hash用 window.location.hash 读取对浏览器安全无用通过 onhashchange 事件监听url修改特点 hash虽然在url中但不被包括在http请求中用来指导浏览器动作对服务端安全无用hash不会重加载页面 history模式 url没有#号history采用H5的新特性且提供了两个新方法 pushState() 和 replaceState()可以对浏览器历史记录栈进行修改以及popState事件可以监听到状态变更 切换模式 在 new VueRouter() 里面增加 mode 属性属性值为 hash 或 history。
40. 路由配置项常用的属性
path ➡ 展示的url
component ➡ 和path对应的组件路径可以使用 () import(组件路径)
name ➡ 命名路由
children ➡ 子路由的配置对象路由嵌套
props ➡ 路由解耦
redirect ➡ 重定向路由
meta ➡ 路由元信息41. 路由跳转的方式
声明式导航
router-link to需要跳转到页面的路径 /编程式导航
this.$router.push() ➡ 跳转到指定的url并在history中添加记录点击回退到上一个页面
this.$router.go(n) ➡ 向前或向后跳转n个页面n可以是正数也可以是负数
this.$router.replace() ➡ 跳转到指定的url但是history中不会添加记录点击回退到上上个页面
this.$router.back() ➡ 回退到上一个页面42. 路由传参的方式有哪些
Vue-Router传参可以分为两大类分别是编程式导航和声明式导航 编程式导航 name 和 params 搭配传参this.$router.push({ name: news, params: { userId: 123} })path 和 query 搭配传参this.$router.push({ path: /news, query: { userId: 123 } }) 声明式导航 命名路由 router-link to{ name: news, params: { userId: 123 } }/router-link 查询参数 router-link to{ path: /news, query: { userId: 123 } }/router-link
43. $route 和 $router 的区别
都是在注册路由的时候提供的两个全局对象$route 路由信息对象;包括path、hash、query、params、name等路由信息参数表示当前激活的路由对象 $router VueRouter的实例;相当于一个全局的路由对象里面包含很多属性和子对象如history对象经常用的跳转链接就可以用this.$router.push()会往history栈中添加一个新的记录返回上一个history也是使用this,$router.go()等方法。
44. query 和 params之间的区别
query 和 path 配合使用接收参数的时候使用 this.$route.query.属性名 params 和 name 配合使用接收参数的时候使用 this.$route.params.属性名
45. Vue-Router 有哪几种路由守卫
全局前置守卫beforeEach()全局后置守卫afterEach()单个路由独享的钩子beforeEnter()组件路由守卫相关的钩子 beforeRouterEnter()beforeRouterUpdate()beforeRouterLeave() 入参 to即将要进入的目标路由对象去哪里form当前导航即将离开的路由对象next调用该方法才能进入下一个钩子函数afterEach next()通过next(url)跳到指定地址 router.beforeEach(async (to, from, next) {// 相关逻辑// next()必须执行但是参数可能不同})46. 如何实现动态路由
路由一般分为静态路由和动态路由静态路由 也可以叫做白名单路由指的是不需要权限就能访问的页面一般都是提前定义好的 动态路由 需要前端进行处理一般都是根据后台返回的路由匹配规则然后在所有的路由中可以利用路由的name属性与权限点匹配的规则筛选出可以访问的路由通过router.addRoutes添加就可以了
47. 如何监测动态路由的变化
可以通过watch方法对$route进行监听或者通过导航守卫的钩子函数beforeRouteUpdate(to, from, next)来监听它的变化。
48. Vue-Router中的router-link上v-slot属性怎么使用
router-link通过一个作用域插槽暴露底层的定制能力。这是一个更高阶的API。主要面向库作者但也可以为开发者提供便利多数情况用在一个类似NavLink这样的自定义组件里有时我们可能想把激活的 class 应用到一个外部元素而不是a标签本身这时可以在一个router-link中包裹该元素并使用v-slot属性来创建链接
router-linkto/foocustomv-slot{ href, route, navgiate, isActive, isExactActive }
li:class[isActive router-link-active,isExactActive router-link-exact-active ]a :hrefhref clicknavigate{{ route.fullPath }}/a/li
/router-link49. 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的重新渲染。
50. 你是怎么认识Vuex的
Vuex可以来理解为一种开发模式或框架通过状态集中管理驱动组件的变化应用级的状态几种放在state中改变状态的方式是提交mutations这里必须是同步的异步逻辑应该封装在action中
51. 为什么使用Vuex
项目比较大以往的关系组件通信进行数据的传递很麻烦不方便状态的统一管理实现数据的共享实现非关联组件之间的通信。
52. Vuex的5个核心属性
分别是module、state、mutation、action、getter
modules 模块化其实只是解决了当 state 中很复杂臃肿的时候module可以将store分隔成模块每个模块拥有自己的state、mutation、action、getter state 状态管理定义变量在state中定义我们需要管理的数据只有在这里定义了在Vue的组件中才能获取到定义数据的状态使用 不使用辅助函数 this.$store.state.模块名.变量名 辅助函数 mutations 同步修改state定义在mutations中的方法有两个入参分别是state 和 payload使用 不使用辅助函数 this.$store.commit(模块名/方法名, 需要传递的数据) 辅助函数 actions 异步修改state使用commit方法将数据提交给mutations中的方法进行修改定义在actions中的方法有两个入参分别是context 和 payload使用 不使用辅助函数 this.$store.dispatch(模块名/方法名, 传递的数据) getters 类似于Vue的计算属性当我们需要从store的state中派生一些状态那么我们就需要使用gettergetter会接受state作为第一个参数而且getter的返回值会根据它的依赖被缓存起来只有getter中的依赖值发生改变的时候才会被重新计算getters中的方法有两个入参分别是state 和 payload在srore下新建getters.js文件
53. 为什么需要对Vuex持久化
vuex中的数据在页面刷新后就没有了要实现数据的长久保存可以通过浏览器的本地存储能力实现 cookielocalStorage
54. Vuex可以直接修改state的值吗
可以直接修改但是及其不推荐state的修改必须在mutation来修改否则无法被devtools所监测无法监测数据的来源无法保存状态快照也就无法实现时间漫游 / 回滚之类的操作。
55. Vuex的mutation和action之间的区别是什么
功能不同 mutation专注于修改state理论上是修改state的唯一途径action专注于业务代码可以发异步请求 限制 mutation必须同步执行action可以异步但不能直接修改state
56. 为什么Vuex的mutation不能做异步操作
Vuex中所有的状态更新的唯一途径都是mutation异步操作通过Action来提交mutation实现这样使得我们可以方便地跟踪每一个状态的变化从而让我们能够实现一些工具帮助我们更好地了解我们的应用每个mutation执行完成后都会对应一个新的状态变更这样devtools就可以打个快照存下来否则无法被devtools所监测如果mutation支持异步操作就没有办法知道状态是何时更新的无法很好的进行状态的追踪给调试带来困难。
57. Vue单页面应用的优缺点
优点 内容的改变不需要重新加载整个页面web应用更具响应性没有页面之间的切换就不会出现“白屏现象”也不会出现假死并没有“闪烁”现象相对服务器压力小服务器只用出数据就可以不用展示逻辑和页面合成吞吐能力会提高几倍良好的前后端分离。后端不再负责模板渲染、输出页面工作。后端API通用化既一套后端程序代码不用修改可以用于Web界面、手机、平板等多种客户端。 缺点 首次加载耗时比较长SEO问题不利于百度360等搜索引擎收录容易造成Css命名冲突前进、后退、地址栏、书签等都需要程序进行管理页面的复杂程度很高需要一定的技能水平和开发成本。
58. 如何对首屏加载实现优化
把不常用的库放到index.html中使用cdn引入使用懒加载Vue组件避免全局注册使用更轻量级的工具库预渲染减少http请求开启gzip压缩。
59. 对SPA单页面的理解它的优缺点分别是什么
单页Web应用是一种特殊的Web应用。他将所有的活动局限于一个web页面中仅在该Web页面初始化时加载相应的HTML、JavaScript和CSS一旦页面加载完成SPA不会因为用户的操作而进行页面的重新加载或跳转。取而代之的是利用JavaScript动态的变换HTML的内容从而实现UI与用户的交互。由于避免了页面的重新加载SPA可以提供较为流畅的用户体验。得益于Ajax我们可以实现无跳转刷新又多亏了浏览器的history机制我们用hash的变化从而可以实现推动界面变化从而模拟元素客户端的单页面切换效果优点 单页面应用的内容的改变不需要重新加载整个页面Web应用更具响应性单页面没有页面之间的切换就不会出现“白屏现象”也不会出现假死并没有“闪烁”现象单页面应用相对服务器压力小服务器只用出数据就可以不用管展示逻辑和页面和声吞吐能力会提高几倍良好的前后端分离。后端不再负责模板渲染、输出页面工作后端API通用化既同一套后端程序代码不用修改就可以用于Web界面、手机、平板等多种客户端。 缺点 首次加载耗时比较多不利于SEO优化各个浏览器的版本兼容性不一样业务随着代码量增加而增加不利于首屏优化前进、后退、地址栏、书签等都需要程序进行管理页面的复杂程度很高需要一定的技能水平和开发成本。
60. 项目优化
减少http请求减少DOM操作使用JSON格式来进行数据的交换使用CDN加速优化代码减少代码体积服务端渲染。
61. VNode是什么什么是虚拟DOM
VNode是什么 VNode 是 JavaScript 对象VNode 表示 Virtual DOM用 JavaScript 对象来 描述真实的 DOM把 DOM 标签、属性、内容都变成对象的属性。就像使用 JavaScript对象对一种动物进行说明一样 VNode的作用 通过 render 将 template 模版描述成 VNode然后进行一系列操作之后形成真实的DOM进行挂载 VNode的优点 兼容性强不受执行环境的影响。VNode 因为是 JS 对象不管 Node 还是浏览器都可以统一操作从而获得了服务端渲染、原生渲染、手写渲染函数等能力减少操作 DOM任何页面的变化都只使用 VNode 进行操作对比只需要在最后一步挂载更新 DOM不需要频繁操作 DOM从而提高页面性能 什么是虚拟DOM 文档对象模型或 DOM 定义了一个接口该接口允许 JavaScript 之类的语言访问和操作 HTML 文档。元素由树中的节点表示并且接口允许我们操纵它们。但是此接口需要付出代价大量非常频繁的 DOM 操作会使页面速度变。Vue 通过在内存中实现文档结构的虚拟表示来解决此问题其中虚拟节点VNode表示 DOM 树中的节点。当需要操纵时可以在虚拟 DOM 的 内存中执行计算和操作而不是在真实 DOM 上进行操纵。这自然会更快并且允许虚拟 DOM 算法计算出最优化的方式来更新实际 DOM 结构,一旦计算出就将其应用于实际的 DOM 树这就提高了性能这就是为什么基于虚拟 DOM 的框架例如 Vue 和 React如此突出的原因。
62. 如何对Vue首屏加载实现优化
把不常改变的库放到 index.html 中通过 cdn 导入Vue路由的懒加载Vue组件尽量不要全局引入使用更轻量级的工具库开启gzip压缩首页单独做服务端渲染
63. Vue中怎么重置data
要初始化 data 中的数据可以使用 Object.assign()方法实现重置 data 中的数据Object.assign()方法基本定义 Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象赋值到目标对象他将返回目标对象用法Object.assign(target, ...sources) 第一个参数是目标对象后面的参数是源对象可以有多个就是将源对象属性复制到目标对象返回目标对象 具体实现 使用 Object.assign()vm.$data 可以获取当前状态下的 data vm.$options.data(this) 可以获取到组件初始化状态下的 data 复制Object.assign(this.$data, this.$options.data(this))❗ 注意加 this不然取不到 data(){ a: this.methodA } 中的 this.methodA。
64. Vue2 和 Vue3 的区别
API不同 Vue2采用选项式API对于代码阅读、维护、逻辑复用不是太友好可以通过minix实现逻辑复用Vue3采用组合式API功能代码组合在一起方便维护、逻辑复用 使用 Vue2配合vuex对于TS的支持不是很好Vue3配合pinia底层是使用TS重构的对TS支持很好
根节点数目 Vue2只能有一个根节点 因为vdom是一棵单根树型结构pacth方法在遍历的时候从根节点开始遍历他要求只有一个根节点组件也会转换为一个vdom自然应该满足这个要求。 Vue3可以有多个根节点 Vue3中引入了Fragment的概念这是一个抽象的节点如果发现组件是多个根节点就创建一个 Fragment节点把多个根节点作为它的children。将来patch的时候如果发现是一个Fragment节点则直接遍历children创建或更新。 数据双向绑定原理不同 Vue2采用Object.definePropertyVue3采用ES6新增的Proxy 生命周期不同Vue2 Vue3beforeCreate() setup()
Created() setup()
beforeMount() onBeforeMount()
mounted() onMounted()
beforeUpdate() onBeforeUpdate()
updated() onUpdated()
beforeDestroyed() onBeforeUnmount()
destroyed() onUnmounted()
activated() onActivated()
deactivated() onDeactivated()v3性能比v2快 v3采用静态标记给静态节点打上标记diff的过程只对比动态节点忽略静态节点虚拟dom的创建 v2中数据发生变化会将模板进行重编译生成所有的虚拟domv3中数据发生变化看该dom是否参与更新如果参与更新创建新的虚拟dom如果不参与更新直接复用上一次的虚拟dom