Vue2023 面试归纳及复习

目录

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

Composition API 的优势

2    Options API 语法格式 

3 setup 语法糖

 4  Vue3的生命周期

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

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

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

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

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

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

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

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

13. Vue3和Vue2最大区别。

14 Vue2.0 的响应式原理

15 Vue3.0 的响应式原理

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

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

18 介绍一下   ref    reactive       toRef    toRefs  函数 

19  setup函数怎么用?

20  watch 和 watchEffect 区别

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

22 Pinia 与 VueX的区别与优缺点:

22  什么是 Reflect ?


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 Pinia 与 VueX的区别与优缺点:

pinia和vuex的区别
(1)pinia它没有mutation,他只有state,getters,action【同步、异步】使用他来修改state数据
 (2)pinia他默认也是存入内存中,如果需要使用本地存储,在配置上比vuex麻烦一点

 (3)pinia语法上比vuex更容易理解和使用,灵活。
 (4)pinia没有modules配置,没一个独立的仓库都是definStore生成出来的

 (5)pinia state是一个对象返回一个对象和组件的data是一样的语法
 

Vuex 和 Pinia 的优缺点
Pinia的优点

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

不支持时间旅行和编辑等调试功能  ?

Vuex的优点

  • 支持调试功能,如时间旅行和编辑
  • 适用于大型、高复杂度的Vue.js项目

Vuex的缺点

  • 从 Vue 3 开始,getter 的结果不会像计算属性那样缓存
  • Vuex 4有一些与类型安全相关的问题

何时使用Pinia,何时使用Vuex


个人感觉:,由于Pinea是轻量级的,体积很小,它适合于中小型应用。它也适用于低复杂度的Vue.js项目,因为一些调试功能,如时间旅行和编辑仍然不被支持。
将 Vuex 用于中小型 Vue.js 项目是过度的,因为它重量级的,对性能降低有很大影响。因此,Vuex 适用于大规模、高复杂度的 Vue.js 项目。

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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/118888.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Linux]套接字通信

摘于https://subingwen.cn,作者:苏丙榅 侵删 文章目录 1. 套接字-socket1.1 概念1.2 网络协议1.3 socket编程1.3.1 字节序1.3.2 IP地址转换1.3.3 sockaddr 数据结构1.3.4 套接字函数 1.4 TCP通信流程1.4.1 服务器端通信流程1.4.2 客户端的通信流程 1.5 扩展阅读1.5.1 初始化套…

黑马 软件测试从0到1 常用分类 模型 流程 用例

课程内容&#xff1a; 1、软件测试基础 2、测试设计 3、缺陷管理 4、Web常用标签 5、项目实战 以终为始&#xff0c;由交付实战目标为终&#xff0c;推出所学知识&#xff1b;从认识软件及软件测试&#xff0c;到如何设计测试、缺陷标准及缺陷管理&#xff0c;最终以项目实战贯…

dockerfile 例子(二)

Dockerfile由一行一行的命令语句组成&#xff0c;#开头的为注释行。Dockerfile文件内容分为四个部分&#xff1a;基础镜像信息、维护者信息、镜像操作指令以及容器启动执行指令。 接下来给大家列出Dockerfile中主要命令的说明。 FROM&#xff0c;指定所创建镜像的基础镜像。 …

汽车电子笔记之:基于AUTOSAR的电机控制器架构设计

目录 1、概述 2、AUTOSAR设计 2.1、SWC设计 2.2、PORT设计 2.3、Runnable设计 2.4、电机控制器OS实现 1、概述 电机控制器应用层的软件架构较为复杂,主要包括PMSM(Permanent-MagnetSynchronous Motor)的矢量控制算法。根据PMSM的控制算法,对算法中的软件功能进行分析&…

java反编译工具jd-gui使用

文章目录 一、JD-GUI介绍二、下载三、安装四、使用教程五、免责声明摘抄 一、JD-GUI介绍 JD-GUI是一个独立的图形实用程序&#xff0c;显示“.class”文件的Java源代码。 使用JD-GUI浏览重构的源代码&#xff0c;以便即时访问方法和字段。 二、下载 MAC安装包&#xff1a;ht…

leetcode410. 分割数组的最大值(java)

分割数组的最大值 题目描述二分法代码演示 题目描述 难度 - 困难 410. 分割数组的最大值 给定一个非负整数数组 nums 和一个整数 m &#xff0c;你需要将这个数组分成 m 个非空的连续子数组。 设计一个算法使得这 m 个子数组各自和的最大值最小。 示例 1&#xff1a; 输入&…

Pyecharts数据可视化(二)

目录 1.绘制散点图 2.绘制饼图 2.1绘制实心饼图 2.2 绘制圆形饼图 2.3 绘制玫瑰图 3.绘制漏斗图 4.绘制仪表盘 5.绘制组合图表 本文主要介绍如何利用Pyecharts来绘制一些常用的可视化图形&#xff0c;比如散点图、饼图、漏斗图等等&#xff0c;具体的绘制方法请见下文。 …

jQuery成功之路——jQuery的DOM操作简单易懂

jQuery的DOM操作 1.jQuery操作内容 jQuery操作内容 1. text() 获取或修改文本内容 类似于 dom.innerText 2. html() 获取或修改html内容 类似 dom.innerHTML 注意: 1. text() 是获取设置所有 2. html() 是获取第一个,设置所有 <!DOCTYPE html> <html lang"zh…

Unity 状态机

Enemy状态以及切换图 程序架构 接口 public interface IState {void OnEnter(); //进入状态时void OnUpdate();//执行状态时void OnExit(); //退出状态时 }接口实现及状态切换类 public class IdleState : IState {private FSM manager;private Parameter parameter;public…

LiteOS qemu realview-pbx-a9 环境搭建与运行

前言 最近打算移植搭建 一些常见的 RTOS 的 qemu 开发学习环境&#xff0c;当前 RT-Thread、FreeRTOS 已经成功运行 qemu&#xff0c;LiteOS 初步验证可以正常 运行 qemu realview-pbx-a9&#xff0c;这里做个记录 首先学习或者研究 RTOS&#xff0c;只是看内核源码&#xff0…

TiDB x 安能物流丨打造一栈式物流数据平台

作者&#xff1a;李家林 安能物流数据库团队负责人 本文以安能物流作为案例&#xff0c;探讨了在数字化转型中&#xff0c;企业如何利用 TiDB 分布式数据库来应对复杂的业务需求和挑战。 安能物流作为中国领先的综合型物流集团&#xff0c;需要应对大规模的业务流程&#xff…

第 3 章 栈和队列(单链队列)

1. 背景说明 队列(queue)是一种先进先出(first in first out,缩为 FIFO)的线性表。它只允许在表的一端进行插入&#xff0c;而在另一端删除元素。 2. 示例代码 1&#xff09;status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果…

Arcface部署应用实战

1、概述 人脸识别的一个比较常用的网络arcface&#xff0c;依赖于其特殊设计的loss函数&#xff0c;使得模型在训练的时候能够实现类间距离增大&#xff0c;类内的距离不断减小&#xff0c;最终使得所训练的backbone能够获取鉴别性很高的特征&#xff0c;便于人脸识别。 本文…

Win11搭建 Elasticsearch 7 集群(一)

一&#xff1a; ES与JDK版本匹配一览表 elasticsearch从7.0开始默认安装了java运行环境&#xff0c;以便在没有安装java运行环境的机器上运行。如果配置了环境变量JAVA_HOME&#xff0c;则elasticsearh启动时会使用JAVA_HOME作为java路径&#xff0c;否则使用elasticsearch根目…

设计模式—简单工厂

目录 一、前言 二、简单工厂模式 1、计算器例子 2、优化后版本 3、结合面向对象进行优化&#xff08;封装&#xff09; 3.1、Operation运算类 3.2、客户端 4、利用面向对象三大特性&#xff08;继承和多态&#xff09; 4.1、Operation类 4.2、加法类 4.3、减法类 4…

【Unity】URP屏幕后处理UI模糊效果实现

这里Canvas(1)设置为Overlay能渲染出指定UI高清&#xff0c;其他UI模糊&#xff0c;然而这做法非常不好&#xff0c;如果此时再打开UI 以及 关闭模糊效果 要将这些置顶UI 恢复到原本Canvas里&#xff0c;也就是要管理2套Canvas using System; using System.Collections; using…

统一使用某一个包管理工具,比如yarn pnpm

原因&#xff1a;前端每个人的习性不一样&#xff0c;有人用npm 有人用yarn等包管理工具&#xff0c;混合下载插件容易出bug&#xff0c;就用个小工具锁住就行了&#xff0c;只能使用yarn或者pnpm反向下载依赖和下载插件。不然就报错 1.在项目主目录下创建preinstall.js // 如…

分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测

分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测 目录 分类预测 | MATLAB实现GRNN广义回归神经网络多特征分类预测分类效果基本介绍模型描述预测过程程序设计参考资料分类效果 基本介绍 MATLAB实现GRNN广义回归神经网络多特

Mybatis学习|多对一、一对多

有多个学生&#xff0c;没个学生都对应&#xff08;关联&#xff09;了一个老师&#xff0c;这叫&#xff08;多对一&#xff09; 对于每个老师而言&#xff0c;每个老师都有N个学生&#xff08;学生集合&#xff09;&#xff0c;这叫&#xff08;一对多&#xff09; 测试环境…

【小沐学Unity3d】3ds Max 骨骼动画制作(Physique 修改器)

文章目录 1、简介2、Physique 工作流程3、Physique 对象类型4、Physique 增加骨骼5、Physique 应用和初始化6、Physique 顶点子对象7、Physique 封套子对象8、设置关键点和自动关键点模式的区别8.1 自动关键点8.2 设置关键点 结语 1、简介 官方网址&#xff1a; https://help.…