English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

vue从使用到源码实现教程详解

Configurazione dell'ambiente

Indirizzo github del progetto

Nel progetto è stato utilizzato json-server per simulare richieste get, utilizzando vue-router;

Dettagli su Vue lifecycle e funzioni hook di vue-router

Vita del componente

1.0 versione

1. Quali interfacce della vita del componente esistono

init
Created
beforeCompile
Compiled
Ready
Attatched
Detached
beforeDestory
destoryed

2. Ordine di esecuzione

1. Senza keep-alive

Entrata:

init->create->beforeCompile->complied->attatched->ready

Rimozione:

beforeDestory->detached->destoryed;

2. Con keep-alive

La prima volta

Entrata:

init->create->beforeCompile->complied->attatched->ready

Rimozione:

detached;

Ogni volta successiva

Entrata:

attatched

Rimozione:

detached

Funzioni hook

3. Quali funzioni hook esistono

data
activete
deactivate
canactivate
candeactivate

4. Ordine di esecuzione

Entrata:

canactivate->actiavte->date

Rimozione:

candeactivate->deactiavte

Entrambi appaiono insieme

5. Per un componente A che contiene un componente figlio B, quando il componente A esegue operazioni di entrata e uscita, l'ordine di esecuzione della vita del componente e delle funzioni hook è come segue:

Ad esempio

A.vue

<div>
<B></B>
</div>

Nota: il contenuto tra parentesi è il componente figlio annidato

1. Senza keep-alive:

Inserimento:

1. canActivate;
2. init;
3. create;
4. beforeCompile;
5. (Componente figlio annidato: init, create, beforeCompile, compile);
6. compile;
7. activate;
8. data;
9. attached;
(Sotto componente attached);
(Sotto componente ready);
12. ready;

Rimozione:

canDeactivate;
deactivate;
beforeDestroy;
(Sotto componente beforeDestroy);
(Sotto componente destoryed);
detached;
(Sotto componente detached);
20. destoryed;

2. Con keep-alive:

Inserimento:

1. canActivate;
2. activate;
3. data;
4. attached;
5. (Sotto componente attached);

Rimozione:

canDeactivate;
deactivate;
detached;
(Sotto componente detached);

6. Ordine di esecuzione degli hook activate e data

Regole asincrone di risoluzione degli hook funzionali:

1. Se l'hook restituisce una Promise, il momento in cui l'hook viene risolto dipende dal momento in cui la Promise viene risolta.

2. Se l'hook non restituisce una Promise e non ha alcun parametro, l'hook sarà risolto同步mente.

3. Se l'hook non restituisce una Promise, ma ha un parametro (transition), l'hook attende che venga chiamato uno dei seguenti: transition.next(), transition.abort() o transition.redirect() prima di risolvere.

4. Nella validazione degli hook, come canActivate, canDeactivate e gli hook globali beforeEach, se il valore di ritorno è un valore booleano (Boolean), farà anche risolvere同步mente l'hook.

 
 

7. Cosa può garantire che l'interfaccia sia stata aggiornata, ossia completata

Esecuzione del ciclo di vita attached indica che è stato montato

Bindaggio bidirezionale e meccanismo di rendering

1. Monitoraggio e attivazione dei dati(iscrizione e pubblicazione observer)

cartella src sotto observer:

1. array.js

2. dep.js;(Implementare un oggetto di pubblicazione e iscrizione)

3. index.js;(Utilizzando l'API Object.defineProperty e progettando un getter/setter speciale per questa proprietà, quindi chiamando una funzione nel setter per raggiungere l'effetto di ascolto);

Ecco il codice sorgente di questa sezione:

Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
var value = getter ? getter.call(obj) : val
if (Dep.target) {
dep.depend()
if (childOb) {
childOb.dep.depend()
}
if (isArray(value)) {
for (var e, i = 0, l = value.length; i < l; i++) {
e = value[i]
e && e.__ob__ && e.__ob__.dep.depend()
}
}
}
return value
},
set: function reactiveSetter (newVal) {
var value = getter ? getter.call(obj) : val
if (newVal === value) {
return
}
if (setter) {
setter.call(obj, newVal)
} else {
val = newVal
}
childOb = observe(newVal)
dep.notify()
}
)

Semplicemente abbreviare il codice di ascolto e attivazione sopra:

function notidy(obj, key) {
console.log(key + " has changed");
console.log(key + " now is: "+ obj[key]);
}
function ToData(key, val) {
var ob = this;
Object.defineProperty(ob, key, {
enumerable: true,
configurable: true,
get: function() {
return val;
},
set:function(newval){
if(newval==val){
return;
}
val=newval;
notidy(this,key);
}
)
}

directory src di directive.js

Nella directive è possibile vedere una serie di attributi analizzati, mentre l'istanziazione della directive può essere vista in utils/lifecycle.js.

Questo pezzo di codice si trova in Directive.prototype._bind

var watcher = this._watcher = new Watcher(
this.vm,
this.expression,
this._update, // callback
{
filters: this.filters,
twoWay: this.twoWay,
deep: this.deep,
preProcess: preProcess,
postProcess: postProcess,
scope: this._scope
}
)
// v-model con valore inline iniziale devono sincronizzarsi di nuovo
// modello invece di aggiornamento al DOM su init. Essi
// impostare l'hook afterBind per indicare che.
if (this.afterBind) {
this.afterBind()
} else if (this.update) {
this.update(watcher.value)
}
Directive.prototype.set = function (value) {
/* istanbul ignore else */
if (this.twoWay) {
this._withLock(function () {
this._watcher.set(value)
)
} else if (process.env.NODE_ENV !== 'production') {
warn(
'Directive.set() può essere utilizzato solo all'interno di twoWay' +
'directives.'
)
}
}

directory src di Watch.js:

Ecco il codice sotto, che può trovare l'oggetto watcher che implementsubscribe tramite il metodo addDep

Watcher.prototype.addDep = function (dep) {
var id = dep.id
if (!this.newDepIds.has(id)) {
this.newDepIds.add(id)
this.newDeps.push(dep)
if (!this.depIds.has(id)) {
dep.addSub(this)
}
}
}

2. Tutto ciò che è stato detto prima riguardo al binding bidirezionale è anche il meccanismo di rendering interno di VUE, riassunto come segue

1. Monitorando i dati con observer e fornendo la capacità di iscriversi ai cambiamenti di un dato specifico

2. Convertendo template in un document fragment, quindi analizzando le directive all'interno, si ottengono i dati dipendenti di ogni directive e i metodi di aggiornamento. Ad esempio, dopo la解析 di v-text="message" (qui è solo un esempio, la logica del programma è più rigorosa e complessa): il dato dipendente this.$data.message e il metodo di aggiornamento della vista node.textContent = this.$data.message

3. Combinando watcher per unire le due parti menzionate, ossia iscrivendo l'osservatore delle dipendenze della directive all'observer dei dati corrispondenti, in modo che quando i dati cambiano, venga attivato l'observer, che a sua volta attiva il metodo di aggiornamento delle dipendenze correlate, raggiungendo infine l'effetto associato del template originale.

Come ha migliorato 3.vue il rendering errato di v-for con dati identici?

Rendering dell'array

L'ID predefinito di rendering interno del array senza track-by è il valore dell'array value, il che significa che se ci sono valori duplicati nell'array, il fragment fragement ottenuto tramite id è lo stesso, e infine, l'operazione insertBefore sul DOM non avrà effetto a causa di un'istanza identica.

<div>
<ul id='test'>
<li id="child1">child1</li>
<li id="child">child2</li>
</ul>
</div>
<script>
_element1=document.getElementById('child1');
_element2=document.getElementById('child2');
document.getElementById('test').insertBefore(_element1,_element2);
</script>

Il risultato della rendering è che child2 è davanti a child1

L'obiettivo dell'uso di track-by è personalizzare questo id interno, in modo che gli elementi con lo stesso valore nell'array non vengano selezionati con la stessa istanza. C'è una certa differenza tra l'uso di track-by='$index' e altri valori di id unici distintivi, ognuno ha i suoi vantaggi.

Utilizzando $index, i dati invertiti non necessitano di operazioni di spostamento, mentre l'uso di altri id quando l'ordine è diverso richiede operazioni di spostamento corrispondenti.

Rendita degli oggetti

Di solito si utilizza una chiave come id dell'oggetto interno in cache, tramite track-by è anche possibile personalizzare questo id per migliorare le prestazioni.

vm.model = {
a: { id: 1, val: "model1"},
b: { id: 2, val: "model2"},
c: { id: 3, val: "model2"},
}

Aggiornamento della lista

vm.model = {
d: { id: 1, val: "model1"},
e: { id: 2, val: "model2"},
f: { id: 3, val: "model2"}
}

Come ha introdotto l'editor a voi la guida dettagliata di Vue dal suo utilizzo alla realizzazione del codice sorgente, spero che sia utile a tutti voi. Se avete qualsiasi domanda, lasciate un messaggio, l'editor risponderà prontamente. Ringraziamo anche il supporto di tutti per il sito web Yellowscream tutorial!

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il diritto d'autore è di proprietà del rispettivo autore, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene il diritto di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una email a notice#oldtoolbag.com (sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente i contenuti sospetti di violazione del copyright.