destroyedLebenszyklus der Eltern-Kind-Komponente von Vue
Dies ist etwas komplizierter als die vorherige Frage. Sie können versuchen, die Erinnerung zu verstehen oder sich einfach direkt daran zu erinnern
Rendering-Prozess
Vater vor Erschaffen
„Vater erschaffen“ childbeforeCreate
childcreated
Kind vor dem Berg
Kind vor dem Berg
Vater montiert
Update-Prozess
. 🎠
Kind vorUpdate
Kind aktualisiert
Vater aktualisiert
Zerstörungsprozess
Kind vor Zerstörung
Kind zerstört
Vater zerstört
Hinweis Wenn es sich bei den untergeordneten Komponenten um asynchrone Komponenten handelt, ändert sich ihre Ausführungsreihenfolge. Der Lebenszyklus der übergeordneten Komponente wird zuerst ausgeführt und dann wird der Lebenszyklus der untergeordneten Komponente ausgeführt
v-if und v-. show
Die Frage ist eine sehr einfache Frage, und sie ist leicht zu verstehen. In Interviews wird normalerweise gefragt, was der Unterschied zwischen diesen beiden Anweisungen ist und welche Anweisung in welchem Szenario geeignet ist. Antwort
v-for和v-if优先级
这个问题被问到的频率还是比较高的,虽然它在实际开发中并不会这么用。
回答
开发过程中一般不建议同时将v-for和v-if放在一个标签中使用
Vue2中v-for的优先级会更高,所以会先执行循环,再进行v-if判断,所以这样就会导致无论需不需展示这个元素,都会先遍历整个列表
在Vue3中v-if的优先级会更高,但是当我们遍历一个数组的时候,根据数组中的某个元素进行v-if判断的时候就会报错,因为v-if会先执行此时还没有拿到这个数组。所以Vue3中依然不建议这样使用
说一下computed和watch
computed和watch实际工作中用的比较多,所以问的也比较多,一般理解了基本都能回答上来
computed 是计算属性,当一个属性受一个或者多个属性影响的时候可以使用.watch 是侦听器,当我们需要根据一个属性的变化而做出一些处理的时候,可以使用watch 来对这个属性进行监听
computed 具有缓存的特点,即当它所依赖的属性发生改变的时候它才会重新执行内部逻辑.如下代码
<template>
<div>{{ addSum }}</div>
<div>{{ addSum }}</div>
<div>{{ addSum }}</div>
</template>
<script setup>
import { computed, ref, watch } from "vue";
const a = ref(1)
const b = ref(2)
let addSum = computed(() => {
console.log('内部逻辑执行')
return a.value + b.value
})
</script>
页面多次使用addSum
,但是只会打印一次"内部逻辑执行"
watch 在页面首次加载的时候默认不会执行,需要设置immediate:true
首次才会执行监听
watch 默认只监听一层数据,不监听多层数据里属性的变化,需要设置deep:true
才会进行深度监听
vue-router
关于vue-router
能问的问题非常多,比如它的实现原理,路由跳转,路由守卫等等,所以建议去系统的查看vue-router
文档
问题1:vue-router是什么,描述一下它的原理?
Vue Router是Vue官方的路由管理器,有hash和history两种模式
hash
模式是通过监听hashchange
事件来实现更新页面部分内容的操作,url后面会带有#
号
history
模式则是通过监听popstate
事件来实现更新页面部分内容的操作原理和hash
模式差不多,只不过url后面不会出现#
会显得更加美观。同时会带来一个问题,因为没有#
号,所以当用户刷新页面时会向服务器发请求导致请求资源为404,因此需要对nginx
进行一个配置,需要把所有路由都重定向到根页面
问题2:路由跳转方式有哪些?
问题3:说一下路由守卫?
路由守卫分为全局路由守卫 ,路由独享守卫 ,组件路由守卫
beforeEach
,接收to、from、next
三个参数,每个路由跳转前都会触发,登录验证时用的比较多
beforeResolve
,和beforeEach
类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后调用
afterEach,在路由跳转完成后调用,接收to、from两个参数
beforeEnter
Im Allgemeinen wird v-show
an Stellen verwendet, an denen der Status häufig geändert wird. v-if
eignet sich besser für Szenarien, in denen Bedingungen vorliegen Ändern Sie nicht häufig, da die Wechselkosten relativ hoch sind Wird relativ häufig gefragt, obwohl dies in der tatsächlichen Entwicklung nicht verwendet wird. 🎜🎜🎜Antwort🎜🎜🎜🎜🎜Es wird im Allgemeinen nicht empfohlen, während des Entwicklungsprozesses gleichzeitig v-for und v-if im selben Tag zu verwenden🎜🎜🎜Die Priorität von v-for in Vue2 wird also höher sein Die Schleife wird zuerst ausgeführt und dann wird die v-if-Beurteilung durchgeführt. Unabhängig davon, ob dieses Element angezeigt werden muss oder nicht, wird zuerst die gesamte Liste durchlaufen🎜🎜🎜In Vue3 , die Priorität von v-if wird jedoch höher sein, wenn wir ein Array durchlaufen, wird ein Fehler gemeldet, wenn eine v-if-Beurteilung basierend auf einem bestimmten Element im Array vorgenommen wird, da v-if zuerst ausgeführt wird und das Array hat zu diesem Zeitpunkt noch nicht erhalten. Daher wird es immer noch nicht empfohlen, es in Vue3 auf diese Weise zu verwenden mehr in der tatsächlichen Arbeit, also Es gibt viele Fragen, und ich kann sie grundsätzlich beantworten, sobald ich sie verstanden habe🎜🎜🎜🎜🎜berechnet🎜 ist ein berechnetes Attribut, das verwendet werden kann, wenn ein Attribut von einem oder mehreren Attributen beeinflusst wird. 🎜watch🎜 ist ein Listener. Wenn wir eine Verarbeitung basierend auf Änderungen in einem Attribut durchführen müssen, können Sie 🎜watch🎜 verwenden, um dieses Attribut zu überwachen. 🎜🎜🎜🎜computed🎜 hat die Eigenschaften des Cachings Das heißt, wenn sich die Attribute ändern, von denen es abhängt, wird die interne Logik zu gegebener Zeit erneut ausgeführt. Der folgende Code: //子组件
<template>
<slot />
</template>
//父组件
<Child>
<div>默认插槽</div>
</Child> : Die Seite verwendet addSum
mehrmals. aber es wird nur einmal „interne Logikausführung“ ausgegeben🎜🎜🎜🎜🎜 watch🎜 wird standardmäßig nicht ausgeführt, wenn die Seite zum ersten Mal geladen wird. Sie müssen immediate:true
zum Ausführen festlegen Überwachung zum ersten Mal🎜🎜🎜🎜watch🎜Standardmäßig überwacht es nur eine Datenschicht und nicht mehrere. Änderungen an Attributen in Schichtdaten müssen auf deep:true
gesetzt werden > um eine umfassende Überwachung durchzuführen🎜🎜vue-router🎜 🎜🎜Es gibt viele Fragen, die Sie zu vue-router
stellen können >, wie das Implementierungsprinzip, Routensprung, Routenschutz usw., daher wird empfohlen, die Dokumentation des Systems vue-router
zu überprüfen🎜🎜🎜Frage 1: Was ist Vue-Router und beschreibt es Prinzip? 🎜🎜🎜Vue Router ist der offizielle Routing-Manager von Vue. Er verfügt über zwei Modi: Hash und Verlauf. Der hash
-Modus aktualisiert einen Teil des Seiteninhalts, indem er den hashchange
abhört > Ereignis. Auf die URL folgt die Nummer #
🎜🎜history
Der Modus besteht darin, das Funktionsprinzip zu implementieren und einen Teil des Seiteninhalts durch Abhören des popstate-Ereignis. Der hash
-Modus ist ähnlich, außer dass #
nicht nach der URL erscheint, was schöner aussieht. Gleichzeitig wird es ein Problem geben, wenn der Benutzer die Seite aktualisiert, was zu einer 404-Ressourcenanforderung führt. Es ist eine Konfiguration von nginx
erforderlich, alle Routen müssen zur Stammseite umgeleitet werden🎜🎜🎜Frage 2: Was sind die Routing-Jump-Methoden? 🎜🎜🎜🎜🎜Eingebauter Komponentensprung🎜🎜🎜router.push({ path: '/home' })
,router.replace({ path: '/ home' ' })
🎜🎜🎜Frage 3: Erzählen Sie uns etwas über Routing-Guards? 🎜🎜🎜Route Guards sind unterteilt in 🎜Global Route Guards🎜, 🎜Route Exclusive Guards🎜, 🎜Component Route Guards🎜🎜
🎜🎜beforeEach
, der drei Parameter empfängt: to, from und next
. Es wird vor jedem Routensprung ausgelöst. Es wird oft verwendet für Anmeldeüberprüfung. 🎜🎜🎜beforeResolve
, ähnlich wie beforeEach
, der Unterschied besteht darin, dass es aufgerufen wird, bevor die Navigation bestätigt wird und nach den Guards und asynchronen Routing-Komponenten werden in allen Komponenten aufgelöst🎜 🎜🎜afterEach wird nach Abschluss des Routensprungs aufgerufen und erhält zwei Parameter von und nach 🎜
🎜Exklusiver Schutz für die Route 🎜beforeEnter, im Allgemeinen in der Routing-Konfigurationsdatei (router/index.js) konfiguriert, führt verwandte Vorgänge aus, bevor eine bestimmte Route eingegeben wird🎜
接收to、from、next
三个参数
beforeRouteEnter
,进入该组件之前调用,无法获取到vue实例
beforeRouteUpdate
,在当前路由改变,但是该组件被复用时调用
beforeRouteLeave
, 在离开当前组件时调用
vue2和vue3区别
当面试问你会用vue3吗,如果你回答会用的话,那么大概率会问vue2和vue3有哪些区别,最近我去面试的时候百分之90都问了这个问题。
回答
写法上的区别:vue2使用的是options(选项)Api
,vue3的是composition Api
(当然vue3也兼容composition api
)。options Api
中methods,compute,data
等api都是分散的。而composition api
中的代码是根据逻辑功能来组织的,我们可以将一个功能所定义的methods,compute,data
等api会放在一起,让我们可以更灵活地组合组件逻辑。
vue2将响应式数据放到data函数中,而vue3则是使用ref
和reactive
将数据声明为响应式
响应式实现方式:vue2中是通过Object.defineProperty
对数据劫持实现的,vue3中则是使用Proxy
对数据代理实现的。
生命周期区别:vue3中将beforeCreate
和created
合并到了setup
函数中
根节点: vue3组件允许多个根节点,而vue2只允许一个
内置组件: vue3新增了传送组件Teleport
和异步依赖处理组件Suspense
vue插件使用
面试一般会问你如何写一个vue插件,所以没写过vue插件的最好去亲自体验一下
回答:
vue
实例会有一个use
函数,它接受的是一个带有install
函数的对象和一个可选的选项对象,当我们使用 vue.use(plugin)
或者app.use(plugin)
会调用我们插件的install
属性的函数,并且将当前组件的实例传进来.所以在插件中就可以对这个实例进行一些操作来实现我们插件的功能
vue插槽
插槽slot
可以理解为占坑,当使用一个组件的时候,在组件标签里的对应的内容就会替换掉这个组件中的slot
标签。
插槽分为默认插槽
,具名插槽
,作用域插槽
。
默认插槽 子组件中用slot
标签来确定渲染位置,父组件使用它时直接在子组件的标签内写入内容即可
//子组件
<template>
<slot />
</template>
//父组件
<Child>
<div>默认插槽</div>
</Child>
具名插槽
顾名思义就是具有名字的插槽,子组件中可以用name
熟悉对slot
命名,父组件在使用的时候通过template
中的v-slot:name
或者#name
来定义这个插槽中的内容
//子组件
<template>
<slot name="content"></slot>
</template>
//父组件
<Child>
<template v-slot:content>具名插槽内容</template>
</Child>
作用域插槽
子组件中的slot
可以通过类似组件属性传递的方式将子组件的值传递给父组件中这个子组件的插槽内容中
(子组件标签内),在父组件使用子组件的时候要用v-slot
的值进行接收这些参数,默认插槽可以将其直接写在子组件标签上,具名插槽则写在template
上。而传过来的值只能在子组件标签中或者template
标签中使用。所以在父组件作用域中获取到了子组件作用域中的变量,可以认为作用域插槽延伸了子组件数据的作用范围,因此叫做作用域插槽
如果你想详细理解插槽的作用可以阅读这篇文章Vue3中插槽(slot)用法汇总 - 掘金 (juejin.cn)
组件通信
这里我大概归纳了一下vue2和vue3的传参方式
... gibt
Vater an Sohn $ attrs
attrs
son to Father $listeners None (fusioniert in attrs way)
father to son provide/inject provide/inject
Untergeordnete Komponente greift auf übergeordnete Komponente zu $parent Keine
Übergeordnete Komponente greift auf untergeordnete Komponenten zu $kinder Keine
Übergeordnete Komponente greift auf untergeordnete Komponenten zu $ref expose&ref
Geschwisterkomponenten übergeben den Wert EventBus mitt
它们的具体用法可以参考我的这篇文章盘点Vue2和Vue3的10种组件通信方式(值得收藏) - 掘金 (juejin.cn)
除了上面的传参方式你也可以回答Vuex和Pinia,前提你了解这两个状态管理器,因为你说了大概率下个问题就会问你Vuex和Pinia
vuex
面试问到这个问题的时候,不要上来就开始说什么state
,mutation
...。你要先阐述Vuex干嘛用的,什么时候需要用Vuex。
回答
Vuex是Vue中的全局状态管理框架,它可以管理应用的所有组件的状态。并不是每个项目都需要引入Vuex的,当我们的项目有很多个页面,并且这些页面共享着多个数据状态,此时我们可以引入Vuex。
Vuex有三个核心的概念,state
,mutations
,actions
,其中state
为存放数据的地方,mutations
中的函数作用则是用来修改state
,actions
中一般是用了处理一些异步操作的函数。
Vuex除了上面三个概念还有getters
,moudles
,getters
就像Vue中的计算属性computed
一样用来描述依赖响应式状态state中的复杂逻辑。moudles
则是可以将store分割成模块(module) ,每个模块都拥有自己的state
,mutations
,actions
等,在大型应用中经常用到
场景:当我们异步获取结果并赋值给state的时候,比如数据请求,我们可以在actions
中进行数据请求,拿到结果通过它的dispatch
方法调用mutations
中修改state
的函数,从而将结果赋值给了state
pinia
这个现在问的好像不多,从我最近面试来看只有我提到了才会问一下,但是以后问的肯定会越来越多。关于pinia问的一般是它和Vuex的区别,确切的说应该是它和Vuex4之间的区别
回答
pinia
其实就是Vuex5,它和Vuex的主要区别有以下几点
Pinia使用更简单,更符合开发者的开发习惯
pinia
中没有了mutations
,状态state
的修改可以直接进行修改,或者在actions
中修改,或者使用它的$patch
方法进行修改
pinia
中没有了modules
,如果想使用多个store,直接使用defineStore
定义多个store传入不同的id即可
更好的TS支持,不需要创建自定义的复杂包装器来支持TS
vue自定义指令
vue 官方提供了v-text、v-for、v-model、v-if 等常用的指令。除此之外vue 还允许开发者自定义指令。面试经常会问什么是自定义指令?你用自定义指令做过哪些功能?
回答1:什么是自定义指令?
自定义指令包含局部指令和全局指令,在模板中使用指令前必须先使用directives
选项注册。局部指令指在某个组件中注册,而全局则是将指令注册到全局,通常在main.js中注册。
自定义指令由一个包含类似组件生命周期钩子的对象来定义。它的生命周期钩子包含created
,beforeMount
,mounted
,beforeUpdate
,updated
,beforeUnmount
,unmounted
,
常用的钩子为mounted
和 updated
,它接受el
,binding
等参数.binding
参数的值一般包含绑定到这个元素上的信息,比如下面这个指令
<div v-example:foo.bar="baz">
它的binding会是这个对象
{
arg: 'foo',
modifiers: { bar: true },
value: /* `baz` 的值 */,
oldValue: /* 上一次更新时 `baz` 的值 */
}
回答2:你用自定义指令做过哪些功能?
数据埋点,通过绑定自定义事件传入点击当前元素需要埋点的事件名,在指令中监听当前元素的点击事件后调用后台接口将事件名传入
权限控制,通过绑定自定义事件传入控制当前元素的权限字段,在指令中获取到当前元素根据权限字段来控制该元素的状态(显示,隐藏等)
...
keep-alive
官网描述
<KeepAlive>
ist eine integrierte Komponente. Ihre Funktion besteht darin, entfernte Komponenteninstanzen zwischenzuspeichern, wenn dynamisch zwischen mehreren Komponenten gewechselt wird. <KeepAlive>
是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。
回答
通常我们切换组件的时候,上一个组件就会被销毁,而当我们使用<KeepAlive>
将其包裹的话这个组件就会被缓存,当这个组件再一次被显示时就会保留之前的状态。
keep-alive
接收两个属性include
和 exclude
,分别代表哪些组件要用缓存和哪些不需要缓存,它接收组件的名字数组,字符串或者正则,当我们使用动态组件component
或者路由router-view
的时候可以使用
keep-alive
还接收max
属性表示最大缓存实例数,如果超出这个数则最久没有被访问的缓存实例将被销毁。
keep-alive
有两个生命周期,分别是activated
和deactivated
,activated
钩子会在首次挂载或者每次从缓存中被重新插入的时候调用。deactivated
钩子则是在组件从DOM上移除或者组件卸载时调用
vue2混入-Mixin
vue3中已经没有Mixin
这个概念了,所以未来被问到的几率会越来越小,但是目前被问到的频率还是很高的。一般会它的概念以及优缺点,有时还会问它与父组件的生命周期执行顺序
vue官网描述:
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
回答 1.Mixin
的作用将组件的公共逻辑提取出来,哪个组件需要用到时,直接将提取的这部分混入到组件内部即可
2. Mixin
的生命周期会在父组件生命周期之前执行,如果Mixin
中的属性或者方法与父组件冲突则会使用父组件中的
2. 优点:可以降低代码冗余提高逻辑复用性。
3. 缺点:命名容易冲突,不好追溯源,后期排查不方便
vue响应式原理
这道题问道的频率极高,就我经历的多场面试几乎都会问到,而且是面试到vue方面的开门题。
下面是我自己的理解回答,以vue2为例,大家可以借鉴参考
vue的响应式原理是根据Object.defineProperty
这个api来对数据进行劫持并结合发布者-订阅者模式实现的
首先会利用Object.defineProperty
中的get
函数来对vue中的data的所有属性进行访问劫持,中间会涉及到劫持data中更深层次的属性需要递归调用劫持方法。这里是通过一个Observer
类实现的
劫持到每一个属性后会给这个属性绑定多个订阅者watcher
,因为一个属性可能被用在很多地方;而这个watcher
中则包含更新视图的函数update
。
watcher
和属性的对应关系以及和视图的联系则是通过编译模板Compile
类来实现的。Compile
中会拿到整个dom对象,然后遍历元素子节点获取到使用过vue中data属性的则给该属性直接添加一个watcher
并赋予一些更新当前视图的方法.
每个属性的多个订阅者watcher
都会被添加到对应的数组中,这里则是通过Deps
类实现的,初始化watcher
的时候会调用Deps
中的addSub
方法将对应watcher
添加该类的Subs
数组中
当data中的某个属性发生改变时则会触发Object.defineProperty
中的set
函数,这时便会调用该属性的Deps
类中的notify
函数遍历Subs
数组中的订阅者watcher
并调用其函数update
去触发视图的更新
Object.defineProperty和proxy区别
一般问完响应式原理可能会问这两者的区别
回答
Object.defineProperty
只能代理属性,Proxy
代理的是对象。
对象上新增属性,Proxy
可以监听到,Object.defineProperty
Antwort 🎜
🎜Wenn wir Komponenten wechseln, wird normalerweise die vorherige Komponente zerstört, und wenn wir Verwenden Sie zum Umschließen <KeepAlive>
, die Komponente wird zwischengespeichert und der vorherige Status bleibt erhalten, wenn die Komponente erneut angezeigt wird. 🎜
🎜keep-alive
erhält zwei Attribute include
und exclude
, die jeweils darstellen, welche Komponenten zwischengespeichert werden müssen und Es ist kein Caching erforderlich. Es empfängt das Namensarray, die Zeichenfolge oder den regulären Ausdruck der Komponente. Es kann verwendet werden, wenn wir dynamische Komponenten component
oder Routing router-view
verwenden. li>
🎜keep-alive
erhält außerdem das Attribut max
, das die maximale Anzahl von Cache-Instanzen angibt. Wenn diese Anzahl überschritten wird, wird auf die Cache-Instanz nicht zugegriffen für die längste Zeit wird zerstört. 🎜
🎜keep-alive
hat zwei Lebenszyklen, nämlich aktiviert
und deaktiviert
, aktiviert Hook wird aufgerufen, wenn er zum ersten Mal gemountet wird oder jedes Mal, wenn er erneut aus dem Cache eingefügt wird. Der Hook <code>deactivated
wird aufgerufen, wenn die Komponente aus dem DOM entfernt oder deinstalliert wird🎜
vue2 mix-in- Mixin 🎜Vue3 hat nicht mehr das Konzept von Mixin
, daher wird die Chance, gefragt zu werden, in Zukunft immer kleiner, aber die Häufigkeit des Seins gefragt ist immer noch sehr hoch. Im Allgemeinen erfahren Sie mehr über sein Konzept, seine Vor- und Nachteile und manchmal werden Sie auch nach der Ausführungsreihenfolge im Lebenszyklus zwischen ihm und der übergeordneten Komponente fragen. 🎜🎜vue offizielle Website-Beschreibung: 🎜🎜🎜Mixin bietet eine sehr flexible Möglichkeit zur Verteilung Komponenten in Vue-Komponenten. Ein Mixin kann beliebige Komponentenoptionen enthalten. Wenn eine Komponente ein Mixin verwendet, werden alle Optionen des Mixins in die Optionen der Komponente selbst „gemischt“. 🎜🎜Antwort 1. Die Funktion von Mixin
besteht darin, die öffentliche Logik der Komponente zu extrahieren, den extrahierten Teil direkt zu mischen Nur intern
2. Der Lebenszyklus von Mixin
wird vor dem Lebenszyklus der übergeordneten Komponente ausgeführt. Wenn die Eigenschaften oder Methoden in Mixin
mit der übergeordneten Komponente in Konflikt stehen, werden die Eigenschaften oder Methoden ausgeführt in der übergeordneten Komponente verwendet werden.
2. Vorteile: Es kann die Coderedundanz reduzieren und die Wiederverwendbarkeit der Logik verbessern.
3. Nachteile: Namenskonflikte sind einfach, es ist schwierig, die Quelle zu ermitteln, und die spätere Fehlerbehebung ist umständlich Diese Frage wird in fast allen Interviews, die ich erlebt habe, sehr häufig gestellt und ist eine Eröffnungsfrage in Vue-Interviews. 🎜🎜Das Folgende ist mein eigenes Verständnis der Antwort. Am Beispiel von vue2 können Sie darauf verweisen🎜
🎜vues Reaktionsfähigkeitsprinzip basiert auf Object .definePropertyDiese API wird verwendet, um Daten zu kapern und sie in Verbindung mit dem Publisher-Subscriber-Modell zu implementieren🎜
🎜Zunächst verwenden wir den in <code>Object .defineProperty
Die get-Funktion führt eine Zugriffsentführung auf alle Attribute der Daten in Vue durch, was die Entführung tieferer Attribute in den Daten beinhaltet und den rekursiven Aufruf der Entführungsmethode erfordert. Dies wird durch eine Observer
-Klasse implementiert🎜
🎜Nach der Entführung jedes Attributs werden mehrere Abonnenten watcher
an dieses Attribut gebunden, weil Ein Attribut kann sein wird an vielen Stellen verwendet; und dieser watcher
enthält die Funktion update
, die die Ansicht aktualisiert. 🎜
🎜Die entsprechende Beziehung zwischen watcher
und Attributen sowie die Verbindung mit der Ansicht werden durch Kompilieren der Template-Klasse Compile
realisiert. Compile
ruft das gesamte Dom-Objekt ab und durchläuft dann die untergeordneten Elementknoten, um das Datenattribut in Vue zu erhalten. Fügen Sie dann direkt einen Watcher
zum Attribut hinzu und weisen Sie einen Aktualisierungsstrom zu Methode anzeigen.🎜
🎜Mehrere Abonnenten watcher
für jedes Attribut werden dem entsprechenden Array hinzugefügt, hier durch die Klassenimplementierung Deps
, wenn watcher
wird die Methode addSub
in Deps
aufgerufen, um die Klasse hinzuzufügen, die watcher
🎜
🎜Wenn sich im Array Subs
eine Eigenschaft in Daten ändert, wird die Funktion set in <code>Object.defineProperty
ausgelöst, dann wird die Funktion notify in der Klasse Deps
des Attributs wird aufgerufen, um den Watcher des Abonnenten im Array <code>Subs
zu durchlaufen und aufzurufen seine Funktion update
, um die Aktualisierung der Ansicht auszulösen🎜
Object.defineProperty and Proxy Difference 🎜Im Allgemeinen fragen Sie nach dem Prinzip der Reaktionsfähigkeit, nach dem Unterschied zwischen den beiden🎜🎜Antwort 🎜
vue3内置组件
vue3新增了两个内置组件分别是Teleport
和Suspense
。
可以称之为传送门,作用将其插槽内容渲染到 DOM 中的另一个位置,接收两个参数to(要去的位置)和disabled(是否留在原位置)。接收比如下面代码
<teleport to="#popup">
<video src="./my-movie.mp4">
</teleport>
video将会被传送到id为popup的元素下。
<Suspense>
组件用于协调对组件树中嵌套的异步依赖的处理。
它一般用于包裹多个异步组件处理多个异步组件加载前与完成后的统一状态
<Suspense>
组件有两个插槽:#default
和 #fallback
,在初始渲染时,<Suspense>
将在内存中渲染其默认的插槽内容。如果在这个过程中遇到任何异步依赖,则会进入挂起 状态等待异步组件加载完毕。在挂起状态期间,展示的是 #fallback
插槽内容
nextTick及原理
关于nextTick会问到它的用法,然后是它的原理,然后还可能问到JS的时间循环机制。
问题1:vue中的nextTick是干什么用的?
这个其实比较简单,用过都知道它是干嘛的,vue官方的解释是:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
这是什么意思呢,其实vue中修改data不会立刻触发dom更新;而是把需要更新的Watcher加入到queueWatcher队列中,然后在合适的时机在nextTick中调用这些Watcher的更新函数进行dom更新,所以在data刚被修改的时候,我们是获取不到更新后的dom的,这时候便需要调用nextTick函数在它的回调函数中获取到变化后的dom
问题2:nextTick原理
nextTick原理是借助浏览器事件循环来完成的,因为每次事件循环之间都有一次视图渲染,nextTick尽量在视图渲染之前完成dom更新,所以nextTick优先使用的是promise(微任务)实现
每次执行nextTick时会将传入的回调函数放入一个队列中(callbacks数组),然后当在本次事件循环的同步代码执行完毕后开启一个微任务(promise或者MutationObserver)去依次执行这个callbacks中的回调函数。
但是当浏览器不支持promise的时候在vue2中会进行进行降级处理,依次使用setImmediate
、setTimeout
开启一个宏任务执行callbacks
当一个data数据更新时对应的watcher便会调用一次nextTick,将它对应的dom更新操作作为回调函数放入callbacks中,所以当我们想获取这个data更新后的dom需要在其值变化后也调用nextTick将回调函数传入排在上个更新dom的回调函数后面,所以我们可以在这个nextTick的回调函数中获取到更新后的data
问题3:js事件循环机制
不属于vue,后面文章再介绍
vue虚拟dom,diff算法
这题在工作中有用吗是???答案是没有用,但是在面试中有用啊,所以我们要会回答?
问题1:什么是虚拟dom?
简单来说就是一个描述dom结构的js对象
问题2:为什么要用虚拟dom?
问题3:说一下diff算法
Die Essenz des Diff-Algorithmus besteht darin, den Unterschied zwischen zwei Objekten zu finden, mit dem Ziel, Knoten so weit wie möglich wiederzuverwenden. In Vue handelt es sich um einen Algorithmus, der zur Berechnung der Differenz zwischen dem virtuellen DOM nach der Änderung und dem virtuellen DOM vor der Änderung verwendet wird, wenn sich der Status ändert.
Die spezifische Implementierung kann nicht in ein paar Sätzen klar erklärt werden. Ich empfehle einen Artikel. Lassen Sie uns über den Double-Ended-Diff-Algorithmus von Vue sprechen – Nuggets (juejin.cn). Teil Die Informationen basieren auf meinem eigenen Verständnis, daher ist es unvermeidlich, dass es einige Fehler und Unzulänglichkeiten gibt, wenn Sie sie finden. Vielen Dank. (Teilen von Lernvideos:
Web-Frontend-Entwicklung, Einfaches Programmiervideo )