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

Vue2023 面试归纳及复习

1. Vue 3中的Composition API(Hooks)是什么?它与Options API有何不同?`


答:Composition API是Vue 3中引入的一种新的API风格,

用于组织和重用组件逻辑。它与Options API相比,

提供了更灵活和可组合的方式来编写组件逻辑。

Composition API使用函数式的API,将相关的逻辑组合在一起,而不是将逻辑分散在不同的选项中。

composition API的好处(带来了什么):

  1. 更好的代码组织(相关逻辑代码可以集中放在一块,而不是分散存在);
  2. 更好的逻辑复用;我们可以将一些常用的逻辑封装成自定义的函数,然后在多个组件中进行重用
  3. 更好的类型推导(比如:optons api中,方法被定义在methods中,但是调用时直接使用this来调用,不符合js语法规范,也不利于我们使用语法的方式来推导类型及属性);
  4. 适用于大型的复杂项目;

不要说setup  跟 composition没啥关系 

1 Composition API 的出现解决了这个问题。它允许我们通过函数的方式组织组件的逻辑,将相关的代码放在一起,使得代码更加清晰、可读性更高。

2. 更好的类型推导和编辑器支持
Composition API 的另一个优势是更好的类型推导和编辑器支持。由于 Composition API 使用了函数的方式来组织代码,编辑器可以更准确地推断变量的类型和提供代码补全。

在 Vue 3 中,通过使用 TypeScript,我们可以为 Composition API 提供类型声明,使得编辑器能够提供更好的代码提示和错误检查。

3. 更好的逻辑复用
Composition API 使得逻辑复用变得更加容易。我们可以将一些常用的逻辑封装成自定义的函数,然后在多个组件中进行重用。

在 Vue 2 中,我们使用 Options API 来编写组件。Options API 是一种基于选项的编程模式,将组件的各种选项(如数据、计算属性、方法等)放在一个对象中。这种方式在小型项目中运作良好,但随着项目规模的增长,组件变得越来越复杂,代码逻辑难以维护和重用。

composition API和Options API如何选择?

  1. 不建议共用,容易引起混乱;

  2. 小型项目、业务逻辑简单用Options AP,因为使用起来简单,门槛更低;

  3. 中大型项目,逻辑复杂,使用composition API

Vue 3 中的 Composition API 是什么?它的优势是什么?_程序员徐师兄的博客-CSDN博客

传统 Options API 中,新增或者修改一个需求,需要分别在 datamethodscomputed,… 里进行修改 。

Composition API 的优势

可以更加优雅的组织我们的代码,函数。能够让相关功能的代码更加有序的组织在一起。

  • 能够将代码按照功能进行封装,降低开发成本与后期维护成本,且让setup中的逻辑更清晰易读。
  • 能够方便的实现代码逻辑复用。

2    Options API 语法格式 

atamethodscomputed

Vue2采用选项式API(Options API)格式,该格式会导致对相同数据进行操作使用的代码被分割到不同属性内,很不利于代码的阅读。

<template><h1>{{helloText}}</h1>
</template>
<script>export default{props:['msg'],data(){return {count:0, //逻辑1的数据name:'HelloWorld' //逻辑2的数据}},methods:{onAdd(){  //逻辑1的方法this.count++;},getCount(){ //逻辑2的方法this.count=Math.floor(Math.random()*100);}},computed:{helloText(){  //逻辑2的计算属性return this.msg+' '+this.name;}},watch:{     count(){  //逻辑1的watchconsole.log('count 变了');}},mounted(){this.getCount() //逻辑1的初始化操作}}
</script>
<style scoped>a{color:#42b983}
</style>

Vue:对比于 Options API,为什么 Composition API 很香?_shangdong2023的博客-CSDN博客

3 setup 语法糖

<script setup>是在单文件组件中使用Composition API的编译时语法糖。相比于普通的<script>语法,它具有更多优势

  1. 不用写setup函数
  2. 组件只需要引入不需要注册
  3. 属性和方法也不需要再返回,可以直接在template模板中使用。

在 Vue 3 当中我自己感觉最鲜明的变化就是 Vue 3 中引入了组合式 Api (composition API)
但是使用 Vue3 组合式 API 的时候感觉整个过程比较繁琐

  • 在 setup () 当中定义 ⇒ setup() 中 return ⇒ 模板中使用

如果需要定义一个方法的话,模板中使用这个方法的时候,需要在 setup 函数中将它返回,模板中需要用到的大量的方法和属性都需要一 一返回 , 这个过程有点难受,时不时的就会漏掉返回这一步导致变量未定义或者 xx not a function 的错误

<script>
import {defineComponent , reactive, ref} from 'vue'
export default defineComponent({setup(){// 基本类型变量const name = ref("你好")const age = ref(2023)// 引用类型变量const book = reactive({name:"月亮",age:"1919"})// 将变量返回return{name,age,book}}
})
</script>

因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。

可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。官网:生命周期钩子

Vue3.0 也提供了 Composition AP I形式的生命周期钩子,与 Vue2.x 中钩子对应关系如下:

obeforeCreate===>setup()
created =======> setup()
beforeMount ===> onBeforeMount
mounted =======> onMounted
beforeUpdate ===> onBeforeUpdate
updated =======>onUpdated
beforeUnmount ==> onBeforeUnmount
unmounted =====> onUnmounted
 

 4  Vue3的生命周期

组合式API形式使用
Vue3.0 中可以继续使用 Vue2.x中 的生命周期钩子,但有有两个被更名:
。beforeDestroy改名为beforeUnmount
。destroyed改名为unmounted

vue2                  -> vue3
beforeCreate     -> 使用 setup()     创建
created               -> 使用 setup()
beforeMount       -> onBeforeMount    挂载
mounted             -> onMounted

beforeUpdate     -> onBeforeUpdate  更新
updated              -> onUpdated
beforeDestroy      -> onBeforeUnmount   卸载
destroyed              -> onUnmounted
errorCaptured       -> onErrorCaptured 

Vue3.0 也提供了 Composition AP I形式的生命周期钩子,与 Vue2.x 中钩子对应关系如下:

obeforeCreate===>setup()
created =======> setup()
beforeMount ===> onBeforeMount
mounted =======> onMounted
beforeUpdate ===> onBeforeUpdate
updated =======>onUpdated
beforeUnmount ==> onBeforeUnmount
unmounted =====> onUnmounted

①onBeforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。

②onMounted: 组件挂载时调用

③onBeforeUpdate:  数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

④onUpdated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

⑤onBeforeUnmount
在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。

⑥onUnmounted
卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。

⑦onActivated 【了解】
被 keep-alive 缓存的组件激活时调用。

⑧onDeactivated 【了解】
被 keep-alive 缓存的组件停用时调用。

⑨onErrorCaptured【了解】
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回
false 以阻止该错误继续向上传播。

 Vue3 调试钩子:

onRenderTracked

跟踪虚拟 DOM 重新渲染时调用。钩子接收 debugger event 作为参数。此事件告诉你哪个操作跟踪了组件以及该操作的目标对象和键。

renderTracked

当虚拟 DOM 重新渲染为 triggered.Similarly 为renderTracked,接收 debugger event 作为参数。此事件告诉你是什么操作触发了重新渲染,以及该操作的目标对象和键。

5. 请解释一下Vue 3中的Teleport(传送)和Suspense(异步组件)是什么,以及它们的作用。

答:Teleport是Vue 3中引入的一个新组件,用于将组件的内容渲染到DOM树中的指定位置。

它可以在组件的模板中指定一个目标,使得组件的内容可以被渲染到目标的位置,而不是直接渲染在组件所在的位置。

Suspense是Vue 3中引入的另一个新组件,用于处理异步组件的加载过程。通过在Suspense组件中包裹异步组件,并提供一个fallback选项,可以在异步组件加载过程中展示一个占位符,直到异步组件加载完成后才显示真正的内容。

<template><div class="main"><Suspense><template #default><A /></template><template #fallback><h3>加载中.....</h3></template></Suspense></div>
</template>
<script setup lang="ts">
import A from "./A.vue";
</script>
<style scoped>
.main {width: 100%;height: 100%;
}
</style>

<Suspense> 是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。

Vue3 新特性 内置组件 <Teleport>_织_网的博客-CSDN博客

Vue3中 内置组件 Teleport 详解_vue3 teleport_明天也要努力的博客-CSDN博客

Suspense组件_会说法语的猪的博客-CSDN博客

6. Vue 3中的响应式系统是如何工作的?请解释一下Reactive和Ref的区别。

答:Vue 3中的响应式系统使用Proxy对象来追踪数据的变化。当数据被访问时,Proxy会收集依赖关系,并在数据变化时触发更新。


Reactive函数是Vue 3中提供的一个全局函数,用于将一个对象转换为响应式对象。它接收一个普通对象作为参数,并返回一个响应式代理对象,可以通过该代理对象访问和修改原始对象的属性。

Ref是Vue 3中提供的一个函数,用于创建一个包装器对象,将一个普通的JavaScript值转换为响应式对象。Ref对象可以通过.value属性访问和修改其包装的值。

7. 请描述一下Vue 3中的虚拟DOM(Virtual DOM)和Diff算法的工作原理。

答:Vue 3中的虚拟DOM是一个内存中的表示,类似于真实DOM结构的JavaScript对象。当数据发生变化时,Vue 3会通过对比新旧虚拟DOM的差异,找出需要更新的部分,然后仅更新那些需要变化的部分,而不是直接操作真实的DOM。
Diff算法是用于比较新旧虚拟DOM树的算法。它会逐层对比两棵树的节点,找出差异,并生成一系列需要进行更新的操作。Diff算法通过一些优化策略,如同级比较、Key的使用等,来尽量减少更新的操作次数,提高性能。

8  Vue 3中的响应式数据如何实现异步更新?请解释一下setup()函数中的异步处理。

Vue 3中的响应式数据可以通过reactive()函数或ref()函数进行定义。

当响应式数据发生变化时,Vue 3会将更新操作推迟到下一个事件循环中执行,以保证多个更新操作的批处理。
在setup()函数中,可以返回一个Promise对象来实现异步处理。当Promise对象解析时,组件会重新渲染,以反映最新的数据状态。

 9 Vue 3中的动态组件是什么?如何在Vue 3中使用动态组件?

答:动态组件是指在运行时根据条件来动态选择渲染不同的组件。在Vue 3中,可以使用元素和:is属性来实现动态组件的渲染。
在模板中使用元素,并将要渲染的组件的名称或组件对象赋给:is属性。根据条件的变化,Vue 3会动态地选择渲染不同的组件。

10  请解释一下Vue 3中的 静态提升和Patch Flag  (补丁标记) 的优化策略。

答:

静态提升是Vue 3中的一项优化策略,用于减少渲染时的虚拟DOM节点创建和比较的开销。

在编译过程中,Vue 3会分析模板中的静态内容,并将其提升为一个单独的静态节点,减少对比的复杂性。

 在Vue2中,每次更新diff,都是全量对比,Vue3则只对比带有标记的,这样大大减少了非动态内容的对比消耗


Patch Flag是Vue 3中的一种标记,用于标识虚拟DOM节点的属性和状态变化。通过在虚拟DOM节点上设置Patch Flag,Vue 3可以跳过对比不必要的属性和状态,以提高性能。
 

在Vue3中有哪些静态标记?  

export const enum PatchFlags {TEXT = 1,// 1 动态的文本节点CLASS = 1 << 1,  // 2 动态的 classSTYLE = 1 << 2,  // 4 动态的 stylePROPS = 1 << 3,  // 8 动态属性,不包括类名和样式FULL_PROPS = 1 << 4,  // 16 动态 key,当 key 变化时需要完整的 diff 算法做比较HYDRATE_EVENTS = 1 << 5,  // 32 表示带有事件监听器的节点STABLE_FRAGMENT = 1 << 6,   // 64 一个不会改变子节点顺序的 FragmentKEYED_FRAGMENT = 1 << 7, // 128 带有 key 属性的 FragmentUNKEYED_FRAGMENT = 1 << 8, // 256 子节点没有 key 的 FragmentNEED_PATCH = 1 << 9,   // 512  表示只需要non-props修补的元素 (non-props不知道怎么翻才恰当~)DYNAMIC_SLOTS = 1 << 10,  // 1024 动态的soltDEV_ROOT_FRAGMENT = 1 << 11, //2048 表示仅因为用户在模板的根级别放置注释而创建的片段。 这是一个仅用于开发的标志,因为注释在生产中被剥离。//以下两个是特殊标记HOISTED = -1,  // 表示已提升的静态vnode,更新时调过整个子树BAIL = -2 // 指示差异算法应该退出优化模式
}

Vue3的编译优化:Block树和PatchFlags_姑老爷呀的博客-CSDN博客

简略介绍Vue3之新特性_vue3 虚拟标签_前端布道人的博客-CSDN博客

11. Vue 3中的Fragment(片段)是什么?它有什么作用?

答:Fragment是Vue 3中引入的一个组件,用于包裹一组连续的节点,并且不会在渲染结果中引入额外的父节点。它可以用来替代使用等标签包裹多个节点的情况,以减少生成的DOM层级。
使用Fragment可以改善渲染性能和DOM结构的简洁性,特别是当需要在循环或条件语句中渲染多个节点时。

在 Vue 3 中,要使用 Fragments,我们可以使用特殊的语法来表示一个 Fragment。这个特殊语法是使用尖括号和 v-if 指令来实现的。

下面是一个示例代码,展示了如何使用 Fragments:

<template><><h1>标题</h1><p>正文内容</p><button>点击我</button></>
</template>

在上面的代码中,我们使用 <> 和 </> 将 <h1>、<p> 和 <button> 包裹起来,形成了一个 Fragment。这样,我们就可以直接将多个子元素组合在一起,而无需引入额外的包裹元素。

需要注意的是,在使用 Fragments 时,我们并不需要指定 key 属性。Vue 3 会自动处理 Fragments 中子元素的渲染和更新,而无需我们手动管理。
 

Fragments 的优势
使用 Fragments 有以下几个优势:

1. 简洁性
Fragments 允许我们在不引入多余包裹元素的情况下,组合和渲染多个子元素。这样可以减少 DOM 结构的嵌套层级,使代码更加简洁易读。

2. 更好的性能
相对于使用包裹元素的方式,Fragments 可以减少不必要的 DOM 元素,从而提高渲染性能。因为在 Fragments 中,不会创建额外的 DOM 节点。

3. 更好的样式控制
使用 Fragments 可以避免引入额外的包裹元素,从而减少对样式的影响。特别是在使用 CSS 布局库或者进行样式复用时,Fragments 可以提供更好的样式控制。

总结
Vue 3 中的 Fragments 是一个非常有用的特性,它允许我们更简洁地组合和渲染多个子元素,而无需引入额外的包裹元素。通过使用 <> 和 </> 将多个子元素包裹起来,我们可以享受到简洁性、更好的性能和更好的样式控制。使用 Fragments 可以避免引入额外的包裹元素,从而减少对样式的影响。特别是在使用 CSS 布局库或者进行样式复用时,Fragments 可以提供更好的样式控制。

12 请解释一下Vue 3中的全局API和实例API的区别。

答:Vue 3中的全局API是指可以在任何组件中直接访问的API,如createApp、directive、

vue2中:有许多的全局API,如:Vue.directive、Vue.component、Vue.config、Vue.mixin等
vue3中:提供的是实例API,通过createApp创建vue实例,原来在Vue原型上的API都被挂载到了vue实例上,如:app.directive、app.component、app.config、app.mixin等

全局API:

1. createApp()  创建一个应用实例。

2. createSSRApp()  以SSR创建一个应用实例,和createApp()用法一样。

3. app.mount(msg)   将一个应用实例挂载到某个元素上。

4. app.unmount()  卸载一个已经挂载的应用实例,会触发这个实例内所有组件的卸载生命周期函数

5. app.provide(key, value) 注入  用来提供一个值,可以让应用所有的后代组件都可以使用。

6. app.component()   定义一个全局组件,或返回一个组件。

7. app.directive()

如果同时传递一个名字和一个指令定义,则会注册一个全局指令;如果只传递一个名字,会返回用该名字注册的指令 (如果存在的话)。

8. app.use()

安装一个插件

第一个参数应是插件本身,第二个参数可选是要传递给插件的选项。

9. app.version

版本号,查询该应用的版本号。可以在插件中使用,比较这个插件满足那个版本才能使用。

实例API :

在Vue3中,使用vue中的createApp方法可以创建一个Vue应用实例。

1、component方法:

注册或检索全局组件。注册还会使用给定的 name 参数自动设置组件的 name。

2、config属性
一个包含应用配置的对象。

3、directive方法
注册或检索全局指令。

4、mount方法
所提供 DOM 元素的 innerHTML 将被替换为应用根组件的模板渲染结果。

5、provide方法
设置一个可以被注入到应用范围内所有组件中的值。组件应该使用 inject 来接收 provide 的值。

6、unmount方法
卸载应用实例的根组件

7、use
安装 Vue.js 插件。如果插件是一个对象,则它必须暴露一个 install 方法。如果插件本身是一个函数,则它将被视为 install 方法。

Vue 实例之全局API,实例属性,全局配置,组件进阶_大可爱学编程ฅ´ω`ฅ的博客-CSDN博客

【Vue3】Vue实例API介绍_vue3获取vue实例_h沐的博客-CSDN博客

13. Vue3和Vue2最大区别。

重要的几个区别: Vue响应式的底层实现不同     语法API不同   

 生命周期     this     Typescript支持

 不太重要的 :  v-if和v-for的优先级    .sync修饰符   key在template和v-if上的使用

一、Vue响应式的底层实现不同

二、生命周期有一定的区别

三、支持碎片化,可以有多个根节点

Vue3 支持多个根节点,也就是 fragment。即以下多根节点的写法是被允许的

四,模板指令

在vue2中,v-for 优先级高于 v-if;

在vue3 中,v-if 优先级高于v-for;

五、语法API不同

Vue2:选项式API,面向对象编程

Vue3:选项式API/组合式API,面向函数编程;

没有this,处处皆函数

3、全局API
vue2中:有许多的全局API,如:Vue.directive、Vue.component、Vue.config、Vue.mixin等
vue3中:提供的是实例API,通过createApp创建vue实例,原来在Vue原型上的API都被挂载到了vue实例上,如:app.directive、app.component、app.config、app.mixin等

1、v-if和v-for的优先级
在vue2中:当v-if和v-for同时使用时,v-for的优先级高于v-if(因此我们通常需要计算属性先对数据进行加工处理,以达到性能优化的目的)
在vue3中:当v-if和v-for同时使用时,v-if的优先级高于v-for


2、.sync修饰符
vue2中:由于vue中是单向数据流,父子组件在传值时想要实现v-model的效果就要用到.sync修饰符来实现“双向绑定”
vue3中:对v-model进行了改造,不再需要 .sync 修饰符即可达到数据双向绑定的效果。在vue3中支持多个 v-model属性,默认使用 modelValue 作为 prop,update:modelValue作为事件,当多个v-model绑定时,书写为例:v-model:title="title",此时 title 作为prop,update:title 作为事件

4、Vue.prototype 替换为 config.globalProperties
vue2中:绑定全局的变量、方法等:Vue.prototype.$ajax = xxxx
vue3中:const app = createApp({}); app.config.globalProperties.$ajax = xxxx


5、生命周期
vue2    vue3
beforeCreate


6、key在template和v-if上的使用
vue2中:在使用v-if、vi-else、v-else-if时,为了保证dom节点渲染的正确性,通常需要在对应的节点添加不同的key,以确保vue在进行虚拟dom对比时是准确的;vue2中template在v-for循环时是不能设置key的,否则会产生警告(需要给子节点设置key)。
vue3中:在使用v-if、vi-else、v-else-if时,不用提供唯一的key对dom节点进行区分,因为vue内部会自动生成唯一的key,如果你提供了key,那你就要保证它的唯一性;vue3中template在v-for循环时,key应该设置在template标签上
7、$listeners被移除
vue2中:使用$attrs访问传递给组件的属性,使用$listeners访问传递给组件的事件(需要结合inheritAttrs:false)。
vue3中:虚拟dom中,事件监听器仅仅是以on为前缀的属性


8、this
vue2中:无时无刻都要使用this
vue3中:因为setup函数的存在,所有的props、data等都不需要用this进行访问(vue3对vue2绝大多数是兼容的,如果你用了vue2相关的东西,那你还是需要像vue2一样书写)
9、typescript支持
vue2中:默认是不支持typescript的。
vue3中:支持使用typescript,使用typescript在构建大型项目时,能够很好的提高项目开发的质量。
 

新特性 区别 

Vue3和Vue2的区别_vue2和vue3区别_你吃香蕉吗?的博客-CSDN博客

14 Vue2.0 的响应式原理

原理:通过数据劫持 defineProperty + 发布订阅者模式,当 vue 实例初始化后 observer 会针对实例中的 data 中的每一个属性进行劫持

使用的Object.defineProperty()重新定义对象,给data的每个属性都添加了getter和setter方法。这时候会为对象的每个属性创建一个Dep实例  (依赖)。Dep实例可以订阅和通知相关的Watcher实例。,  这一步叫  数据劫持  或者 依赖收集

在数据发生更新后调用 set 时会通知发布者 notify 通知对应的订阅者做出数据更新,同时将新的数据根性到视图上显示。 这一步叫 派发更新

Vue2的响应式原理通过使用Object.defineProperty方法来实现属性的劫持和侦听,同时使用Dep和Watcher实例来建立属性和依赖之间的关系,并进行更新通知。同时,为了解决对象属性添加和删除的问题,Vue提供了全局的Vue.set和Vue.delete方法,以及实例的vm.$set和vm.$delete方法。

缺陷:只能够监听初始化实例中的 data 数据,动态添加值不能响应,要使用对应的 Vue.set()。

解释:

  1. 在创建 Observer 实例的同时还会创建 Dep 实例,用于保存依赖项。因此每个数据都有 Observer 的实例,每个 Observer 实例中又都有一个 Dep 的实例。
  2. 当 Vue 解析到当解析到模板字符串 {{ }} 时中数据时,就会去创建 Watcher 实例,在 constructor 时会调用自身的 get 方法,该方法不仅将当前的 Watcher 实例赋值给了 Dep.target(表示此时处于依赖收集阶段),还让这个新实例去读取一下 {{ }} 中的数据,一旦读取,就会触发这个数据的 getter 方法。因为此时正在进行收集依赖,Dep.target 一定是为 true 的,于是顺利地把当前的这个 Watcher 实例记录到了 dep 中的 subs 数组里。再然后将 Dep.target 的值重新赋值为 null,表示退出依赖收集阶段

1 在initState()方法里会对组件的props, methods, data,computed, watch等进行编译初始化=>

2 initData()会先获取组件内部的data数据,然后判断data里的数据和props,或者和methods里的名称重复,则抛出错误提示,然后就会去监听data,执行observe方法=>

3   Observer()  =>   defineReactive, dependArray =>  defineProperty()   =>   Observer()    递归

使用的Object.defineProperty()重新定义对象,给data的每个属性都添加了getter和setter方法。

在get的时候会调用dep.depend;如果是数组,则调用dependArray(对数组里的每个元素进行递归调用dep.depend);
在set的时候会先判断数据是否更新,未更新不做操作,更新则observe(),且dep.notify()

总结:

在Vue2中,响应式原理是通过使用Object.defineProperty方法来实现的。当一个对象被传入Vue的observe函数中时,Vue会为对象的每个属性创建一个Dep实例。Dep实例可以订阅和通知相关的Watcher实例。

当一个属性被访问时,Watcher实例会将自己添加到该属性的Dep实例的订阅列表中。当该属性的值发生变化时,Dep实例会遍历订阅列表,通知所有相关的Watcher实例进行更新。

然而,Vue无法检测到对象属性的添加和删除。为了解决这个问题,Vue提供了全局的Vue.set方法或实例的vm.$set方法来添加属性,使用Vue.delete方法或实例的vm.$delete方法来删除属性。对于数组的变动,Vue无法检测到利用索引设置数组,但可以使用Vue.set方法或实例的vm.$set方法。此外,Vue也无法检测直接修改数组长度,但可以使用splice方法来实现。

总结起来,Vue2的响应式原理通过使用Object.defineProperty方法来实现属性的劫持和侦听,同时使用Dep和Watcher实例来建立属性和依赖之间的关系,并进行更新通知。同时,为了解决对象属性添加和删除的问题,Vue提供了全局的Vue.set和Vue.delete方法,以及实例的vm.$set和vm.$delete方法。

15 Vue3.0 的响应式原理

总结来说就是:Vue3使用了Proxy来劫持数据,通过代理对象拦截属性的读取和赋值操作。当对属性进行赋值时,会触发代理对象的set拦截函数执行,从而实现对属性的监听和更新。

  • 在Vue3中,使用reactive函数可以将一个普通的JavaScript对象转换为响应式对象。该函数使用Proxy对对象的属性进行劫持,使得修改属性时可以触发相应的更新操作。
  • 此外,Vue3还引入了effect函数,用于创建副作用函数,即在响应式对象变化时执行的函数。effect函数接受一个用户自定义的fn函数和options选项,可以用于实现具体的业务逻辑。
  • 总结来说,Vue3的响应式原理通过Proxy的劫持数据实现属性的监听和更新,同时配合reactive和effect函数提供了更强大的响应式能力。这样可以实现组件的自动更新,提升开发效率和用户体验。

我们总结一下整个数据绑定建立响应式大致分为三个阶段

1 初始化阶段: 初始化阶段通过组件初始化方法形成对应的proxy对象,然后形成一个负责渲染的effect。

2 get依赖收集阶段:通过解析template,替换真实data属性,来触发get,然后通过stack方法,通过proxy对象和key形成对应的deps,将负责渲染的effect存入deps。(这个过程还有其他的effect,比如watchEffect存入deps中 )。

3 set派发更新阶段:当我们 this[key] = value 改变属性的时候,首先通过trigger方法,通过proxy对象和key找到对应的deps,然后给deps分类分成computedRunners和effect,然后依次执行,如果需要调度的,直接放入调度。


 

16   Vue3.0中的响应式原理是什么?vue2的响应式原理是什么?

(1)vue2.x版本响应式基于ES5的Object.defineProperty实现

(2)Vue3.x版本响应式基于ES6(es2015)的Proxy实现

总结

在vue2中利用的是原生js下边的Object.defineProperty()进行数据劫持,在通过里面的getter和setter方法,进行查看和数据的修改,通过发布、订阅者模式进行数据与视图的响应式。vue2是对对象的所有属性进行递归, 让每个对象的每个属性都调用Object.defineProperty()为止。

  • vue2使用Object.defineProperty()实现响应式原理,而vue3使用Proxy()实现。
  • 虽然vue2,vue3面对对象嵌套,都需要递归,但vue2是对对象的所有属性进行递归,
  • vue3是按需递归,如果没有使用到内部对象的属性,就不需要递归,性能更好。
  • vue2中,对象不存在的属性是不能被拦截的。而vue3可以。
  • vue2对数组的实现是重写数组的所有方法,并改变,vue2中,数组的原型来实现,而Proxy则可以轻松实现。而且vue2中改变数组的长度是无效的,无法做到响应式,但vue3可以。

Vue3.0的相应式原理:利用Proxy劫持对象,访问对象的时候会触发get方法,此时会进行依赖的收集;当修改对象数据的时候会触发set方法,此时会派发依赖,即调用组件的副作用渲染函数(其实不限于), 这样组件就能重新渲染,DOM更新。

17  有哪些vue3响应性判断函数?

isRef
判断一个值是否为一个 ref 对象
isReactive
判断一个对象是否是由 reactive创建的响应式代理
isReadonly
判断一个对象是否是由 readonly 创建的只读代理
isProxy
判断一个对象是否是由 reactive 或 readonly 创建的代理
 

18 介绍一下   ref    reactive       toRef    toRefs  函数 

ref

ref是Vue3提供的一种用于包装基本数据类型的响应式对象的实现方式。

在Vue3中,使用ref可以将基本数据类型(如字符串、数字、布尔值等)包装为响应式对象。当这些基本数据类型的值发生变化时,Vue3会自动更新视图中相应的内容。

需要注意的是,在使用ref包装基本数据类型时,我们需要通过.value来访问这个值。这是因为ref返回的是一个包含.value属性的响应式对象,而不是一个基本数据类型的值。

reactive

reactive是Vue3提供的一种用于包装对象的响应式对象的实现方式。在Vue3中,使用reactive可以将对象包装为一个响应式对象。当这个对象的属性发生变化时,Vue3会自动更新视图中相应的内容。

和ref不同的是,reactive可以深层代理数据

reactive为传入的数据包装ref,生成value,利用Proxy代理检测数据变化。

注意::一般引用数据类型添加响应式使用reactive, 基本数据类型使用ref

vue3响应式数据的相关函数_let data = ref()_MiMenge的博客-CSDN博客

ref和reactive的区别

在使用ref和reactive时,需要注意它们之间的区别。ref适用于包装基本数据类型,而reactive适用于包装对象。此外,ref返回的是一个包含.value属性的响应式对象,而reactive返回的是一个包装后的响应式对象。

toref   函数

创建一个ref对象,这个响应式对象的value引用了接收的对象的某个响应式属性,且与源数据保持引用关系

let data = { num: 0, o: ["1", 2], },

let dynamicProp = toRef(refData, "o");

 toRefs函数

和toRef功能差不多,只不过toRefs可以创建多个ref对象
因为当有多个响应式对象需要单独提取的时候,toRef就显得过于复杂了,使用toRefs可以简化这个过程

let { o, num, job } = toRefs(refData);

在某些情况下,我们希望将一个响应式对象的属性单独作为响应式属性使用,而不是将整个对象作为一个响应式数据使用。这时就可以使用 toRefs 函数。

Vue 3 中的 toRefs 函数是一个非常有用的工具,它可以将一个响应式对象转换为一组响应式属性。这个函数可以用于将父组件中的响应式对象传递给子组件,并在子组件中以单独的响应式属性的形式使用它们。

shallowRef

特殊的ref,只处理基本数据类型的响应式,无法为引用数据类型添加响应式

shallowReactive

只为对象的第一层属性添加响应式

triggerRef

ref生成的数据强制在页面更新页面

前面在使用shallowRef添加响应对象时,数据不能更新到页面,使用triggerRef便可以强制更新

 readony

让一个响应式数据变为深只读

shallowReadony

让一个响应式数据变为浅只读

toRaw

将响应式数据变更为非响应式数据(基础数据)

11 markRaw

将响应式数据永久变更为非响应式数据

12 customRef

自定义ref, 通过基础ref配置满足自定义要求的ref

vue3响应式数据的相关函数_let data = ref()_MiMenge的博客-CSDN博客

【Vue3响应式】ref、reactive,以及toRefs 函数_m0_71975585的博客-CSDN博客

19  setup函数怎么用?

1、setup函数在beforeCreate和created之前执行

2、在setup函数中定义的变量和方法需要return出去,不然无法在模板中使用

3、setup函数是Composition API的入口。

setup函数里面是没有this对象的,使用它的话会报 undefined。

setup函数那么它讲会有两个参数分别是  props  和  context

 
export default {props: {item: String},setup(props,context) { //   setup(props,{ emit } ) 解构赋值console.log(props.item) // 这个可以访问到props里面的值console.log(context.emit) // 这个可拿到emit方法}
}

props 是响应式的,当传入新的 props 时,它将被更新。但是,因为 props 是响应式的,你不能使用 ES6 解构,它会消除 prop 的响应性。

setup第二参数是 Context 

context 是一个普通 Js 对象,

context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构。

export default {setup(props, { attrs, slots, emit, expose }) {...}
}

20  watch 和 watchEffect 区别

  • watch- 显式指定依赖源,依赖源更新时执行回调函数

  • watchEffect - 自动收集依赖源,依赖源更新时重新执行自身

1.watch是惰性执行,也就是只有监听的值发生变化才会执行,但watchEffect不同,每次代码加载watchEffect都会执行。

注:(忽略watch第三个参数的配置,如果修改配置项,也可以实现立即执行)。

2.watch需要传递监听的对象,watchEffect不需要。   

3.watch只能监听响应式数据:ref定义的属性和reactive定义的对象,如果直接监听reactive定义对象中的属性是不允许的 (会报警告),除非使用函数转换一下,既要指明监视的属性,也要指明监视的回调。

  

4.watchEffect如果监听reactive定义的对象是不起作用的 ,只能监听对象中的属性。
 

Vue3 中 watch 与 watchEffect 有什么区别?_vue3 watcheffect和watch区别_琉璃℡初雪的博客-CSDN博客

21  什么是SSR(服务端渲染),原理是什么? 好处有哪些?

服务端渲染

服务端渲染 SSR (Server-Side Rendering),是指在服务端完成页面的 html 拼接处理, 然后再发送给浏览器,将不具有交互能力的 html 结构绑定事件和状态,在客户端展示为具有完整交互能力的应用程序。

适用场景

以下两种情况 SSR 可以提供很好的场景支持

  • 需更好的支持 SEO

    优势在于同步。搜索引擎爬虫是不会等待异步请求数据结束后再抓取信息的,如果 SEO 对应用程序至关重要,但你的页面又是异步请求数据,那 SSR 可以帮助你很好的解决这个问题。

  • 需更快的到达时间

    优势在于慢网络和运行缓慢的设备场景。传统 SPA 需完整的 JS 下载完成才可执行,而SSR 服务器渲染标记在服务端渲染 html 后即可显示,用户会更快的看到首屏渲染页面。如果首屏渲染时间转化率对应用程序至关重要,那可以使用 SSR 来优化。

开箱即用的SSR脚手架

目前前端流行的三种技术栈 React, Vue 和 Angula,已经孵化出对应的服务端渲染框架,开箱即用,感兴趣的同学可以自主学习使用。

  • React: Next.js

  • Vue:  Nuxt.js

彻底理解服务端渲染 - SSR原理_沛沛老爹的博客-CSDN博客

服务端渲染SSR及实现原理_ssr场景_油墨香^_^的博客-CSDN博客

22  什么是 Reflect ?

Reflect 其实和 Proxy 一样都是属于 ES6 的高级API,Reflect 也是属于 window 的一个内置类,可以通过 window.Reflect 访问到,看下图    

     Reflect是JavaScript中的全局对象,提供操作JavaScript对象的方法,类似与Object操作对象的方法。用于解决Object方法过于臃肿的问题,对大多数的Object方法进行了实现,同时对于对象的操作返回操作的结果,如返回对象的set操作结果,在某些场景下可以进行监听操作。  

工具人
 

为什么 Proxy 要配合 Reflect 一起使用

①触发代理对象的劫持时保证正确的 this 上下文指向

function getPrivateProps(obj, filterFunc) {return new Proxy(obj, {get(obj, prop) {if (!filterFunc(prop)) {let value = Reflect.get(obj, prop);// 如果是方法, 将this指向修改原对象if (typeof value === 'function') {value = value.bind(obj);}return value;}},set(obj, prop, value) {if (filterFunc(prop)) {throw new TypeError(`Can't set property "${prop}"`);}return Reflect.set(obj, prop, value);},has(obj, prop) {return filterFunc(prop) ? false : Reflect.has(obj, prop);},ownKeys(obj) {return Reflect.ownKeys(obj).filter(prop => !filterFunc(prop));},getOwnPropertyDescriptor(obj, prop) {return filterFunc(prop) ? undefined : Reflect.getOwnPropertyDescriptor(obj, prop);}});}
//因为私有属性 一般以 _开头 这里就简单过滤
function propFilter(prop) {return prop.indexOf('_') === 0;
}

②框架健壮性

详解Reflect:Reflect和Object的异同,Reflect的一些内置方法以及方法注意点_DCodes的博客-CSDN博客

都知道vue3响应式是Proxy实现的,进来把proxy与Reflect吃透_vue3数据响应式过程reflect_前端阿彬的博客-CSDN博客

详解Reflect:Reflect和Object的异同,Reflect的一些内置方法以及方法注意点_DCodes的博客-CSDN博客


【前端vue3面试题】2023最新面试实录vue3.0,高频10问(持续更新...)_wzySan的博客-CSDN博客

相关文章:

Vue2023 面试归纳及复习

1. Vue 3中的Composition API&#xff08;Hooks&#xff09;是什么&#xff1f;它与Options API有何不同&#xff1f; 答&#xff1a;Composition API是Vue 3中引入的一种新的API风格&#xff0c; 用于组织和重用组件逻辑。它与Options API相比&#xff0c; 提供了更灵活和可…...

Android动态可编辑长度列表

概述 在界面实现一个列表&#xff0c;用户可以随意给列表新增或者删除项目&#xff0c;在开发中比较常用&#xff0c;但是真正做起来又有点花时间&#xff0c;今天花时间做一个&#xff0c;以便在以后的开发中用到。 详细 运行效果&#xff1a; 二、实现思路&#xff1a; 1…...

合并对象在 Typescript 中的实现与应用

合并对象在 Typescript 中的实现与应用 文章目录 合并对象在 Typescript 中的实现与应用一、简介二、实现1、函数实现2、参数说明3、返回值 三、使用示例四、实际应用场景五、拓展&#xff1a;使用 lodash-es 的 assign 函数进行对象合并1、简介2、安装与导入3、基础用法4、注意…...

antd upload组件beforeUpload返回promise之后,获取的文件不是file类型导致上传失败

之前的beforeUpload直接返回一个false值 &#xff0c;文件是可以正常与服务端进行传输的 beforeUpload: (file) > {return false},但是这样并不能阻止文件上传&#xff0c;看了官方文档后&#xff0c;改用返回promise对象上传 beforeUpload: (file) > {console.log(-befo…...

创建ffmpeg vs2019工程

0 写在前面 本文主要参考链接&#xff1a;https://www.cnblogs.com/suiyek/p/15669562.html 感谢作者的付出&#xff1b; 1 目录结构 2 下载yasm和nasm 如果自己在安装VS2019等IDE的时候已经安装了它们&#xff0c;则不用再单独进行安装&#xff0c;比如我这边已经安装了&a…...

无涯教程-机器学习 - Jupyter Notebook函数

Jupyter笔记本基本上为开发基于Python的数据科学应用程序提供了一个交互式计算环境。它们以前称为ipython笔记本。以下是Jupyter笔记本的一些功能,使其成为Python ML生态系统的最佳组件之一- Jupyter笔记本可以逐步排列代码,图像,文本,输出等内容,从而逐步说明分析过程。 它有…...

ubuntu安装单机的Consul

文章目录 场景解决启动方式 场景 公司使用Consul做注册发现中心以及管理配置&#xff0c;之前没有用过consul, 现在记录下ubuntu部署的过程 解决 apt 安装 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-…...

聊聊mybatis-plus的sql加载顺序

序 本文主要研究一下如果mybatis mapper定义了多个同名方法会不会有问题 MybatisConfiguration com/baomidou/mybatisplus/core/MybatisConfiguration.java /*** MybatisPlus 加载 SQL 顺序&#xff1a;* <p> 1、加载 XML中的 SQL </p>* <p> 2、加载 SqlP…...

基于jeecg-boot的flowable流程审批时增加下一个审批人设置

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 因为有时…...

HTML 与 CSS 有什么区别?

HTML&#xff08;超文本标记语言&#xff09;和 CSS&#xff08;层叠样式表&#xff09;是构建网页的两个核心技术。HTML负责定义网页的结构和内容&#xff0c;而CSS则用于控制网页的样式和布局。虽然它们在构建网页时密切相关&#xff0c;但它们在功能和用途上有明显的区别。 …...

服务器数据恢复-vmware ESXI虚拟机数据恢复案例

服务器数据恢复环境&#xff1a; 从物理机迁移一台虚拟机到ESXI&#xff0c;迁移后做了一个快照。该虚拟机上部署了一个SQLServer数据库&#xff0c;存放了5年左右的数据。ESXI上有数十台虚拟机&#xff0c;EXSI连接了一台EVA存储&#xff0c;所有的虚拟机都在EVA存储上。 服务…...

Rabbitmq的Shovel

Federation 具备的数据转发功能类似&#xff0c; Shovel 够可靠、持续地从一个 Broker 中的队列 ( 作为源端&#xff0c;即source)拉取数据并转发至另一个 Broker 中的交换器 ( 作为目的端&#xff0c;即 destination) 。作为源端的队列和作为目的端的交换器可以同时位于…...

华为手机实用功能介绍

一、内置app介绍 分四块介绍&#xff0c;包括出门款、规划款、工作款和生活款。 出门款&#xff1a;红色框框部分&#xff0c;照镜子化妆/看天气 规划款&#xff1a;黄色框框部分&#xff0c;日程表/计划表/番茄时间/计时 工作款&#xff1a;蓝色框框部分&#xff0c;便笺/录…...

算法题打卡day50-动态规划 | 123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

123. 买卖股票的最佳时机 III - 力扣&#xff08;LeetCode&#xff09; 状态&#xff1a;查看索引含义和初始化思路后AC。 增加了两次的限制&#xff0c;相应的就是需要考虑的状态改变&#xff0c;具体的索引含义在代码中&#xff1a; class Solution { public:int maxProfit(…...

jvm与锁

今天是《面霸的自我修养》的第二弹&#xff0c;内容是Java并发编程中关于Java内存模型&#xff08;Java Memory Model&#xff09;和锁的基础理论相关的问题。这两块内容的八股文倒是不多&#xff0c;但是难度较大&#xff0c;接下来我们就一起一探究竟吧。 数据来源&#xff…...

零基础安装pycuda

零基础安装pycuda 前言安装Visual Studio安装C/C环境添加环境变量 安装pycuda查看系统位数查看python版本下载whl文件 前言 最近开始学习基于python的cuda编程&#xff0c;记录一下pycuda的安装。 在安装pycuda之前&#xff0c;首先需要有NVIDIA的独立显卡并且要安装CUDA和CUD…...

Streamlit 讲解专栏(十一):数据可视化-图表绘制详解(中)

文章目录 1 前言2 绘制交互式散点图3 定制图表主题4 增强数据可视化的交互性与注释步骤1步骤二 5 结语 1 前言 在上一篇博文《 Streamlit 讲解专栏&#xff08;十&#xff09;&#xff1a;数据可视化-图表绘制详解&#xff08;上&#xff09;》中&#xff0c;我们学习了一些关…...

d3dx9_35.dll丢失怎么解决

今天&#xff0c;我将为大家介绍关于电脑d3dx9_35.dll丢失的4种详细修复方法。希望通过这次分享&#xff0c;能够帮助大家解决在日常工作和生活中遇到的一些问题。 首先&#xff0c;让我们来了解一下d3dx9_35.dll是什么&#xff1f; d3dx9_35.dll是一个非常重要的动态链接库文…...

Ansible自动化运维工具(二)

目录 &#xff08;6&#xff09;copy模块 &#xff08;7&#xff09;file模块 ​编辑​编辑&#xff08;8&#xff09;hostname模块 &#xff08;9&#xff09;ping模块 &#xff08;10&#xff09;yum 模块 &#xff08;11&#xff09;service/system模块 ​编辑 ​…...

uniapp中使用原生canvas标签绘制视频帧来模拟拍照,拍照后将图绘制在另外一个canvas上编辑画图,这样反复操作

uniapp中使用原生canvas标签绘制视频帧来模拟拍照&#xff0c;拍照后将图绘制在另外一个canvas上编辑画图&#xff0c;这样反复操作会导致ios系统上白屏&#xff0c;canvas2d上下文为null,经查阅找到相关资料 IOS 创建Canvas过多导致getContext(‘2d’) 返回null 总 Canvas 内存…...

机器视觉工程师们,学习是工作以外的事情

面试时&#xff0c;领导问你&#xff0c;很多技术问题&#xff0c;你永远的回答是&#xff0c;我可以学。 公司以为你来公司的目标就是学习&#xff0c;学完就跑。 那你进公司的目标到底是什么&#xff1f; 我认为你&#xff0c;你最好想好再回答。 对于每一家公司来说&#xf…...

数据驱动的生活:探索未来七天生活指数API的应用

前言 随着科技的不断发展&#xff0c;数据已经成为我们生活中不可或缺的一部分。从社交媒体上的点赞和分享&#xff0c;到电子邮件和搜索引擎的历史记录&#xff0c;数据正在以前所未有的速度积累。而这些数据的利用不仅仅停留在社交媒体或商业领域&#xff0c;它们还可以为我…...

【数据分享】2006-2021年我国城市级别的集中供热相关指标(免费获取\20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…...

2022年研究生数学建模竞赛优秀论文汇总

A题&#xff1a;移动场景超分辨定位问题 参考代码论文1 论文2 论文3 论文4 论文5 论文6 论文7B题&#xff1a; 方形件排样优化与订单组批问题探析 参考代码论文1 论文2 论文3 论文4 论文5 论文6 论文7C题&#xff1a; 汽车制造涂装-总装缓存调序区调度优化问题论文1 论文2 论文…...

阿里云申请免费SSL证书的两种验证方式及配置服务器Tomcat升级HTTPS协议

通用教程&#xff0c;其他服务商的免费 SSL 证书也差不多是这个流程。&#xff08;至少腾讯云的操作步骤和本文是一致&#xff0c;嘻嘻&#xff01;&#xff09; 申请 SSL 证书 首先在阿里云上创建并申请 SSL 证书&#xff0c;之后选择 DNS 验证的方式&#xff0c;一种是手动配…...

SQL Server 和 MySql 语法和关键字的区别

SQL Server 和 MySql 语法和关键字的区别 ——用于SQLServer到MySql的转换 mysql的ifnull()函数对应sql的isnull()函数;mysql的存储过程中变量的定义去掉;mysql的每句结束要用";"SQLServer存储过程的AS在MySql中需要用begin .....end替换字符串连接用concat()函数;…...

2023_Spark_实验三:基于IDEA开发Scala例子

一、创建一个空项目&#xff0c;作为整个项目的基本框架 二、创建SparkStudy模块&#xff0c;用于学习基本的Spark基础 三、创建项目结构 1、在SparkStudy模块下的pom.xml文件中加入对应的依赖&#xff0c;并等待依赖包下载完毕。 在pom.xml文件中加入对应的依赖 ​<!-- S…...

2023年高教社杯数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...

C# Dapper 操作Oracle数据库

nuget安装内容 1.配置连接字符串 OracleConnectionString这个可用 {"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*","…...

element侧边栏子路由点击不高亮问题

最近自己封装侧边栏 又碰到了点击子路由不高亮的问题 <template><div class"aside"><el-scrollbar :vertical"true" class"scrollbar_left_nav"><el-menu :default-active"defaultActive" :collapse"$stor…...