面试总结(vue整理)

149 阅读12分钟

vue

  1. vue生命周期
  2. vue数据双向绑定的原理
  3. vue数组数据更改了,视图没更新,为什么怎么解决
  4. 父子组件的生命周期顺序
  5. vue组件通信的方法
  6. computed 和 watch区别
  7. nexTick的原理
  8. vue修改一个数据后面会发生什么
  9. vue的修饰用过哪些
  10. vuex中actions和mutations的区别
  11. v-model的定义使用
  12. vue组件封装需要考虑什么(数据同步更改)
  13. v-for v-if 一起使用的优先级
  14. vue路由跳转的方式和区别
  15. vue3的新特性
  16. vue的diff算法(vue2和vue3)
  17. vue3和vue2的区别
  18. 递归组件
  19. vue的自定义指令
  20. vue的 mixin使用
  21. vue-router(路由原理?路由守卫?)
  22. 单页面应用和多页面应用区别以及优缺点
  23. Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?
  24. vuex和pinia的优劣势

答案记录

1. vue生命周期

image.png image.png

2. vue数据双向绑定的原理

vue2 通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发响应的监听回调

vue3 使用proxy进行双向绑定,proxy提供了可以定义对象基本操作的自定义行为的功能(如属性查找、赋值、枚举、函数调用),可以直接拦截整个对象,不需要再进行递归;

3. vue数组数据更改了,视图没更新,为什么怎么解决

是因为直接对元素深层做修改,数据更新了,但是页面不会同步更新
vue2 使用$set()方法进行更新 或者 借助第三个变量来修改,let a = this.b; this.b = a;

4. 父子组件的生命周期顺序

  • 加载渲染过程 执行的先后顺序为 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted。
  • 子组件更新过程 父beforeUpdate->子beforeUpdate->子updated->父updated
  • 父组件更新过程  父beforeUpdate->父updated
  • 销毁过程  父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

5. vue组件通信的方法

  • props和$emit(常用)
  • vuex(常用)
  • parentparent和children
  • provide和inject
  • attrsattrs和listeners
  • v-model
  • 中央事件总线(非父子组件间通信)

6. computed 和 watch区别

  • 如果一个数据需要经过复杂计算就用 computed computed不使用它是不会执行的,而且计算属性如果依赖不变的话,它就会变成缓存
  • 如果一个数据需要被监听并且对数据做一些操作就用 watch

7. nexTick的原理

参考地址 blog.csdn.net/longtengg1/… www.cnblogs.com/sexintercou…

8. vue修改一个数据后面会发生什么

修改数据后,会触发对象的set方法,会通知watcher,从而触发watcher的update方法,update方法内会将watcher添加进watcher队列,执行nexttick,把清空wacher队列的方法加入到微任务,等待同步事件执行完成后,浏览器就会执行微任务,从而更新dom。

所以何时更新dom就看同步事件何时执行完,定时器是宏任务,每执行完一次定时器都会更新一次dom

9. vue的修饰用过哪些

参考地址 juejin.cn/post/698162…

10. Mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutatio

actions 1、用于通过提交mutation改变数据 2、会默认将自身封装为一个Promise 3、可以包含任意的异步操作 mutations 1、通过提交commit改变数据 2、只是一个单纯的函数 3、不要使用异步操作,异步操作会导致变量不能追踪

Mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,

11. v-model的定义使用

参考地址 juejin.cn/post/703585… juejin.cn/post/702854…

12. vue组件封装需要考虑什么(数据同步更改)

Vue组件的API主要包含三部分:prop、event、slot

  • props 表示组件接收的参数,最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,此外还可以通过type、validator等方式对输入进行验证
  • slot可以给组件动态插入一些内容或组件,是实现高阶组件的重要途径;当需要多个插槽时,可以使用具名slot
  • event是子组件向父组件传递消息的重要途径 参考地址 juejin.cn/post/684490…

13. v-for v-if 一起使用的优先级

在 vue 2.x 中, 在一个元素上同时使用 v-if 和 v-for 时, v-for 会优先作用。
在 vue 3.x 中, v-if总是优先于 v-for 生效

14. vue路由跳转的方式和区别

方案一:声明式导航router-link

1.1不带参数

<router-link :to="{name:'home'}">  
<router-link :to="{path:'/home'}"> //name,path都行, 建议用name 

1.2带参数:

<router-link :to="{name:'home', params: {id:1}}">
<router-link :to="{name:'home', query: {id:1}}">  
<router-link :to="/home/:id">  
//传递对象
<router-link :to="{name:'detail', query: {item:JSON.stringify(obj)}}"></router-link> 

方案二:编程式导航 this.$router.push()

不带参数

this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})

query传参

跳转:
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
获取参数
html取参: $route.query.id
script取参: this.$route.query.id

params传参

跳转:
this.$router.push({name:'home',params: {id:'1'}})
注意:
// 只能用 name匹配路由不能用path
// params传参数(类似post)  路由配置 path: "/home/:id" 或者 path: "/home:id"否则刷新参数消失
获取参数
html取参:$route.params.id 
script取参:this.$route.params.id

直接通过path传参(动态路由)

跳转:
this.$router.push({path:'/home/123'}) 
或者:
this.$router.push('/home/123') 
获取参数:
this.$route.params.id

传递对象(obj不能过长否则会报错) arams和query的区别

query类似 get,跳转之后页面 url后面会拼接参数,类似?id=1。
非重要性的可以这样传,密码之类还是用params,刷新页面id还在。
params类似 post,跳转之后页面 url后面不会拼接参数。

方案三:this.$router.replace()

用法和this.$router.push()相同 区别 push本质是向history栈中添加一个路由,在我们看来是切换路由,但本质是在添加一个history记录; replace 替换路由,没有历史记录,点击返回,会跳转到上上一个页面

方案四:this.$router.go(n)

向前或者向后跳转n个页面,n可为正整数或负整数

总结:

1.query可以用namepath匹配路由,通过this.$route.query.id获取参数,刷新浏览器参数不会丢失
2.params只能用name匹配路由,通过path匹配路由获取不到参数,对应的路由配置path:'/home/:id'或者path:'home:id',否则刷新浏览器参数丢失
3.直接通过url传参,push({path: '/home/123'})或者push('/home/123'),对应的路由配置path:'/home/:id',刷新浏览器参数不会丢失

15. vue3的新特性

  1. 双向响应原理使用es6的Proxy\
  2. 由于不能在setup函数中使用datamethods,为了避免使用Vue出错,所以把setup函数中this修改为了undefined\
  3. setup 是 Vue3.x 新增的一个选项, 他是组件内使用 Composition API的入口。\
  4. 组合api,可以把相关的数据和方法放在一块,\
  5. 数据定义使用 reactive、ref 与 toRefs\
  6. defineProps 和 defineEmit来声明 props 和 emits\
  7. watch 与 watchEffect 的用法 \
  8. 不再限制 template 只有一个根节点。\
  9. Teleport 的使用可以使我们的组件可以挂载在指定的dom下面\
  10. Suspense 只是一个带插槽的组件,只是它的插槽指定了default 和 fallback 两种状态。\
  11. 对ts支持 \
  12. css内部可以直接引用js的变量
.text {
  color: v-bind(color);
}
  1. 使用 <script setup> 的组件是默认关闭的,为了在 <script setup> 组件中明确要暴露出去的属性,使用 defineExpose 编译器宏
<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

defineExpose({
  a,
  b
})
</script>

16. vue的diff算法(vue2和vue3)

参考juejin.cn/post/691937… juejin.cn/post/696986… vue3 增加了静态标签(即标签内没有引用变量)跳过比较

17. vue3和vue2的区别

参考上面的vue3特性

18. 递归组件

组件内部调用自身组件,常用导航菜单的组件,树选择器等

19. vue的自定义指令

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。 指令钩子函数会被传入以下参数

  • el: 指令所绑定的元素,可以用来直接操作 DOM,就是放置指令的那个元素。

  • binding: 一个对象,里面包含了几个属性,这里不多展开说明,官方文档上都有很详细的描述。

  • vnode:Vue 编译生成的虚拟节点。

  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。 原文地址: juejin.cn/post/684490…

20. vue的 mixin使用

mixin是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项

与vuex的区别

  • vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。
  • Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。

与公共组件的区别

  • 组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。
  • Mixins:则是在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。

21. vue-router(路由原理?路由守卫?)

路由原理

路由就是用来解析URL以及调用对应的控制器,并返回从视图对象中提取好的网页代码给web服务器,最终返回给客户端。

hash模式:在浏览器中符号的“#”,以及#后面的字符称之为hash,用window.location.hash读取;

特点: hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。

hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),

replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。

特点:

history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 地址后加上/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。

路由传参:

三种:

分别是query,params,动态路由传参

接收:

  • 通过query方式传递过来的参数一般是通过this.$route.query接收
  • 通过params方式传递过来的参数一般是通过this.$route.params接收
  • 通过动态路由传参方式传递过来的参数一般是通过this.$route.params接收
  • query使用path和name传参跳转都可以,而params只能使用name传参跳转。
  • 传参跳转页面时,query不需要再路由上配参数就能在新的页面获取到参数,params也可以不用配,但是params不在路由配参数的话,当用户刷新当前页面的时候,参数就会消失。
  • 也就是说使用params不在路由配参数跳转,只有第一次进入页面参数有效,刷新页面参数就会消失。

路由守卫:

2.路由守卫使用的方式有几种? 全局的 单个路由独享的 组件级的

3.vue-router全局有三个守卫:

  • router.beforeEach 全局前置守卫 进入路由之前
  • router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
  • router.afterEach 全局后置钩子 进入路由之后

组件内的守卫: beforeRouteEnter beforeRouteUpdata(2.2新增) beforeRouteLeave

  1. 路由守卫钩子函数里面的三个参数分别是什么?
  • to,from,next 这三个参数:
  • to和from是将要进入和将要离开的路由对象,路由对象指的是平时通过this.$route获取到的路由对象。
  • next:Function 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)。
  • next() 进入该路由。
  • next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。 next 跳转新路由,当前的导航被中断,重新开始一个新的导航。

原文链接:blog.csdn.net/weixin_6146…

22. 单页面应用和多页面应用区别以及优缺点

单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。

多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新

单页面的优点:

  1. 用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小
  2. 前后端分离
  3. 页面效果会比较炫酷(比如切换页面内容时的专场动画) 单页面缺点:
  4. 不利于seo
  5. 导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
  6. 初次加载时耗时多
  7. 页面复杂度提高很多 转载 blog.csdn.net/weixin_4185…

23. Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?

如果也没有引用就不会更新视图, 如果这个数据被其他计算属性依赖且页面引用了,就会先更新执行计算属性然后去试图更新

24. vuex和pinia的优劣势

Pinia 是 Vue.js 的轻量级状态管理库,它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库 Vuex的优点

  • 支持调试功能,如时间旅行和编辑
  • 适用于大型、高复杂度的Vue.js项目 Vuex的缺点
  • 从 Vue 3 开始,getter 的结果不会像计算属性那样缓存
  • Vuex 4有一些与类型安全相关的问题

Pinia的优点

  • 完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易
  • 极其轻巧(体积约 1KB)
  • store 的 action 被调度为常规的函数调用,而不是使用 dispatch 方法或 MapAction 辅助函数,这在 Vuex 中很常见
  • 支持多个Store
  • 支持 Vue devtools、SSR 和 webpack 代码拆分 Pinia的缺点
  • 不支持时间旅行和编辑等调试功能

由于Pinea是轻量级的,体积很小,它适合于中小型应用。 Vuex 用于中小型 Vue.js 项目是过度的,因为它重量级的,对性能降低有很大影响。因此,Vuex 适用于大规模、高复杂度的 Vue.js 项目。