当前位置: 首页 > news >正文

最近常问的70道vue相关面试题

文章目录

    • 1. 谈谈你对MVVM开发模式的理解?
    • 2. v-if 和 v-show 有什么区别?
    • 3. route和router区别
    • 4. vue⾃定义指令
    • 5. vue项⽬优化
    • 6. vue模板如何编译
    • 7. vue2响应式原理
    • 8. vue3响应式原理
    • 9. 刷新浏览器后,Vuex的数据是否存在?如何解决?
    • 10. vue和react共同点?区别
    • 11. vue双向数据绑定原理
    • 12. computed和watch区别
    • 13. Vuex
    • 14. vuex辅助函数
    • 15. vuex模块化使⽤
    • 16. vue中mixin
    • 17. Vue中给对象添加新属性时,界⾯不刷新怎么办?
    • 18. vue组件通讯⽅式
    • 19. vue3setup的⽗传⼦怎么去写?
    • 20. setup可不可以直接写async和await?
    • 21. vue⽣命周期
    • 22. 说说 Vue 中 CSS scoped 的原理
    • 23. $nextTick原理
    • 24. data是函数不是对象
    • 25. 路由守卫
    • 26. vue设置全局变量
    • 27. vue中keep-alive
    • 28. vue插槽
    • 29. vue2和vue3区别
    • 30. Vue3.0 所采⽤的 Composition Api (组合式)与 Vue2.x 使⽤的 Options Api(选项式) 有什么不同?
    • 31. vue3中hook
    • 32. vue组件和插件的区别
    • 33. vue修饰符
    • 34. Vue路由中,history和hash两种模式有什么区别?
    • 35. params和query区别
    • 36. vue2中assets和vue3中public区别 ?
    • 37. 单⻚应⽤如何提⾼加载速度?
    • 38. Vue⽗组件调⽤⼦组件的⽅法
    • 39. vue3中dom获取,ref在组件上使⽤
    • 40. 渐进式框架理解
    • 41. ⻚⾯初始化闪烁
    • 42. vue属性名和method名称⼀致出现什么问题
    • 43. class和style如何动态绑定
    • 44. vue遇到的坑
    • 45. v-if和v-for 优先级
    • 46. vue核⼼原理
    • 47. vue⾃带动画组件, transition
    • 48. vue-loader⼯作原理
    • 49. vue的diff算法
    • 50. vue和jquery区别
    • 51. 说说你对 SPA 单⻚⾯的理解,它的优缺点分别是什么?
    • 52. 怎样理解 Vue 的单向数据流?
    • 53. ⽗组件可以监听到⼦组件的⽣命周期吗?
    • 54. Vue3.0 性能提升主要是通过哪⼏⽅⾯体现的
    • 55. 什么是 MVVM?⽐之 MVC 有什么区别?什么⼜是 MVP ?
    • 56. vue中hook和react中hook区别
    • 57. Redux和Vuex的区别
    • 58. vue服务端渲染(SSR),解决了哪些问题?
    • 59. Vue 3.0中Treeshaking特性是什么,并举例进⾏说明?
    • 60. 虚拟 DOM 的优缺点?
    • 61. 虚拟 DOM 实现原理?
    • 62. Vue 中的 key 有什么作⽤?
    • 62. Object.defineProperty怎么⽤, 三个参数?,有什么作⽤啊?
    • 63. reactive与ref的区别?
    • 64. v-on可以监听多个⽅法吗?
    • 65. vue3中如何获取refs,dom对象的⽅式?vue2中如何使⽤?
    • 66. shallowReactive和shallowRef的区别
    • 67. provide与inject如何使⽤
    • 68. toRaw 与 markRaw是什么作⽤?
    • 69. Readonly和shallowReadonly理解
    • 70. toref和torefs区别
    • 71. 学习 EventBus
    • 72. vue2过滤器(vue3取消)

1. 谈谈你对MVVM开发模式的理解?

MVVM是⼀种简化⽤⼾界⾯的实践驱动编程⽅式。在当前主流的前后端分离的开发模式中,MVVM模式的优越性⽇益体现,相较于经典的MVC模式,其对于程序模块的封装很好地解决了前后端信息交互的冗余和繁琐。

MVVM分为ModelViewViewModel三者。

Model     代表数据模型,数据和业务逻辑都在Model层中定义;
View      代表UI视图,负责数据的展⽰;
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理⽤⼾交互操作;

Model 和 View 并⽆直接关联,⽽是通过 ViewModel 来进⾏联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于⽤⼾交互操作⽽改变的数据也会在 Model 中同步。

这种模式实现了 Model 和 View 的数据⾃动同步,因此开发者只需要专注对数据的维护操作即可,⽽不需要⾃⼰操作 dom。

为什么使⽤MVVM:低耦合,可复⽤,独⽴开发,可测试

2. v-if 和 v-show 有什么区别?

⼿段

v-if是动态的向DOM树内添加或者删除DOM元素;
v-show是通过设置DOM元素的display样式属性控制显隐;

编译

v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第⼀次变为真时才开始局部编译;
v-show是在任何条件下,⽆论⾸次条件是否为真,都被编译,然后被缓存,⽽且DOM元素保留;

性能消耗:

v-if有更⾼的切换消耗;
v-show有更⾼的初始渲染消耗
v-if指令可以应⽤于template包装元素上,v-show不⽀持

3. route和router区别

$route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数

$router 是“路由实例”想要导航到不同URL 对象包括了路由的跳转⽅法,钩⼦函数等。通过push、replace、go、back等⽅法,来实现⻚⾯间的跳转

4. vue⾃定义指令

vue2
局部注册:directive选项

directives: {'focus': {bind(el, binding, vnode) {el.focus()}}
}

全局注册:main.js

Vue.directives('focus',{bind(el, binding, vnode) {el.focus()}
})

⽣命周期:

bind:只调⽤⼀次,指令第⼀次绑到元素调⽤,⽤于初始化
inserted:被绑定元素插⼊⽗节点时调⽤
update:所在组件vnode更新调⽤
componentUpdate:指令在组件的vnode及⼦组件的vnode全部更新完调⽤
ubind:只调⽤⼀侧,指令解绑

vue3

局部注册:引⼊ import { Directive , DirectiveBinding } from ‘vue’ 分别校验vFocus,binding

<template>
<input type="text" v-focus="{ color: 'red' }" />
</template>
<script setup>
const vFocus = {created(el, binding) {el.style.backgroundColor = binding.value.color;console.log(el, binding.value.color); //<input type="text" style="background-color: red;"> 'red'},
};
</script>

全局注册:main.js,app.vue如上引⼊

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.directive('focus', {created(el, binding) {el.style.backgroundColor = binding.value.color;console.log(el, binding.value.color); //<input type="text" style="background-color: red;">'red'}
})

app.mount(‘#app’)

⽣命周期:

created 元素初始化的时候
beforeMount 指令绑定到元素后调⽤ 只调⽤⼀次
mounted 元素插⼊⽗级dom调⽤
beforeUpdate 元素被更新之前调⽤ update 这个周期⽅法被移除 改⽤updated
beforeUnmount 在元素被移除前调⽤ unmounted 指令被移除后调⽤ 只调⽤⼀次

5. vue项⽬优化

代码层⾯
⻓列表性能优化: Object.freeze ⽅法来冻结⼀个对象,⼀旦被冻结的对象就再也不能被修改了
事件销毁, beforeDestroy⽣命周期函数内执⾏销毁逻辑。
图⽚懒加载
路由懒加载
按需加载插件
v-if,v-for避免同时使⽤,v-for遍历添加key
v-if,v-show选择
keep-alive组件缓存
input防抖节流
基础的web技术优化
开启gzip压缩
浏览器缓存
CDN加速
webpack优化

6. vue模板如何编译

Vue的模板编译就是将“HTML”模板编译成render函数的过程。这个过程⼤致可以分成三个阶段

解析阶段:“HTML”模板解析成AST语法树
核⼼ parseHTML( template ,{}) Vue定义了很多匹配HTML的正则表达式 ,parseHTML根据正则匹配

parseHTML是解析模板字符串的“主线程”,它的第⼀个参数是要解析的模板字符串, 也就是单⽂件组件中最外层所包裹的部分;第⼆个参数是⼀个选项对象,它会包含⼀些回调,以及⼀些配置项。

选项对象:

start( tag, attrs, unary )
匹配到开始标签时的回调,tag为当前标签的标签名,attrs为该标签上的属性列表,unary为当前标签是否为⾃闭合标签 end()
匹配到结束标签时的回调 chars(text) 匹配到⽂本节点的回调 comment(text)
匹配到注释节点的回调,其处理逻辑跟⽂本的处理逻辑类似

优化阶段:AST语法树中找出静态⼦树并进⾏标记(被标记的静态⼦树在虚拟dom⽐对时会被忽略,从⽽提⾼虚拟dom⽐对的性能);
上⾯简单介绍过,优化阶段的⼯作就是标记静态⼦树,标记静态⼦树后主要有以下两个优点:
⽣成虚拟dom的过程中,如果发现⼀个节点是静态⼦树,除了⾸次渲染外不会⽣成新的⼦节点树,⽽是拷⻉已存在的静态⼦树;

⽐对虚拟dom的过程中,如果发现当前节点是静态⼦树,则直接跳过,不需要进⾏⽐对。
标记静态⼦树的过程分为两个步骤:

遍历AST语法树,找出所有的静态节点并打上标记(注:当前节点及其所有⼦节点都是静态节点,当前节点才会被打上静态节点的标记)
遍历经过上⾯步骤后的树,找出静态根节点,并打上标记(注:静态根节点是指本⾝及所有⼦节点都是静态节点,但是⽗节点为动态节点的节点,找到了静态根节点也就找到了“静态⼦树”)

代码⽣成阶段:通过AST⽣成代码字符串,并最终⽣成render函数。

7. vue2响应式原理

vue 采⽤了⼏个核⼼部件 : ObserverDepWatcherScheduler

  • observer把⼀个普通的对象转换成响应式的对象
    observer 把对象的每个属性通过 object.defineProperty 转换为带有 getter 和 setter 的属性
  • Dep 表⽰依赖, vue 会为响应式对象中的每⼀个属性,对象本⾝,数组本⾝创建⼀个 dep 实例,每个dep 实例都可以做两件事情 :

记录依赖:是谁在⽤我
派发更新:我变了,我要通知那些⽤我的⼈

  • watcher 在函数执⾏的过程中,如果发⽣了依赖记录,那么 dep 就会把这个全局变量记录下来,表⽰有⼀个 wathcer⽤到了我这个属性。
  • Scheduler 不会⽴即执⾏更新,通过nexttick异步更新

8. vue3响应式原理

通过Proxy(代理): 拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。
通过Reffect(反射): 对源对象的属性进⾏操作, Reflect不是⼀个函数对象,因此它是不可构造
的。

9. 刷新浏览器后,Vuex的数据是否存在?如何解决?

不存在

原因: 因为 store ⾥的数据是保存在运⾏内存中的,当⻚⾯刷新时,⻚⾯会重新加载vue实例,store⾥⾯的数据就会被重新赋值初始化。

我们有两种⽅法解决该问题:
使⽤ vuex-along
使⽤ localStorage 或者 sessionStroage

10. vue和react共同点?区别

共同点:

数据驱动视图
组件化
都使⽤ Virtual DOM

不同点:
核⼼思想不同

vue定位就是尽可能的降低前端开发的⻔槛,让更多的⼈能够更快地上⼿开发。这就有了vue的主要特点:灵活易⽤的渐进式框架,进⾏数据拦截/代理,它对侦测数据的变化更敏感、更精确。

react 定位就是提出 UI 开发的新思路 React推崇函数式编程(纯组件)数据不可变以及单向数据流,
当然需要双向的地⽅也可以⼿动实现, ⽐如借助onChange和setState来实现。

组件写法

React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中
Vue推荐的做法是 template 的单⽂件组件格式(简单易懂,从传统前端转过来易于理解),即 html,css,JS写在同⼀个⽂件(vue也⽀持JSX写法)

diff算法
响应式原理

vue2采⽤object.defineProperty ,vue3采⽤proxy,reflect
React基于状态机,⼿动优化,数据不可变,需要setState驱动新的state替换⽼的state

11. vue双向数据绑定原理

简易实现:v-model分为两部分,通过v-bind绑定值,再通过v-on:input来同步修改值
原理:

需要observe的数据对象进⾏递归遍历,包括⼦属性对象的属性,都加上setter和getter,这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化

通过dep来理清依赖关系watcher在依赖中添加⾃⾝compile解析模板指令将模板中的变量替换成数据,然后初始化渲染⻚⾯视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,⼀旦数据有变动,收到通知,更新视图

待属性变动dep.notice()通知时,能调动watcher⾃⾝的update⽅法,并触发compile回调渲染视图。

12. computed和watch区别

computed计算属性,watch监听属性

计算属性不在 data 中,它是基于data 或 props 中的数据通过计算得到的⼀个新值。
watch 可以监听的数据来源:data,props,computed内的数据

computed中有get和set⽅法,会默认缓存计算结果。
watch不⽀持缓存,⽀持异步, immediate监听属性⽴即执⾏⼀次,deep开启深度监听

13. Vuex

Vuex是⼀种状态管理模式,存在的⽬的是共享可复⽤的组件状态。
主要包括以下⼏个模块:

State => 基本数据,定义了应⽤状态的数据结构,可以在这⾥设置默认的初始状态。
Getter => 从基本数据派⽣的数据,允许组件从 Store 中获取数据,mapGetters 辅助函数仅 仅是将 store 中的 getter 映射到局部计算属性。
Mutation =>是唯⼀更改 store 中状态的⽅法,且必须是同步函数。
Action => 像⼀个装饰器,包裹mutations,使之可以异步。⽤于提交mutation,⽽不是直接变更状 态,可以包含任意异步操作。
Module => 模块化Vuex,允许将单⼀的 Store 拆分为多个
store 且同时保存在单⼀的状态树中。

14. vuex辅助函数

mapState, mapMutations, mapActions, mapGetters
mapState和mapGetters:
两者都放在 computed中,以mapState举例

import { mapState } from 'vuex'
computed中
computed:{
...mapState(['data']) //data是vuex存放的state中的属性,此时{{data}}可使⽤
}

mapMutations, mapActions:
放在组件的methods属性中 。使⽤与上类似

15. vuex模块化使⽤

当我们开发的项⽬⽐较⼤时,store中的数据就可能⽐较多,这时我们store中的数据就可能变得臃肿,为了解决这⼀问题,我们就需要将store模块化(module)
前提:

创建两份js⽂件,含有属性与vuex写法相同,需要通过namespaced:true开启命名空间store/index.js:在modules中引⼊⽂件

使⽤:
访问state数据:

第⼀种⽅式:this.$store.state.moduleA.sum
第⼆种⽅式:…mapState(‘moduleA’,[‘sum’,‘number’])

action提交mutation

第⼀种⽅式:需要传参this.store.dispatch(′moduleB/addZhang′,name:′⼩明′,age:18),⽆需传参this.store.dispatch('moduleB/addZhang',{name:'⼩明',age:18}) ,⽆需传参 this.store.dispatch(moduleB/addZhang,name:,age:18)需传参this.store.dispatch(‘moduleB/addServer’)
第⼆种⽅式:…mapActions(‘moduleB’,[‘addZhang’])

getters计算属性
第⼀种⽅式: this.$store.getters[‘moduleB/firstName’]
第⼆种⽅式:…mapGetters(‘moduleB’,[‘firstName’])

16. vue中mixin

mixin(混⼊):

提供了⼀种⾮常灵活的⽅式,来分发 Vue 组件中的可复⽤功能。
本质其实就是⼀个js对象,它可以包含我们组件中任意功能选项,如data、components、methods、created、computed等等
我们只要将共⽤的功能以对象的⽅式传⼊ mixins选项中,当组件使⽤
mixins对象时所有mixins对象的选项都将被混⼊该组件本⾝的选项中来

具体使⽤:
创建mixins.js⽂件

let mixin = {
created() {
console.log('我是mixin中的');
},
methods: {
hellow() {
console.log('你好');
},
},
}
export default mixin

局部使⽤

import mixin from "./mixins";
export default {
mixins: [mixin],
mounted() {
this.hellow();//你好
},
};

全局使⽤main.js

import { createApp } from 'vue'
import App from './App.vue'
import mixins from "./mixins";
const app = createApp(App)
app.mixin(mixins)
app.mount('#app')

17. Vue中给对象添加新属性时,界⾯不刷新怎么办?

原因:

vue2响应式采⽤object.defineProperty进⾏劫持,那个添加新属性时,新的属性不会具有get和set⽅法,不是⼀个响应式所以界⾯不刷新

解决:

Vue.set() 向响应式对象中添加⼀个property,并确保这个新 property 同样是响应式的

vue3通过proxy劫持和reflect映射实现响应式,不会有这个问题

18. vue组件通讯⽅式

通过 props 传递
props校验:name:{type:String,required:true,default:默认值} required是否必要
通过 $emit 触发⾃定义事件
使⽤ ref
EventBus
Provide 与 Inject
Vuex

19. vue3setup的⽗传⼦怎么去写?

介绍三种⽅法:

第⼀种:使⽤vue2写法通过props和$emit
第⼆种:setup函数写法
setup(props,context),通过props接收数据,通过context.emit(‘调⽤⽗组件⽅法’,传递参数)
第三种:script中setup
vue3⾃带definePropsdefineEmits
const emits = defineEmits([“changeNumber”]);
// 也可以不赋值,取值通过{{num}}获取

const props = defineProps({num: {type: Number,default: () => [],},list: {type: Array,},
});
const changeNum = function () {emits("changeNumber", 888);// console.log(11111111111);
};

20. setup可不可以直接写async和await?

可以
setup 语法糖中可直接使⽤ await,不需要写 async , setup 会⾃动变成 async setup

<script setup>
import Api from '../api/Api'
const data = await Api.getData()
console.log(data)
</script>

21. vue⽣命周期

vue2
beforeCreate ‒ ⾸次访问data
created ‒ ⾸次访问this⽣命周期
mounted ‒ ⻚⾯展⽰
vue3
区别:
beforeCreate -> setup() 开始创建组件之前,创建的是data和method
created -> setup()
beforeMount -> onBeforeMount 组件挂载到节点上之前执⾏的函数。
mounted -> onMounted 组件挂载完成后执⾏的函数
beforeUpdate -> onBeforeUpdate 组件更新之前执⾏的函数。
updated -> onUpdated 组件更新完成之后执⾏的函数。
beforeDestroy -> onBeforeUnmount 组件挂载到节点上之前执⾏的函数。
destroyed -> onUnmounted 组件卸载之前执⾏的函数。dszhuoyi
activated -> onActivated 组件卸载完成后执⾏的函数
deactivated -> onDeactivated

22. 说说 Vue 中 CSS scoped 的原理

添加scoped标签后会给组件中所有标签元素,添加⼀个唯⼀标识,这个唯⼀标识就是⾃定义属性data-v-xxxxxxxx这样的字眼,同时对应的样式选择器也会添加这个唯⼀的属性选择器

23. $nextTick原理

在下次 DOM 更新循环结束之后执⾏延迟回调。在修改数据之后⽴即使⽤这个⽅法,获取更新后的DOM

24. data是函数不是对象

vue是⼀个单⻚⾯应⽤最终所有的实例都会挂载到app.vue⽂件,如果data是⼀个对象那么会导致数据污染。通过函数返回对象的⽅式,利⽤函数作⽤域的限制避免数据污染

25. 路由守卫

vue路由守卫分为三种:全局路由守卫独享路由守卫,组件路由守卫

to: 进⼊到哪个路由去
from: 来⾃哪个路由
next:是否跳转

全局守卫: router.beforeEach((to,from,next)=>{})
独享路由守卫: beforeEnter:(to,from,next)=>{}
组件路由守卫: beforeRouteEnter:(to,from,next)=>{}, beforeRouteUpdate , beforeRouteLeave

26. vue设置全局变量

⽅法⼀:
vue2.x挂载全局是使⽤ Vue.prototype.$xxxx=xxx 的形式来挂载,然后通过 this.$xxx来获取挂载到全
局的变量或者⽅法。
Vue 3 中,使⽤ config.globalProperties

app.config.globalProperties.$data =111const {proxy} = getCurrentInstance()
console.log(proxy.$data)

⽅法⼆:

provide/inject

27. vue中keep-alive

属性:include和exclude
语法:
// 指定home组件和about组件被缓存

<keep-alive include="home,about" >
<router-view></router-view>
</keep-alive>

// 除了home组件和about组件别的都缓存

<keep-alive exclude="home,about" >
<router-view></router-view>
</keep-alive>

钩⼦函数:

activated 当组件被激活(使⽤)的时候触发 可以简单理解为进⼊这个⻚⾯的时候触发 deactivated
当组件不被使⽤(inactive状态)的时候触发 可以简单理解为离开这个⻚⾯的时候触发

进⼊开启缓存的组件
初始进⼊和离开 created —> mounted —> activated --> deactivated
后续进⼊和离开 activated --> deactivated

28. vue插槽

slot⼜名插槽,是Vue的内容分发机制,组件内部的模板引擎使⽤slot元素作为承载分发内容的出⼝。
插槽slot是⼦组件的⼀个模板标签元素,⽽这⼀个标签元素是否显⽰,以及怎么显⽰是由⽗组件决定的。slot⼜分三类,默认插槽,具名插槽和作⽤域插槽。

默认插槽:

⼜名匿名插槽,当slot没有指定name属性值的时候⼀个默认显⽰插槽,⼀个组件内只有有⼀个匿名插槽。

具名插槽:

带有具体名字的插槽,也就是带有name属性的slot,⼀个组件可以出现多个具名插槽。

作⽤域插槽:

默认插槽、具名插槽的⼀个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在⼦组件渲染作⽤域插槽时,可以将⼦组件内部的数据传递给⽗组件,让⽗组件根据⼦组件的传递过来的数据决定如何渲染该插槽。

实现原理:
当⼦组件vm实例化时,获取到⽗组件传⼊的slot标签的内容,存放在vm.s l o t 中,默认插槽为 v m . slot中,默认插槽为vm.slot中,默认插槽为vm.slot.default,具名插槽为vm.s l o t . x x x, x x x 为插槽名,当组件执⾏渲染函数时候,遇到 s l o t 标签,使⽤ slot.xxx,xxx 为插槽名,当组件执⾏渲染函数时候,遇到slot标签,使⽤slot.xxx,xxx为插槽名,当组件执⾏渲染函数时候,遇到slot标签,使⽤slot中的内容进⾏替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作⽤域插槽。

29. vue2和vue3区别

双向绑定更新

vue2 的双向数据绑定是利⽤ES5 的⼀个 API ,Object.defineProperty()对数据进⾏劫持 结合 发布订阅模式的⽅式来实现的。
vue3 中使⽤了 ES6 的 ProxyAPI 对数据代理,通过 reactive() 函数给每⼀个对象都包⼀层 Proxy,通过 Proxy 监听属性的变化,从⽽ 实现对数据的监控。

这⾥是相⽐于vue2版本,使⽤proxy的优势如下

1.defineProperty 只能监听某个属性,不能对全对象监听 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
2.可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。

获取props

vue2在script代码块可以直接获取props,
vue3通过setup指令传递

API不同

Vue2使⽤的是选项类型API(Options API),
Vue3使⽤的是合成型API(Composition API)

建⽴数据data

vue2是把数据放⼊data中,
vue3就需要使⽤⼀个新的setup()⽅法,此⽅法在组件初始化构造得时候触发。

⽣命周期不同

vue2 -------- vue3

beforeCreate -> setup() 开始创建组件之前,创建的是data和method created -> setup()
beforeMount -> onBeforeMount 组件挂载到节点上之前执⾏的函数。 mounted -> onMounted
组件挂载完成后执⾏的函数 beforeUpdate -> onBeforeUpdate 组件更新之前执⾏的函数。 updated ->
onUpdated 组件更新完成之后执⾏的函数。 beforeDestroy -> onBeforeUnmount
组件挂载到节点上之前执⾏的函数。 destroyed -> onUnmounted 组件卸载之前执⾏的函数。dszhuoyi
activated -> onActivated 组件卸载完成后执⾏的函数 deactivated -> onDeactivated

是否⽀持碎⽚

vue2.0 只允许有⼀个根标签,
vue3.0⽀持碎⽚化,可以拥有多个根节点

main.js⽂件不同

vue2中我们可以使⽤pototype(原型)的形式去进⾏操作,引⼊的是构造函数
vue3中需要使⽤结构的形式进⾏操作,引⼊的是⼯⼚函数

diff算法不同
更好的⽀持ts

30. Vue3.0 所采⽤的 Composition Api (组合式)与 Vue2.x 使⽤的 Options Api(选项式) 有什么不同?

options Api 当组件变得复杂,导致对应属性的列表也会增⻓,这可能会导致组件难以阅读和理解 。
composition Api 它将功能定义在⼀起,利于查找和理解
Composition API 对 tree-shaking 友好,代码也更容易压缩
Composition API中⻅不到this的使⽤,减少了this指向不明的情况
如果是⼩型组件,可以继续使⽤Options API,也是⼗分友好的

31. vue3中hook

本质是⼀个函数,把setup函数中使⽤的Composition API(组合式api)进⾏了封装,类似于vue2中
的mixin
⾃定义hook优势:复⽤代码,让setup中的逻辑更清楚易懂

32. vue组件和插件的区别

组件:

Vue 组件是⼀个可复⽤的 Vue 实例,可以带有⾃⼰的状态和⽅法。组件可以包含其他组件,从⽽形成⼀个复杂的 UI 列表。

优点

可以将代码封装成⼀个可复⽤的组件,提⾼开发效率。
组件具有良好的可维护性,易于修改和更新。

缺点
组件的功能和作⽤⽐较独⽴,不太适⽤于全局功能的扩展。
组件的管理和组织需要⼀定的规范,否则可能会导致混乱和不易维护。

插件:

Vue 插件可以扩展 Vue 的全局功能,在应⽤程序中可以重复使⽤。常⻅的插件如 vue-router、vuex、axios 等。

优点

插件可以⽅便地扩展 Vue 的全局功能。
插件可以使代码重复利⽤,提⾼开发效率。
开源社区中已经有⼤量的插件可以⽤于解决常⻅的问题。

缺点
插件具有⼀定的复杂性,需要更多的学习成本。
插件功能可能⽐较复杂,可能会导致性能下降。

33. vue修饰符

在Vue中,修饰符处理了许多DOM事件的细节,让我们不再需要花⼤量的时间去处理这些烦恼的事情,⽽能有更多的精⼒专注于程序的逻辑处理

表单修饰符

.lazy 懒加载,光标离开标签时,才赋值给value
.trim 过滤⾸位空格
.number 限制输⼊类型为数字或转为数字

事件修饰符

.stop 阻⽌事件冒泡
.prevent 组织事件默认⾏为
.once 事件只触发⼀次
.capture 开启事件捕获
.self 事件只在⾃⾝触发

⿏标按键修饰符

left 左键点击
right 右键点击
middle 中键点击

键值修饰符

普通键(enter、tab、delete、space、esc、upR)
系统修饰键(ctrl、alt、meta、shiftR)

v-bind修饰符

.async 对props进⾏双向绑定
.prop 设置⾃定义标签属性,避免暴露数据,防⽌污染html结构
.camel 将命名为驼峰命名法

34. Vue路由中,history和hash两种模式有什么区别?

hash:

hash 模式是⼀种把前端路由的路径⽤井号 # 拼接在真实 URL 后⾯的模式。当井号 #后⾯的路径发⽣变化时,浏览器并不会重新发起请求,⽽是会触发 hashchange 事件。

优点:浏览器兼容性较好,连 IE8 都⽀持
缺点:路径在井号 # 的后⾯,⽐较丑

history:

history API 是 H5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址⽽不重新发起请求

优点:路径⽐较正规,没有井号 #
缺点:兼容性不如 hash,且需要服务端⽀持,否则⼀刷新⻚⾯就404了

35. params和query区别

params 和 query 都是⽤于传递参数的,但它们的传参⽅式和使⽤场景是不同的。
params 通过路由路径传递参数,在路由配置中使⽤ :paramName 的形式进⾏声明

const router = new VueRouter({
routes: [{path: '/user/:id',component: User,},
],
})

query 通过 URL 查询字符串(即问号后⾯的部分)传递参数,在路由地址后⾯使⽤ ? 连接多个参数键值对
不需要在router中配置 /search?q=vue 会⾃动匹配到search组件

区别:

params 适合⽤于必须存在的参数传递,例如⽤⼾详情⻚或⽂章详情⻚的访问。
query 适合⽤于可选的参数传递,例如搜索功能中关键词的传递。

36. vue2中assets和vue3中public区别 ?

在 Vue 2 中,

assets ⽬录是默认存在的,可以直接在项⽬的根⽬录下创建,它通常⽤来存放组件需要的图⽚、样式等静态资源⽂件。这些⽂件会被打包到JavaScript ⽂件中,在代码中使⽤相对路径引⽤。

在 Vue 3 中,

可以通过配置 vue.config.js ⽂件来设置 public ⽬录,它的作⽤与 assets ⽬录类似,⽤来存放静态资源⽂件。但是,与Vue 2 不同的是,public ⽬录下的⽂件不会被打包,⽽是会直接复制到输出⽬录下

37. 单⻚应⽤如何提⾼加载速度?

使⽤代码分割:将代码拆分成⼩块并按需加载(懒加载),以避免不必要的⽹络请求和减少加载时间。
缓存资源:利⽤浏览器缓存来存储重复使⽤的⽂件,例如 CSS 和 JS ⽂件、图⽚等。
预加载关键资源:在⾸次渲染之前,先提前加载关键资源,例如⾸⻚所需的 JS、CSS 或数据,以保证关键内容的快速呈现。
使⽤合适的图⽚格式:选择合适的图⽚格式(例如 JPEG、PNG、WebP 等),并根据需要进⾏压缩以减少⽂件⼤⼩。对于⼀些⼩图标,可以使⽤ iconfont 等字体⽂件来代替。
启⽤ Gzip 压缩:使⽤服务器端的 Gzip 压缩算法对⽂件进⾏压缩,以减少传输时间和带宽消耗。
使⽤ CDN:使⽤内容分发⽹络(CDN)来缓存和传递⽂件,以提⾼⽂件的下载速度和可靠性。
优化 API 请求:尽可能地减少 API 调⽤的数量,并使⽤缓存和延迟加载等技术来优化 API 请求的效率。
使⽤服务器端渲染:使⽤服务器端渲染(SSR)来⽣成 HTML,以减少客⼾端渲染所需的时间和资源。但需要注意,SSR 也可能增加了服务器的负担并使⽹站更复杂。

38. Vue⽗组件调⽤⼦组件的⽅法

vue中如果⽗组件想调⽤⼦组件的⽅法,可以在⼦组件中加上ref,然后通过this.$refs.ref.method调⽤

<child ref="child"></child>

调⽤:this.$refs.child.⼦组件⽅法

39. vue3中dom获取,ref在组件上使⽤

<template>
<div class="ref">
<h3>ref使⽤:</h3>
<input type="text" ref="input" /> // ref="input" 需要和 const input = ref(null); 相对应
</div>
</template>
<script setup>
import { reactive, ref, createApp, onMounted } from "vue";
let state = reactive({ text: "信息按钮" });
// 同名的 input来进⾏获取节点
const input = ref(null);
onMounted(() => {if (input.value) {input.value.focus();}
});
</script>
<style scoped></style>

40. 渐进式框架理解

渐进式: 可以理解为没有多做职责之外的事
个⼈理解:主张最少的,⼀开始仅基于基础框架构建,随着需求不断扩充

41. ⻚⾯初始化闪烁

产⽣原因:
当⽹速较慢,vue.js⽂件还没有加载完时,在⻚⾯上会显⽰{{message}}的字样,知道vue创建实例,编译模板时,dom才会被替换,所以这个过程屏幕是闪动的。

所以解决这个问题,需要
在style样式中设置【v-cloak】{display:none}。在⼀般情况下,v-clock是⼀个解决初始化慢导致⻚⾯闪动的最佳实践,对于简单的项⽬很实⽤。

但是在具有⼯程化的项⽬⾥,⽐如使⽤了webpack和vue-router的项⽬中,html结构只是⼀个空的div元素,剩余的内容都是由路由去挂载不同的组件完成的,所以不需要v-cloak。

42. vue属性名和method名称⼀致出现什么问题

vue2中, 这个属性会覆盖掉 methods 中的⽅法。也就是说,这个⽅法将⽆法被正确调⽤。
vue3中,报错

43. class和style如何动态绑定

class 与 style 动态绑定⼀般通过对象或者数组来实现
对象写法:适⽤于要绑定的样式名字样式确定,但动态决定⽤不⽤。
数组写法:适⽤于要绑定的样式名字样式不确定。

<div v-bind:class="{ active: isActive }"></div> //对象写法
<div v-bind:class="[activeClass, errorClass]"></div> //数组写法

44. vue遇到的坑

data必须是⼀个函数,⽽不是⼀个对象
vue管理的函数不要写成箭头函数
添加属性⻚⾯不刷新
⼦路由path不需要添加**/**,path=‘new’

45. v-if和v-for 优先级

实践中不管是vue2或者vue3都不应该把v-if和v-for放在⼀起使⽤。

在 vue 2.x 中,在⼀个元素上同时使⽤ v-if 和 v-for 时, v-for 会优先作⽤。

在 vue 3.x 中v-if 总是优先于 v-for ⽣效

vue2中v-for的优先级是⾼于v-if的,放在⼀起,会先执⾏循环在判断条件,并且如果值渲染列表中⼀⼩部分元素,也得再每次重渲染的时候遍历整个列表,⽐较浪费资源。
vue3中v-if的优先级是⾼于v-for的,所以v-if执⾏时,它调⽤相应的变量如果不存在,就会导致异常

46. vue核⼼原理

数据驱动,组建系统

47. vue⾃带动画组件, transition

组件是 Vue 提供的⽤于包裹需要动画效果的元素组件。使⽤组件可以⽅便地实现元素的进⼊和离开动画效果。

<template><div><button @click="visible = !visible">Toggle</button><transition name="fade"><p v-if="visible">Hello, World!</p></transition></div>
</template>
<script>
export default {data() {return {visible: false}},
}
</script>
<style>
.fade-enter-active, .fade-leave-active {transition: opacity .5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}
</style>

48. vue-loader⼯作原理

将⼀个 .vue ⽂件 切割成 template、script、styles 三个部分。

template 部分 通过 compile ⽣成 render、 staticRenderFns
获取 script 部分 返回的配置项对象 scriptExports
styles 部分,会通过 css-loader、vue-style-loader, 添加到 head 中, 或者通过 css-loader、MiniCssExtractPlugin 提取到⼀个 公共的css⽂件 中。

使⽤ vue-loader 提供的 normalizeComponent ⽅法, 合并 scriptExports、render、staticRenderFns, 返回 构建vue组件需要的配置项对象 - options, 即 {data, props, methods,render, staticRenderFnsR}。

49. vue的diff算法

diff整体策略为:深度优先,同层⽐较

数据发⽣改变时,订阅者watcher就会调⽤patch真实的DOM打补丁
通过isSameVnode进⾏判断,相同则调⽤patchVnode⽅法

patchVnode做了以下操作:

找到对应的真实dom,称为el 如果都有都有⽂本节点且不相等,将el⽂本节点设置为Vnode的⽂本节点
如果oldVnode有⼦节点⽽VNode没有,则删除el⼦节点
如果oldVnode没有⼦节点⽽VNode有,则将VNode的⼦节点真实化后添加到el
如果两者都有⼦节点,则执⾏updateChildren函数⽐较⼦节点

updateChildren主要做了以下操作:

设置新旧VNode的头尾指针
新旧头尾指针进⾏⽐较,循环向中间靠拢,根据情况调⽤patchVnode进⾏patch重复流程、调⽤createElem创建⼀个新节点,从哈希表寻找
key⼀致的VNode 节点再分情况操作

50. vue和jquery区别

设计理念

Vue.js 是⼀个现代化的JavaScript框架,专注于构建⼤型的、可维护的Web应⽤程序。Vue.js的核⼼是组件化,它提供了⼀种将⻚⾯分解成独⽴、可重⽤的组件的⽅式,并且能够⾮常容易地管理这些组件之间的依赖关系。同时,Vue.js还内置了状态管理、路由、构建⼯具等功能,使得构建复杂的 Web 应⽤程序更加容易。

⽽ jQuery 则是⼀个早期的 JavaScript 库,主要关注的是 DOM 操作和处理事件。它的设计理念是将JavaScript 代码尽可能地简单化,使得使⽤者可以很容易地完成⼀些常⻅的操作(如选择元素、修改样式、处理事件等)。在 jQuery 中,通过链式调⽤和函数式变成的设计,可以使得代码变得⾮常简洁易读。

⽤途

Vue.js 主要⽤于构建⼤型的、复杂的 Web 应⽤程序,它提供了诸如组件化、状态管理、路由等功能,⾮常适合构建单⻚⾯应⽤(SPA)。

⽽ jQuery 则更多地⽤于简化 DOM 操作和事件处理,它适⽤于编写⼩型的 Web 应⽤程序或较为简单的交互效果。同时,由于 jQuery 在浏览器兼容性、性能等⽅⾯的优势,它也被⼴泛应⽤于⼀些成熟的⽹站和CMS系统中。

51. 说说你对 SPA 单⻚⾯的理解,它的优缺点分别是什么?

SPA( single-page application )仅在 Web ⻚⾯初始化时加载相应的 HTML、JavaScript 和
CSS。⼀旦⻚⾯加载完成,SPA 不会因为⽤⼾的操作⽽进⾏⻚⾯的重新加载或跳转;取⽽代之的是利⽤路由机制实现HTML 内容的变换,UI
与⽤⼾的交互,避免⻚⾯的重新加载。

优点:

⽤⼾体验好、快,内容的改变不需要重新加载整个⻚⾯,避免了不必要的跳转和重复渲染;
基于上⾯⼀点,SPA 相对对服务器压⼒⼩;
前后端职责分离,架构清晰,前端进⾏交互逻辑,后端负责数据处理;

缺点:

初次加载耗时多:为实现单⻚ Web 应⽤功能及显⽰效果,需要在加载⻚⾯的时候将 JavaScript、CSS统加载,部分⻚⾯按需加载;
前进后退路由管理:由于单⻚应⽤在⼀个⻚⾯中显⽰所有的内容,所以不能使⽤浏览器的前进后退功能,所有的⻚⾯切换需要⾃⼰建⽴堆栈管理;
SEO 难度较⼤:由于所有的内容都在⼀个⻚⾯中动态替换显⽰,所以在 SEO 上其有着天然的弱势。

52. 怎样理解 Vue 的单向数据流?

所有的 prop 都使得其⽗⼦ prop 之间形成了⼀个单向下⾏绑定:⽗级 prop 的更新会向下流动到⼦组件中,但是反过来则不⾏。

这样会防⽌从⼦组件意外改变⽗级组件的状态,从⽽导致你的应⽤的数据流向难以理解。额外的,每次⽗级组件发⽣更新时,⼦组件中所有的 prop 都将会刷新为最新的值。
这意味着你不应该在⼀个⼦组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
⼦组件想修改时,只能通过 $emit 派发⼀个⾃定义事件,⽗组件接收到后,由⽗组件修改。

53. ⽗组件可以监听到⼦组件的⽣命周期吗?

⽐如有⽗组件 Parent 和⼦组件 Child,如果⽗组件监听到⼦组件挂载 mounted 就做⼀些逻辑处理,

可以通过以下写法实现:
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
以上需要⼿动通过 $emit 触发⽗组件的事件,更简单的⽅式可以在⽗组件引⽤⼦组件时通过 @hook
来监听即可,如下所⽰:
// Parent.vue
<Child @hook:mounted="doSomething" ></Child>
doSomething() {
console.log('⽗组件监听到 mounted 钩⼦函数 ...');
},
// Child.vue
mounted(){
console.log('⼦组件触发 mounted 钩⼦函数 ...');
},
// 以上输出顺序为:
// ⼦组件触发 mounted 钩⼦函数 ...
// ⽗组件监听到 mounted 钩⼦函数 ...

当然 @hook ⽅法不仅仅是可以监听 mounted,其它的⽣命周期事件,例如:created,updated 等都可以监听。

54. Vue3.0 性能提升主要是通过哪⼏⽅⾯体现的

diff算法优化
静态提升: Vue3中对不参与更新的元素,会做静态提升,只会被创建⼀次,在渲染时直接复⽤
移除⼀些不常⽤的API,再重要的是Tree shanking
响应式系统

55. 什么是 MVVM?⽐之 MVC 有什么区别?什么⼜是 MVP ?

MVC 通过分离 Model、View 和 Controller 的⽅式来组织代码结构。 ⽤⼾与⻚⾯产⽣交互时Controller 中的事件触发器就开始⼯作了,通过调⽤ Model 层,来完成对 Model 的修改,然后Model 层再去通知 View 层更新。

MVVM 模式中的 VM,指的是 ViewModel, 它通过双向的数据绑定,将 View 和 Model 的同步更新给⾃动化了。当 Model 发⽣变化的时候,ViewModel 就会⾃动更新;ViewModel 变化了,View 也会更新。

MVP 模式 ,View 层的接⼝暴露给了 Presenter 因此我们可以在 Presenter 中将 Model 的变化和 View的变化绑定在⼀起,以此来实现 View 和 Model 的同步更新

56. vue中hook和react中hook区别

在React中,hook是⼀种函数,它可以让你在函数组件中添加state、effect等功能。 React 中的hook有useState、useEffect、useContext等。使⽤hook可以避免使⽤类组件时可能会出现的繁琐的⽣命周期⽅法、this等问题。

在Vue中,hook被称为⽣命周期钩⼦函数,它们是在组件实例化过程中⾃动调⽤的回调函数。 Vue中的⽣命周期钩⼦函数包括beforeCreate、created、beforeMount、mounted等。它们可以⽤于控制组件的⽣命周期,以及在组件⽣命周期特定阶段执⾏特定的操作。

57. Redux和Vuex的区别

redux是⼀个范⽤的js库,vuex是专⻔服务vue的

相同点:

state共享数据
流程⼀致:定义全局state,触发,修改state
原理相似,通过全局注⼊store。

不同点:

Vuex定义了state,getter、mutation、action,module五个对象;
redux定义了state、reducer、action;

Vuex触发⽅式有两种commit同步dispatch异步
redux同步和异步都使⽤dispatch;

Vuex中action有较为复杂的异步ajax请求;
redux中action中可简单可复杂,简单就直接发送数据对象({type:xxx, your-data}),复杂需要调⽤异步ajax(依赖redux-thunk插件)

Redux使⽤的是不可变数据,⽽Vuex的数据是可变的。Redux每次都是⽤新的state替换旧的state,⽽Vuex是直接修改;

Redux在检测数据变化的时候,是通过diff的⽅式⽐较差异的,
Vuex其实和Vue的原理⼀样,是通过getter/setter来⽐较的。

58. vue服务端渲染(SSR),解决了哪些问题?

Vue服务端渲染(SSR)通过在服务器上预先⽣成Vue组件的HTML字符串并将其发送到客⼾端,以实现更快的⻚⾯加载速度、更好的搜索引擎优化和更好的⽤⼾体验。

服务端渲染解决了许多SPA(Single Page Application)应⽤程序中存在的问题,例如:

SEO(搜索引擎优化)问题

由于传统的SPA应⽤程序是在浏览器中构建的,因此搜索引擎⽆法正确地索引它们的内容。使⽤Vue SSR,可以在服务器上呈现HTML字符串并向搜索引擎提供更好的友好的⻚⾯。

性能问题

SPA应⽤程序需要⼤量的JavaScript代码来初始化应⽤程序并交互。这可能导致⻚⾯加载时间缓慢,⽤⼾体验较差。使⽤Vue SSR,可以在浏览器中更快地呈现初始HTML的完整标志,并在其中嵌⼊必要的JavaScript。这样可以加快⻚⾯加载速度,并提⾼⽤⼾体验。

⾸屏渲染问题

传统的SPA应⽤程序在⾸次加载时可能会需要⼤量时间才能呈现第⼀个屏幕,直到JavaScript代码完成下载并执⾏。使⽤Vue SSR,可以在服务器上呈现组件,并将其作为HTML字符串发送到客⼾端,从⽽实现快速呈现⾸屏的⽬标。

59. Vue 3.0中Treeshaking特性是什么,并举例进⾏说明?

Tree shaking 是⼀种通过清除多余代码⽅式来优化项⽬打包体积的技术

Tree shaking是基于ES6模板语法(import与export),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输⼊和输出的变量

Tree shaking⽆⾮就是做了两件事:

编译阶段利⽤ES6 Module判断哪些模块已经加载 判断那些模块和变量未被使⽤或者引⽤,进⽽删除对应代码

作⽤:
减少程序体积(更⼩)
减少程序执⾏时间(更快)
便于将来对程序架构进⾏优化(更友好)

60. 虚拟 DOM 的优缺点?

优点:

保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产⽣的操作,它的⼀些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是⽐起粗暴的 DOM 操作性能要好很多,因此框架的虚拟DOM ⾄少可以保证在你不需要⼿动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;⽆需⼿动操作 DOM: 我们不再需要⼿动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的⽅式更新视图,极⼤提⾼我们的开发效率;
跨平台: 虚拟 DOM 本质上是 JavaScript 对象,⽽ DOM 与平台强相关,相⽐之下虚拟 DOM 可以进⾏更⽅便地跨平台操作,例如服务器渲染、weex 开发等等。

缺点:
⽆法进⾏极致优化: 虽然虚拟 DOM + 合理的优化,⾜以应对绝⼤部分应⽤的性能需求,但在⼀些性能要求极⾼的应⽤中虚拟 DOM ⽆法进⾏针对性的极致优化。

61. 虚拟 DOM 实现原理?

虚拟 DOM 的实现原理主要包括以下 3 部分:
⽤ JavaScript 对象模拟真实 DOM 树,对真实 DOM 进⾏抽象;
diff 算法⽐较两棵虚拟 DOM 树的差异
pach 算法将两个虚拟 DOM 对象的差异应⽤到真正的 DOM 树

62. Vue 中的 key 有什么作⽤?

key 是为 Vue 中 vnode 的唯⼀标记,通过这个 key,我们的 diff 操作可以更准确、更快速。

Vue 的 diff 过程可以概括为:oldCh 和 newCh 各有两个头尾的变量 oldStartIndex、oldEndIndex 和newStartIndex、newEndIndex,它们会新节点和旧节点会进⾏两两对⽐,即⼀共有4种⽐较⽅式:
newStartIndex 和oldStartIndexnewEndIndex 和 oldEndIndexnewStartIndex 和 oldEndIndexnewEndIndex 和 oldStartIndex,如果以上 4 种⽐较都没匹配,如果设置了key,就会⽤ key 再进⾏⽐较,在⽐较的过程中,遍历会往中间靠,⼀旦 StartIdx > EndIdx 表明 oldCh 和 newCh ⾄少有⼀个已经遍历完了,就会结束⽐较。

所以 Vue 中 key 的作⽤是:

key 是为 Vue 中 vnode 的唯⼀标记,通过这个 key,我们的 diff 操作可以更准确、更快速!

更准确:因为带 key 就不是就地复⽤了,在 sameNode 函数 a.key === b.key 对⽐中可以避免就地复
⽤的情况。所以会更加准确。

更快速:利⽤ key 的唯⼀性⽣成 map 对象来获取对应节点,⽐遍历⽅式更快,源码如下:

function createKeyToOldIdx (children, beginIdx, endIdx) {
let i, key
const map = {}
for (i = beginIdx; i <= endIdx; ++i) {key = children[i].keyif (isDef(key)) map[key] = i}return map
}

62. Object.defineProperty怎么⽤, 三个参数?,有什么作⽤啊?

Object.defineProperty() ⽅法会直接在⼀个对象上定义⼀个新属性,或者修改⼀个对象的现有属性,并返回此对象。

obj:需要定义属性的对象
prop:需要定义的属性
{}:要定义或修改的属性描述符。
value: “18”, // 设置默认值 (与 get() 互斥)
enumerable: true, //这⼀句控制属性可以枚举 enumerable 改为true 就可以参与遍历了 默认值false
writable: true, // 该属性是否可写 默认值false (与 set() 互斥)
configurable: true, // 该属性是否可被删除 默认值false
get // 当有⼈读取 prop 的时候 get函数就会调⽤,并且返回就是 sss 的值
set // 当有⼈修改 prop 的时候 set函数就会调⽤, 有个参数这个参数就是修改后的值

63. reactive与ref的区别?

从定义数据⻆度对⽐:

ref⽤来定义:基本类型数据
reactive⽤来定义对象(或数组)类型数据

备注:ref也可以⽤来定义对象(或数组)类型数据, 它内部会⾃动通过reactive转为代理对象。

从原理⻆度对⽐:

ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
reactive通过使⽤Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据

从使⽤⻆度对⽐:

ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
reactive定义的数据:操作数据与读取数据:均不需要.value。

64. v-on可以监听多个⽅法吗?

可以⼀个元素绑定多个事件的两种写法

<a v-on='{click:DoSomething,mouseleave:MouseLeave}'>doSomething</a>
<button @click="a(),b()">点我ab</button>

65. vue3中如何获取refs,dom对象的⽅式?vue2中如何使⽤?

vue3:
(1) setup函数⽅法内,获取单个ref属性绑定的dom元素:先定义⼀个空的响应式数据ref定义的,你想获取哪个dom元素,在该元素上使⽤ref属性绑定该数据即可,通过ref.value即可获取到dom节点
(2) 获取多个ref属性绑定的dom元素。使⽤ref绑定⼀个函数,在函数⾥把dom添加到数组⾥⾯

//vue2
<h3 ref="myref">myref</h3>
//获取
this.$refs.myref

66. shallowReactive和shallowRef的区别

(1) shallowReactive只处理对象最外层的响应式(浅响应式)
(2) shallowRef只处理基本数据类型的响应式,不进⾏对象的响应式处理。

(3) 应⽤场景:

① 如果有⼀个对象数据,结构⽐较深,但变化时候,只是外层属性变化,使⽤shallowReactive。
② 如果有⼀个对象数据,后续功能不会修改改对象中的属性,⽽是⽣成新的对象来替换,使⽤shallowRef。

67. provide与inject如何使⽤

(1) ⽗⼦组件传参可以通过props和emit来实现,但是当组件的层次结构⽐较深时,props和emit就没
什么作⽤了。vue为了解决这个提出了Provide / Inject;provider/inject:简单的来说就是在⽗组件中
通过provider来提供变量,然后在⼦组件中通过inject来注⼊变量
(2) provide需要先引⼊,我们将需要传递给下级组件的变量通过provider(‘传输key’,变量)
(3) Inject,下级组件通过变量⽅式接收,person= inject(‘传输key’)

68. toRaw 与 markRaw是什么作⽤?

(1) toRaw :将⼀个由reactive⽣成的响应式对象转化为普通对象

使⽤场景:

⽤于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起⻚⾯更新.

(2) markRaw:标记⼀个对象,使其永远不会再成为响应式对象

应⽤场景:

有些值不应被设置为响应式的,例如复杂的第三⽅类的库,当渲染具有不可变数据源的⼤ 列表时,跳过响应式转换可以提⾼性能

69. Readonly和shallowReadonly理解

readonly:让⼀个响应式数据变为只读的(深只读),readonly是⼀个函数,他会接收⼀个响应式的数据
shallowReadonly:让⼀个响应式数据变为只读的(浅只读),shallowReadonly只限制对象中的第⼀层数据(不能改动,如:salary),但是嵌套的深层次的value属性值 是可以更改的,我们点击更改按钮测试就能发现,被shallowReadonly包裹的对象的深层次值改变了。

70. toref和torefs区别

toRef 和 toRefs 可以⽤来复制 reactive ⾥⾯的属性然后转成 ref,⽽且它既保留了响应式,也保留了引⽤toref(变量,属性),torefs(整个变量)

区别:
在插值表达式中{{}}:
访问 toRefs 的值,需要带上 .value 如果不带上,就会出现双引号 {{user.name.value}}

访问 toRef 的值,不需要带上 .value {{user.name}}

转换属性:
toRef: 复制 reactive ⾥的单个属性并转成 ref
toRefs: 复制 reactive ⾥的所有属性并转成 ref

71. 学习 EventBus

⾸先,在你的项⽬中创建⼀个 eventBus.js ⽂件,并定义⼀个空的 EventBus 对象:

import Vue from 'vue';
export const EventBus = new Vue();

发送事件

import { EventBus } from './eventBus.js';
// 发送名为 'myEvent' 的事件
EventBus.$emit('myEvent', data);

接收事件

import { EventBus } from './eventBus.js';
EventBus.$on('myEvent', (data)=>{});

取消监听

EventBus.$off('myEvent');

72. vue2过滤器(vue3取消)

filter 过滤器是⼀种很常⽤的功能,它可以⽤于对数据进⾏格式化、排序、筛选等操作。在使⽤过程中,我们只需要在模板表达式中使⽤管道符 |,并将要使⽤的过滤器的名称作为参数传递进去即可。

全局过滤器:Vue.filter(‘过滤器名称’,function(){})
局部过滤器:filter选项

filters: {//filterName过滤器名,value是'|'之前的数据filterName(value) {if (!value) return '';return '你好'+value.toString()}
}
http://www.dtcms.com/a/339268.html

相关文章:

  • 豆包1.5 Vision Lite 对比 GPT-5-min,谁更适合你?实测AI模型选型利器 | AIBase
  • 【Langchain系列七】Langchain+FastAPI(字符串输出与OpenAI规范流式输出)+FastGPT
  • 《若依》项目结构分析
  • 温故而知新 再看设计模式
  • 2025.8.19总结
  • 防抖技术(一)——OIS光学防抖技术详解
  • 块存储 对象存储 文件存储的区别与联系
  • plantsimulation知识点25.8.19 工件不在RGV中心怎么办?
  • 技术详解及案例汇总|JY-V620半导体RFID读写器在晶圆盒追踪中的使用
  • Aiseesoft iPhone Unlocker:轻松解决iPhone锁屏问题
  • 量子计算和超级计算机将彻底改变技术
  • 重置iPhone会删除所有内容吗? 详细回答
  • 【Cocos】2D关节组件
  • canoe发送接收报文不通到底是接口问题还是配置问题如何处理
  • Codeforces 斐波那契立方体
  • 【Pycharm虚拟环境中安装Homebrew,会到系统中去吗】
  • k8sday11服务发现(2/2)
  • 机器学习(决策树2)
  • CMake进阶: CMake Modules---简化CMake配置的利器
  • C# NX二次开发:操作按钮控件Button和标签控件Label详解
  • 机器学习之决策树:从原理到实战(附泰坦尼克号预测任务)
  • STM32学习笔记15-SPI通信软件控制
  • Ansible 大项目管理实践笔记:并行任务、角色管理与负载均衡架构部署
  • Effective C++ 条款51:编写new和delete时需固守常规
  • Pandas 入门到实践:核心数据结构与基础操作全解析(Day1 学习笔记)
  • 电源、电流及功率实测
  • Shader开发(十五)创建四边形
  • 【工作笔记】VMware安装 - 安装程序检测到主机启用了Hyper-V或Device/Credential Guard……提示解决方法
  • 在CentOS系统中查询已删除但仍占用磁盘空间的文件
  • 深入解析:Unity、Unreal Engine与Godot引擎中的Uniform变量管理