Cet article vous apporte quel est le principe de la réactivité de vue ? L'analyse du principe de réactivité de Vue a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer, j'espère qu'elle vous sera utile.
new Vue() => , watch appelle la fonction d'initialisation correspondante
function initState (vm: Component) { vm._watchers = [] const opts = vm.$options if (opts.props) initProps(vm, opts.props) if (opts.methods) initMethods(vm, opts.methods) if (opts.data) { initData(vm) } else { observe(vm._data = {}, true /* asRootData */) } if (opts.computed) initComputed(vm, opts.computed) if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch) } }
initProps et initData
initComputed
Faites attention à watcher.depend() Cette méthode permet à l'observateur qui utilise cet attribut de s'abonner à la dépendance. dans l'observateur, et l'observateur d'attribut calculé poussera l'observateur qui y est abonné dans ses sous-marins (lorsque la valeur de l'attribut calculé change, les observateurs qui y sont abonnés sont avertis)
function createComputedGetter (key) { return function computedGetter () { const watcher = this._computedWatchers && this._computedWatchers[key] if (watcher) { watcher.depend() return watcher.evaluate() } } }
initWatch
Lorsque un nouveau Watcher est appelé dans le code, il sera exécuté tout comme render watcher. Ensuite, utilisez la méthode get de l'observateur et appelez pushTarget pour attribuer l'observateur de l'utilisateur actuel à Dep.target. La valeur de l'instruction = this.getter.call(vm, vm) dans get() déclenchera l'obtention. méthode de l'attribut réactif surveillé par l'observateur personnalisé et modifiez l'utilisateur actuel.
l'observateur pousse les sous-marins dont dépend cet attribut, donc lorsque l'utilisateur
Une fois l'ensemble de propriétés surveillé par l'observateur déclenché, l'observateur abonné à la dépendance est averti de déclencher la mise à jour, c'est-à-dire que le gestionnaire correspondant à la clé liée à l'observateur est déclenché. Appelez ensuite popTarget pour afficher la pile et l'attribuer à Dep.target.
Vue.prototype.$watch = function ( expOrFn: string | Function, cb: any, options?: Object ): Function { const vm: Component = this if (isPlainObject(cb)) { return createWatcher(vm, expOrFn, cb, options) } options = options || {} options.user = true // 代表该watcher是用户自定义watcher const watcher = new Watcher(vm, expOrFn, cb, options) if (options.immediate) { cb.call(vm, watcher.value) } return function unwatchFn () { watcher.teardown() } }
trois observateurs, seul l'observateur calculé n'exécutera pas sa méthode get() au début. Le nouvel observateur de rendu dans $mount appellera la méthode get() et pushTarget pour attribuer l'observateur de rendu actuel à Dep.target. Vient ensuite le point culminant, l'appel à updateComponent, qui exécutera vm._update(vm._render(), hydrating), dans lequel la fonction de rendu déclenchera le get hook des attributs réactifs utilisés en HTML. Le hook get amènera le dépôt d'instance dépendant de la propriété responsive à convertir le rendu actuel
L'observateur est poussé dans son tableau subs, donc lorsque les propriétés réactives dépendantes changent, il traversera les sous-marins pour avertir l'observateur qui y est abonné d'appeler update().
updateComponent = () => { vm._update(vm._render(), hydrating) } new Watcher(vm, updateComponent, noop, { before () { if (vm._isMounted) { callHook(vm, 'beforeUpdate') } } }, true /* isRenderWatcher */)
Je vais commencer directement par le rendu et ne parler que de cela. le dépôt suivant est lié à l'observateur
$mount : nouveau un observateur de rendu (la méthode get de l'observateur attribuera l'observateur de rendu à Dep.target) lorsque vm._update(vm._render(), hydrating), render's À ce moment, les attributs réactifs utilisés en HTML seront obtenus. Dans l'exemple ci-dessus, a est utilisé en premier, et le get hook de a sera déclenché. Parmi eux, dep.depend() poussera l'observateur de rendu actuel dans les sous-marins de dep. l'attribut a dans le tableau.<div id="app"> <div>{{a}}</div> <div>{{b}}</div> </div> new Vue({ el: "#app", data() { return { a:1, } }, computed:{ b() { return a+1 } }, })
Continuez l'exécution et accédez à b (b est la valeur de l'attribut calculé), ce qui déclenchera la méthode get de l'attribut calculé. La méthode get des propriétés calculées est la fonction ComputedGetter renvoyée après l'appel de la fonction createComputedGetter watcher.depend() est exécutée dans la fonction ComputedGetter. La méthode depend de Watcher est réservée exclusivement aux calculs
Utilisé par l'observateur.
Retournez à la méthode watcher.depend() que nous venons de mentionner pour le watcher calculé. Sa fonction est d'exécuter this.dep.depend() (le dep défini par le watcher calculé est utilisé ici). this.dep.depend() amènera l'observateur de rendu actuel à s'abonner à la dépendance de la propriété calculée. La propriété calculée poussera également l'observateur de rendu dans ses propres sous-marins ([render watcher] lorsque la valeur de la propriété calculée est modifiée). , il avertira l'observateur dans les sous-marins d'appeler update(), afin que la page puisse être actualisée si la valeur de l'attribut calculée change.
Retournez au hook get qui a déclenché l'attribut calculé de b. Le hook get exécutera finalement watcher.evaluate(), et watcher.evaluate() exécutera la méthode get() de l'observateur calculé.
Le point clé arrive à ce moment-là. Dep.target (observateur de rendu) sera poussé dans la pile targetStack (après avoir été stocké afin de pouvoir être retiré plus tard pour une utilisation continue), puis l'observateur calculé. de cet attribut calculé sera attribué à Dep .target. Dans la méthode get, value = this.getter.call(vm, vm) exécutera le gestionnaire lié à l'attribut calculé.
Renvoyer un + 1 comme dans l'exemple ci-dessus. Si a est utilisé, le hook get de a sera déclenché, et le hook get appellera dep.depend() amènera l'observateur calculé à stocker dep dans son tableau deps, et le dep de a stockera le dep actuel. . Dep.target (observateur calculé) est stocké dans son tableau subs. Dans l'exemple actuel, les sous-marins de a seront [observateur de rendu, observateur calculé], donc les changements dans la valeur de a traverseront les observateurs dans les sous-marins de a. et appelez la méthode update(). Le a utilisé en HTML sera actualisé lorsque l'observateur d'attributs calculé appelle la méthode update(), il en informera ses propres sous-marins ([render). watcher]) dans le rendu Lorsque le watcher appelle la méthode update, l'attribut calculé b utilisé en HTML rafraîchira le dom (pour rappel ici, je parle juste en gros, cela ne déclenchera pas forcément une mise à jour après l'attribut dont dépend l'attribut calculé change, il le fera comparer une fois le calcul terminé) si la valeur change).
calculé La méthode get() de l'observateur appellera enfin popTarget(), extraira l'observateur de rendu précédemment stocké de la pile et l'attribuera à Dep.target. À ce stade, le targetStack dans mon exemple devient un tableau vide.
La méthode get de render watcher sortira de la pile à la fin de l'exécution. À ce moment, la valeur attribuée à Dep.target sera vide.
Recommandations associées :
Analyse du principe de réactivité des données Vue
À propos des principes de réactivité dans Vue (tutoriel détaillé)
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!