Maison > Article > interface Web > [Compiler et partager] Quelques questions d'entretien à haute fréquence avec Vue
Cette fois, je partagerai avec vous quelques questions d'entretien courantes sur Vue pour vous aider à trier les connaissances de base et à améliorer votre réserve de connaissances Vue. Cela vaut la peine d'être collecté, venez y jeter un œil !
Ce que je partage, ce sont quelques questions courantes d'entretien avec Vue, mais elles ne représentent pas toutes. S'il y a quelque chose qui ne va pas dans l'article, veuillez le signaler. Si vous avez des doutes ou si vous avez d'autres questions sur l'entretien, vous pouvez également laisser un message dans la zone de commentaire pour en discuter ensemble.
Communication des composants parent-enfant : props
et event
, v-
modèle
, .sync
, ref
, $parent
et
$enfants
. (Partage de vidéos d'apprentissage : tutoriel vidéo vueprops
和 event
、v-
model
、 .sync
、 ref
、 $parent
和
$children
。(学习视频分享:vue视频教程)
非父子组件通信:$attr
和 $listeners
、
provide
和 inject
、eventbus
、通过根实例$root
访问、vuex
、dispatch
和
brodcast
vue 2.0v-model
是⽤来在表单控件或者组件上创建双向绑定的,他
的本质是 v-bind
和 v-on
的语法糖,在
⼀个组件上使⽤ v-model
,默认会为组件绑定名为 value
的
prop
和名为 input
的事件。
Vue3.0
在 3.x 中,⾃定义组件上的 v-model
相当于传递了 modelValue
prop
并接收抛出的update:modelValue
事件
Vuex和全局对象主要有两种区别:
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发⽣变 化,那么相应的组件也会相应地得到⾼效更新。
不能直接改变 store 中的状态。改变 store 中的状态的唯⼀途径就是显式地提交 (commit)mutation。这样使得我们可以⽅便地跟踪每⼀个状态的变化,从⽽让我们能够实现⼀些⼯ 具帮助我们更好地了解我们的应⽤。
渲染过程:⽗组件挂载完成⼀定是等⼦组件都挂载完成后,才算是⽗组件 挂载完,所以⽗组件的mounted在⼦组件mouted之后
⽗beforeCreate -> ⽗created -> ⽗beforeMount -> ⼦beforeCreate -> ⼦created -> ⼦beforeMount -> ⼦mounted -> ⽗mounted
⼦组件更新过程:
⽗组件更新过程:
销毁过程:⽗beforeDestroy -> ⼦beforeDestroy -> ⼦ destroyed -> ⽗destroyed
看起来很多好像很难记忆,其实只要理解了,不管是哪种情况,都⼀定是⽗组件等待⼦组件完 成后,才会执⾏⾃⼰对应完成的钩⼦,就可以很容易记住
v-if
会在切换过程中对条件块的事件监听器和⼦组件进⾏销毁和重建,如果初始条件是false,则什么都不做,直到条件第⼀次为true时才开始渲
染模块。
v-show
只是基于css进⾏切换,不管初始条件是
什么,都会渲染。
所以, v-if
切换的开销更⼤,⽽ v-show
初始化渲染开销更
⼤,在需要频繁切换,或者切换的部分dom很复杂时,使⽤ v-show
更合
适。渲染后很少切换的则使⽤ v-if
)
$attr
et $listeners
,
provide
et inject
, eventbus
, accessibles via l'instance racine $root
, vuex
, expédition
et
brodcast
2. Comment v-model implémente-t-il la liaison bidirectionnelle ? vue 2.0
v-model
est utilisé pour créer une liaison bidirectionnelle sur des contrôles ou des composants de formulaire.
L'essence est du sucre syntaxique pour v-bind
et v-on
.
Lors de l'utilisation de v-model
sur un composant, le composant nommé value
sera lié au composant par défaut.
prop
et un événement nommé input
. 🎜🎜🎜Vue3.0
Dans 3.x, v-model
sur un composant personnalisé équivaut à passer modelValue
prop
et recevez l'événement update:modelValue
lancé🎜v-if
🎜détruira et reconstruira🎜 les écouteurs d'événements et les sous-composants du bloc conditionnel pendant le processus de commutation. Si la condition initiale est fausse, rien ne sera fait. ne démarrera pas tant que la condition ne sera pas vraie pour la première fois.
Module de teinture. 🎜🎜🎜v-show
est juste 🎜une commutation basée sur CSS🎜, quelles que soient les conditions initiales
Tout sera rendu. 🎜🎜Ainsi, le coût de la commutation v-if
est plus élevé, et le coût du rendu d'initialisation v-show
est plus élevé
⼼, 🎜Lorsque des commutations fréquentes sont nécessaires ou que la partie du DOM à commuter est très complexe, il est plus approprié d'utiliser v-show
approprié. Si vous changez rarement après le rendu, il est plus approprié d'utiliser v-if
. 🎜🎜🎜🎜6. Quels problèmes le v-html dans Vue causera-t-il ? 🎜🎜🎜Le rendu dynamique du HTML arbitraire sur le site Web peut facilement conduire à des attaques XSS🎜. Donc cela ne peut être que crédible
Utilisez v-html sur le contenu et ne doit jamais être utilisé sur le contenu soumis par l'utilisateur. 🎜key
est le id
unique attribué à chaque vnode
, en même temps
Pendant le processus de comparaison vnode
, vous pouvez comparer rapidement la clé
pour déterminer si elle est
Qu'il s'agisse du même nœud et que le caractère unique de la key
peut être utilisé pour générer une map
afin d'obtenir plus rapidement
Obtenez le nœud correspondant. key
是给每个 vnode
指定的唯⼀ id
,在同
级的 vnode
diff 过程中,可以根据 key
快速的对⽐,来判断是
否为相同节点,并且利⽤ key
的唯⼀性可以⽣成 map
来更快的获
取相应的节点。
另外指定 key
后,就不再采⽤“就地复⽤”策略了,可以保证渲染的准确性
。
v-for
和 v-if
处于同⼀个节点时, v-
for
的优先级⽐ v-if
更⾼,这意味着 v-if
将分别重复
运⾏于每个 v-for
循环中。如果要遍历的数组很⼤,⽽真正要展示的数据很少时
,这将造成很⼤的性能浪费。computed
,先对数据进⾏过滤。区别:
url 展示上,hash 模式有 "#",history 模式没有
刷新⻚⾯时,hash 模式可以正常加载到 hash 值对应的⻚⾯,⽽ history 没有处 理的话,会返回404,⼀般需要后端将所有⻚⾯都配置重定向到⾸⻚路由。
兼容性。hash 可以⽀持低版本浏览器和 IE
#
后⾯ hash 值的变化,不会导致浏览器向服务器发出请求,浏览器不发出请
求,就不会刷新⻚⾯。同时通过监听 hashchange 事件可以知道 hash 发⽣了哪些变化,然后根据
hash 变化来实现更新⻚⾯部分内容的操作。
history 模式的实现,主要是 HTML5 标准发布的两个 API, pushState
和
replaceState
,这两个 API 可以在改变 url,但是不会发送请求。这样就可以监
听 url 变化来实现更新⻚⾯部分内容的操作。
Model-View-ViewModel
缩写,也就是把 MVC
中
的 Controller
演变成 ViewModel
。流程总结如下:
1、当组件初始化的时候, computed
和 data
会分别建⽴各
⾃的响应系统, Observer
遍历 data
中每个属性设置
get/set
数据拦截
2、初始化 computed
会调⽤ initComputed
函数
注册⼀个 watcher
实例,并在内实例化⼀个 Dep
消
息订阅器⽤作后续收集依赖(⽐如渲染函数的 watcher
或者其他观察该计算属性
变化的 watcher
)
调⽤计算属性时会触发其 Object.defineProperty
的
get
key
en plus, la stratégie de "réutilisation sur place" ne sera plus utilisée, ce qui peut garantir la précision du rendu.
. 🎜v-for
et v-if
Lorsque dans le même nœud, v-
for
a une priorité plus élevée que v-if
, ce qui signifie que v-if
sera répété séparément
S'exécute dans chaque boucle v-for
. Si le tableau à parcourir est très grand, mais que les données réelles à afficher sont très petites
, ce qui entraînera beaucoup de pertes de performances. calculé
pour filtrer d'abord les données. #
La modification de la valeur de hachage n'entraînera pas l'envoi d'une requête au serveur par le navigateur, et le navigateur n'enverra pas de demande.
Si demandé, la page ne sera pas actualisée. En même temps, en écoutant l'événement hashchange, vous pouvez savoir quels changements se sont produits dans le hachage, puis en fonction de
Hash changes pour mettre en œuvre l’opération de mise à jour d’une partie du contenu de la page. 🎜pushState
et
replaceState
, ces deux API peuvent modifier l'url, mais n'enverront pas de requête. De cette façon, vous pouvez surveiller
Écoutez les modifications d'URL pour mettre à jour une partie du contenu de la page. 🎜Model-View-ViewModel
, c'est-à-dire MVC
Le Controller
a évolué vers le ViewModel
. calculé
et données
construiront chacun
Système d'auto-réponse, Observateur
parcourt chaque paramètre d'attribut dans données
get/set
Interception de données 🎜🎜2. L'initialisation calculed
appellera la fonction initComputed
🎜 watcher
et instancier un message Dep
à l'intérieur de celle-ci
L'abonné aux informations est utilisé comme dépendance de collection ultérieure (telle que watcher
de la fonction de rendu ou d'autres propriétés calculées observées.
watcher
)🎜Object.defineProperty
sera déclenché
Fonction accesseur get
🎜Appel de la méthode watcher.depend()
à votre propre abonné au message
Ajoutez d'autres attributs à watcher
dans les subs
de dep
watcher.depend()
⽅法向⾃身的消息订阅器
dep
的 subs
中添加其他属性的watcher
调⽤ watcher
的 evaluate
⽅法(进⽽调⽤
watcher
的 get
⽅法)让⾃身成为其他watcher
的消息订阅器的订阅者,⾸先将 watcher
赋给 Dep.target
,然
后执⾏ getter
求值函数,当访问求值函数⾥⾯的属性(⽐如来⾃
data
、 props
或其他 computed
)时,
会同样触发它们的 get
访问器函数从⽽将该计算属性的 watcher
添加到求值函数中属性的watcher
的消息订阅器 dep
中,当这些
操作完成,最后关闭 Dep.target
赋为 null
并
返回求值函数结果。
3、当某个属性发⽣变化,触发 set
拦截函数,然后调⽤⾃身消息订阅器
dep
的 notify
⽅法,遍
历当前 dep 中保存着所有订阅者 wathcer
的 subs
数组,并逐个
调⽤ watcher
的 update
⽅
法,完成响应更新。
如果⾯试被问到这个问题,⼜描述不清楚,可以直接画出 Vue 官⽅⽂档的这个图,对着图来 解释效果会更好。
Object.defineProperty
对数据进⾏劫持,并结合观察者模式实现。Object.defineProperty
创建⼀个 observe
来
劫持监听所有的属性,把这些属性全部转为 getter
和 setter
。watcher
实例,它会在组件渲染的过
程中把使⽤过的
数据属性通过 getter
收集为依赖。之后当依赖项的 setter
触发
时,会通知 watcher
,从⽽使它关联的组件重新渲染。Object.defineProperty
只能劫持对象的属性,⽽ Proxy
是直接代理对象由于
Object.defineProperty
只能对属性进⾏劫持,需要遍历对象的每个属性。⽽
Proxy 可以直接代理对象。
Object.defineProperty
对新增属性需要⼿动进⾏
Observe
, 由于Object.defineProperty
劫持的是对象的属性,
所以新增属性时,需要重新遍历对象,对其新
增属性再使⽤ Object.defineProperty
进⾏劫持。 也正是因为这个原因,使⽤
Vue 给 data
中的数组或对象新增属性时,需要使⽤ vm.$set
才能
保证新增的属性也是响应式的。
Proxy
⽀持13种拦截操作,这是
defineProperty
所不具有的。
新标准性能红利Proxy 作为新标准,⻓远来看,JS引擎会继续优化
Proxy
,但 getter
和 setter
基本不会再有针对
性优化。
Proxy
兼容性差 ⽬前并没有⼀个完整⽀持 Proxy
所
有拦截⽅法的Polyfill⽅案
Vue 的 Observer
对数组做了单独的处理,对数组的⽅法进⾏编译,并赋值给
数组属性的 __proto__
属性上,因为原型链的机制,找到对应
的⽅法就不会继续往上找了。编译⽅法中会对⼀些会增加索引的⽅法( push
,
unshift
, splice
evaluatewatcher
Méthode /code> (pour appeler
(méthode get
de watcher
) se fait abonné aux autres abonnés aux messages de watcher
. Tout d'abord, définissez watcher
. code> est affecté à Dep.target
, puis
Après avoir exécuté la fonction d'évaluation getter
, lors de l'accès aux propriétés de la fonction d'évaluation (telles que Tathagata Self
data
, props
ou autre calculé
),
Leurs fonctions d'accesseur get
seront également déclenchées, ajoutant ainsi le watcher
de la propriété calculée à l'abonnement au message du watcher
de la propriété dans la fonction d'évaluation dans. dep
, lorsque ceux-ci
L'opération est terminée, et enfin fermez Dep.target
et attribuez-le à null
et
Renvoie le résultat de la fonction d'évaluation. 3. Lorsqu'un certain attribut change, déclenchez la fonction d'interception set
, puis appelez son propre abonné au message.
La méthode notify
de dep
, encore et encore
Le tableau subs
de tous les abonnés wathcer
est enregistré dans la dépendance actuelle, et un par un
Appelez la méthode update
de watcher
méthode pour terminer la mise à jour de la réponse.
Object.defineProperty
et combinée avec le 🎜Modèle Observer🎜. 🎜🎜Vue utilise Object.defineProperty
pour créer un observer
Détournez toutes les propriétés et convertissez-les en getter
et setter
. 🎜🎜Chaque instance de composant dans Vue correspondra à une instance watcher
, qui sera affichée lors du rendu du composant.
Pendant le processus, le utilisé
Les propriétés des données sont collectées en tant que dépendances via des getters
. Ensuite, lorsque le setter
de la dépendance se déclenche
, watcher
sera averti, provoquant le nouveau rendu de son composant associé. 🎜Object.defineProperty
ne peut détourner que les propriétés des 🎜objets🎜, ⽽ Proxy
est direct 🎜 Objet proxy 🎜En raison de
Object.defineProperty
ne peut détourner que les propriétés et doit parcourir chaque propriété de l'objet. Et
Le proxy peut directement proxy des objets. 🎜🎜🎜🎜Object.defineProperty
Les nouvelles propriétés doivent être ajoutées manuellement
Observer
, puisque Object.defineProperty
détourne les propriétés de l'objet,
Par conséquent, lors de l'ajout d'attributs, vous devez parcourir à nouveau l'objet et lui ajouter de nouveaux attributs.
Ajoutez des propriétés, puis utilisez Object.defineProperty
pour le piratage. C'est pour cette raison qu'en utilisant
Lorsque Vue ajoute des attributs au tableau ou à l'objet dans data
, vous devez utiliser vm.$set
.
Assurez-vous que les attributs nouvellement ajoutés sont également réactifs. 🎜🎜🎜🎜Proxy
⽀Prend en charge 🎜13 types d'opérations d'interception🎜, c'est
Ce que defineProperty
n'a pas. 🎜🎜🎜🎜Nouveau proxy de bonus de performance standard En tant que nouveau standard, à long terme, le moteur JS continuera d'être optimisé
Proxy
, mais getter
et setter
ne seront fondamentalement plus ciblés
Optimisation sexuelle. 🎜🎜🎜🎜Proxy
a une mauvaise compatibilité Actuellement, il n'existe pas de support complet pour Proxy
.
Solution Polyfill avec méthode d'interception🎜🎜Observer
de Vue effectue un traitement séparé sur le tableau, compile la méthode du tableau et l'attribue à
Sur l'attribut __proto__
de l'attribut array, en raison du mécanisme 🎜prototype chain🎜, le correspondant
Je ne continuerai pas à chercher la méthode. La méthode de compilation inclura certaines méthodes qui augmenteront l'index (push
,
unshift
, splice
) pour une observation manuelle. 🎜🎜🎜18. Que fait nextTick ? Quel est son principe ? 🎜🎜🎜La condition préalable pour répondre clairement à cette question est de comprendre le processus EventLoop. 🎜nextTick
Pour la mise en œuvre de la micro tâche, il faudra d'abord vérifier si elle est supportée
Promesse
, si elle n'est pas prise en charge, elle pointera directement vers la macro-tâche, et l'implémentation de la macro-tâche sera vérifiée en premier.
Testez s'il prend en charge setImmediate
(pris en charge par les versions supérieures d'IE et d'Etage). S'il n'est pas pris en charge, vérifiez s'il est pris en charge.
MessageChannel est pris en charge. S'il n'est toujours pas pris en charge, il sera finalement rétrogradé à setTimeout
0 ; nextTick
对于 micro task 的实现,会先检测是否⽀持
Promise
,不⽀持的话,直接指向 macrotask,⽽ macro task 的实现,优先检
测是否⽀持 setImmediate
(⾼版本IE和Etage⽀持),不⽀持的再去检测是否⽀
持 MessageChannel,如果仍不⽀持,最终降级为 setTimeout
0;v-on
)。注意:之所以将 nextTick
的回调函数放⼊到数组中⼀次
性执⾏,⽽不是直接在 nextTick
中执⾏回调函数,是为了保证在同⼀个tick内多
次执⾏了 nextTcik
,不会开启多个异步任务,⽽是把这些异步任务都压成⼀个同
步任务,在下⼀个tick内执⾏完毕。
vue模板的编译过程分为3个阶段:
将模板字符串解析⽣成 AST,⽣成的AST 元素节点总共有 3 种类型,1 为普通元素, 2 为 表达式,3为纯⽂本。
Vue 模板中并不是所有数据都是响应式的,有很多数据是⾸次渲染后就永远不会变化的,那么 这部分数据⽣成的 DOM 也不会变化,我们可以在 patch 的过程跳过对他们的⽐对。
此阶段会深度遍历⽣成的 AST 树,检测它的每⼀颗⼦树是不是静态节点,如果是静态节点则 它们⽣成DOM 永远不需要改变,这对运⾏时对模板的更新起到极⼤的优化作⽤。
1、⽣成代码
const code = generate(ast, options)
通过 generate ⽅法,将ast⽣成 render 函数。
Vue3.x改⽤ Proxy
RemarqueCependant, en raison de la haute priorité de la micro-tâche, dans certains cas, elle peut être déclenchée pendant le processus de bouillonnement de l'événement, ce qui entraîne Provoque quelques problèmes, donc certains endroits forceront l'utilisation de tâches macro (telles que
v-on
).
: La raison pour laquelle la fonction de rappel deLe processus de compilation du modèle Vue est divisé en 3 étapes :nextTick
est placée une fois dans le tableau Au lieu d'exécuter la fonction de rappel directement dansnextTick
, il s'agit de garantir que plusieurs appels peuvent être exécutés dans le même tick. LorsquenextTcik
est exécuté pour la première fois, plusieurs tâches asynchrones ne seront pas démarrées. Au lieu de cela, ces tâches asynchrones seront compressées en une seule tâche simultanée. La tâche étape sera exécutée au prochain tick.19. Principe de compilation du modèle Vue
Convertir la chaîne du modèle Analyser et générer AST. Les nœuds d'éléments AST générés ont un total de 3 types, 1 est un élément ordinaire et 2 est un élément ordinaire. L'expression 3 est du texte brut.
Proxy
au lieu de Object.defineProperty. Parce que Proxy peut surveiller directement le
Des modifications sont apportées aux objets et aux tableaux, et il existe jusqu'à 13 méthodes d'interception. Et en tant que nouveau standard, il fera l’objet d’une optimisation continue des performances par les fabricants de navigateurs.
changement. Nous pouvons déterminer si la clé est la propriété cible de l'objet proxy actuel, et nous pouvons également déterminer si l'ancienne valeur et la nouvelle valeur sont égales. Ce n'est que lorsque l'une des deux conditions ci-dessus est remplie qu'il est possible d'exécuter le déclencheur.
key pour garantir l'unicité
Utilisez ⽤ paresseux chargement des routes, composants asynchronesPré-rendu
Rendu côté serveur SSRTree Shaking/Scope Hoistingpermet de charger ⽤cdn le troisième⽅module
Emballage multi-thread happypack 🎜🎜morceaux divisés extrait du texte public 🎜🎜optimisation sourceMap🎜🎜🎜🎜Expérience utilisateur🎜🎜🎜🎜Écran squelette🎜🎜PWA🎜🎜🎜Vous pouvez également utiliser l'optimisation du cache (cache client, cache serveur), activer la compression gzip sur le serveur, etc. 🎜🎜 (Partage de vidéos d'apprentissage : 🎜développement web front-end🎜, 🎜Vidéo de programmation de base🎜)🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!