Vue: Ich hoffe, Keep-Alive kann die Funktion des dynamischen Löschens zwischengespeicherter Komponenten erhöhen

Erstellt am 4. Sept. 2017  ·  49Kommentare  ·  Quelle: vuejs/vue

Welches Problem löst diese Funktion?

Wenn ich vue als Single-Page-Anwendung verwende und mehrere Funktionen umgeschaltet werden, hoffe ich, den Effekt der dynamischen Erstellung von Registerkarten zum Wechseln zu erzielen. Alives Wenn die Speichernutzung des Browsers zu groß ist. Ich hoffe, dass es höchstens zehn umschaltbare Tabs gibt, zum Beispiel beim vorherigen werde ich das Programm verwenden, um die entsprechenden Tabs automatisch zu schließen, und ich hoffe, die zwischengespeicherten Komponenten entsprechend zu löschen.

Wie sieht die vorgeschlagene API aus?

Beispiel: vm.$clearKeepAlived(routerName)

feature request

Hilfreichster Kommentar

Wenn ich die Methode von $destroy sehe, denke ich, dass dies die richtige Verwendung ist, die bestimmt, ob die Komponente zwischengespeichert wird, wenn die Seite durch verschiedene Benutzerverhalten in der Komponente verlassen wird.
(Zum Beispiel eine Nachrichtenkomponente, diese Komponente sollte zerstört werden, nachdem die Nachricht erfolgreich gesendet wurde. Wenn sie nicht gesendet wird, sollte der Cache aufbewahrt werden, damit der Benutzer eintreten und beim nächsten Mal fortfahren kann.)
Nach dem Zerstören führt jedoch ein wiederholter Zugriff auf diese Komponente zu seltsamen Ergebnissen und die Komponente kann nicht mehr zwischengespeichert werden.Ich denke, dies ist ein Fehler.

Alle 49 Kommentare

In der Tat, bevor Sie diese Frage einmal im Forum beantworten, können Sie keep-alive von include oder exclude tun.

Um dir ein einfaches Beispiel zu schreiben:
https://jsfiddle.net/jingkaizhao/m5tLg7wt/2/

ist das nicht ein Dup von #6259?

@posva Ja, ähnliche Situation. Es ist dabei, den keep-alive Cache während der Laufzeit dynamisch zu leeren.

@jkzing Vielen Dank, Ihre Methode sollte das oben erwähnte Szenario abschließen können, aber ich habe immer noch ein Szenario, z die Daten direkt aus dem Speicher, wenn Nach dem Ändern eines Datenelements springt das Programm zur Listenseite, in der Hoffnung, neue Daten im Hintergrund zu erhalten. Obwohl ich die neuen Daten aus dem Hintergrund abrufen kann, nachdem die Seite fertig ist, fühlt es sich an nicht elegant genug.Wenn es die obige API gibt, muss ich sie nur nach der Modifikation ändern.Das Keep-Alive dieses Routers ist gelöscht, und die Daten sollten automatisch aus dem Hintergrund bezogen werden. Ich weiß nicht, ob Sie das, was ich gesagt habe, verstehen können. Kurz gesagt, ich hoffe, dass ich die Single-Page-Anwendung elegant an den Multi-Tab-Effekt des vorherigen Iframes anpassen kann: http://www.sucaihuo .com/modals/16/1653/demo / Oben, danke.

@okjesse Dies ist auch möglich, Sie müssen include oder exclude auf höherwertige Komponenten aktualisieren oder, wenn vuex verwendet wird, include vuex Store stellen .

Kurz gesagt, Vue bietet dafür eine grundlegende API. Wenn Sie sie bequem verwenden möchten, müssen Sie sie leicht kapseln.

@jkzing verstehe, danke, ich schreibe jetzt selbst eine Keep-Alive-Implementierung, ich werde versuchen, deiner Methode zu folgen

@jkzing , aber selbst wenn dies erreicht werden kann, denke ich, dass es besser ist, diese API zu haben, die Semantik wird anders sein, was ich möchte, ist, die am Leben erhaltenen Daten zu löschen, die Komponente selbst ist noch am Leben als non-stop Ob der Schalter am Leben wird

Dies ist nur eines der Probleme: Das ständige Öffnen neuer Seiten, auf die wir stoßen, wird zu viel Speicher verursachen und schließlich friert der Browser ein, mit Keepalive sollte das nichts zu tun haben.Wenn wir können, können

Was wir erreichen möchten, ist zu entscheiden, ob die zwischengespeicherte Seite oder eine neue Seite verwendet werden soll, kurz bevor Sie zu der Seite springen.Die alte API kann das nicht

Ich bin auch auf diese Anforderung gestoßen. Dann habe ich auf die Menüliste geklickt, um eine Verbindung herzustellen, ein Label in den Registerkarten hinzugefügt und die neu geöffnete Komponente zwischengespeichert; auf das Schließen-Label geklickt, ich hoffe, die zwischengespeicherte Komponente zu löschen; ich habe das aufgerufen.$ in die deaktivierte Hook-Funktion der Komponente

@fadexiii Ich habe die vorhandene Methode gelöst, die durch dynamisches Setzen von Includes erreicht werden kann

@okjesse Mein Keep-Alive enthält ein <router-view></router-view> Die include -Methode funktioniert nicht

@okjesse Gerade habe ich das Namensattribut von conponent nicht definiert. Nach der Definition ist es okay, danke

Zur Info: implementiert in 2cba6d4cb1db8273ee45cccb8e50ebd87191244e

@fadexiii #6961 Die gleichen Bedürfnisse wie Sie, wie lösen Sie es?

@Jack-93 Keep-alive-Include verwenden, wenn ein neues Tag geöffnet wird, wird der aktuelle Komponentenname zum Include-Array hinzugefügt und der Komponentenname des schließenden Tags wird aus dem Array gelöscht, wenn das Tag geschlossen wird.

Wenn ich die Methode von $destroy sehe, denke ich, dass dies die richtige Verwendung ist, die bestimmt, ob die Komponente zwischengespeichert wird, wenn die Seite durch verschiedene Benutzerverhalten in der Komponente verlassen wird.
(Zum Beispiel eine Nachrichtenkomponente, diese Komponente sollte zerstört werden, nachdem die Nachricht erfolgreich gesendet wurde. Wenn sie nicht gesendet wird, sollte der Cache aufbewahrt werden, damit der Benutzer eintreten und beim nächsten Mal fortfahren kann.)
Nach dem Zerstören führt jedoch ein wiederholter Zugriff auf diese Komponente zu seltsamen Ergebnissen und die Komponente kann nicht mehr zwischengespeichert werden.Ich denke, dies ist ein Fehler.

@wanyaxing Ich bin auch auf ein ähnliches Problem gestoßen wie du. Ich habe Keep-Alive verwendet, um alle Unterkomponenten zwischenzuspeichern.
In diesem Fall gibt es beim ersten Mal kein Problem und es kann normal ausgeführt werden. Nach zwei oder mehr Malen wird B mehrmals zwischengespeichert. Jedes Mal, wenn es von D nach B zurückkehrt, wird ein neues B generiert und The das zuvor zwischengespeicherte B befindet sich noch im Speicher, wie in der Abbildung gezeigt:
image

Der Kerncode lautet wie folgt:
image

@realfly08 Ich habe versucht, eine PR einzureichen, um dieses Problem zu lösen, aber es scheint, dass die Übermittlung fehlgeschlagen ist.Ich habe nicht herausgefunden, wie man die automatische Codeüberprüfung von vue besteht. -https :

Ich habe mich zuvor auch auf den Site-weiten Cache vorbereitet, und dann stieß ich auf die logische Grube des Cache-Updates.
Jetzt habe ich den gesamten Site-Cache aufgegeben, nur den Cache auf den Schlüsselformularseiten aktiviert und dann im Code dynamisch beurteilt, ob die aktuellen Seitendaten beibehalten werden sollen, was ein vorübergehendes Überspringen dieser Probleme ist, aber ich habe immer noch das Gefühl, dass dies Logik ist nicht gut genug.

@wanyaxing Ich bin auch auf ein ähnliches Problem gestoßen. Die zu implementierende logische Funktion ist A->B->C 3 Seiten. Der Cache wird bei der Rückkehr verwendet und beim erneuten Betreten neu gerendert. Derzeit wird jede Seite am Leben gehalten , und dann urteile ich auf Seite B. Wenn es zur vorherigen Seite zurückkehren soll (go -1), zerstören Sie die aktuelle Komponente in deaktiviert und rufen Sie $destroy auf.Wenn Sie Seite C wieder der Reihe nach eingeben, kehren Sie zu Seite B zurück , Sie können sehen, dass es sich um eine neu erstellte B-Seite handelt, es befindet sich gleichzeitig eine B-Seite im Cache

https://www.jianshu.com/p/cd1baf5b03b0
Ich habe das zusammengestellt

@fadexiii Keep-Alive, wie man mit Router-View verwendet?

  <keep-alive :include="includes">
     <router-view></router-view>
  </keep-alive>

include schreibt den Namen in die Routing-Konfiguration:'login'

const router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      component: Login
    }]
 })

Warum weise ich einer leeren Zeichenfolge Includes zu und sie kann trotzdem zwischengespeichert werden?Meine Anforderung ist, die zwischengespeicherte Route manuell zu zerstören

Nachdem die Komponente zerstört wurde, wird der Cache nicht geleert.Ich denke, das Problem liegt hier.
Der Projektverantwortliche empfiehlt die Verwendung von Attributen wie Include für die Verarbeitung.Ich glaube nicht, dass es direkt zerstört wird.Das Gedächtnis kann verbessert werden.

@wanyaxing die von Ihnen eingereichte PR gelesen haben, sie sollte gültig sein oder eine API zum Entfernen des Cache öffnen, oder?

@leixu2txtek Ich habe diese PR aufgegeben.Durch das gewaltsame Löschen des Caches habe ich die Funktion des dynamischen Löschens der getarnten Cache-Komponente realisiert.

Ich verwende derzeit Caching auf der gesamten Site und implementiere die Funktion zum Löschen des Cache basierend auf Geschäftslogik, indem ich das Routing-Ereignis der verlassenden Seite abfange.Die folgenden Code-Snippets dienen als Referenz:

  • Setzen Sie die Router-Ansicht in das Keep-Alive, und die gesamte Site verwendet standardmäßig den Cache.
    <keep-alive><router-view class="transit-view"></router-view></keep-alive>
  • Ich habe alle Seiten in den Routen geschichtet. Zum Beispiel repräsentiert meta.rank die Seitenebene, wie 1,5 > 2,5 > 3,5 bedeutet, dass die zweite Ebene von der ersten Ebene zur dritten Ebene eingegeben wird.
routes: [
{   path: '/', redirect:'/yingshou', },
{   path: '/yingshou',                meta:{rank:1.5,isShowFooter:true},          },
{   path: '/contract_list',           meta:{rank:1.5,isShowFooter:true},          },
{   path: '/customer',                meta:{rank:1.5,isShowFooter:true},          },
{   path: '/wode',                    meta:{rank:1.5,isShowFooter:true},          },
{   path: '/yingfu',                  meta:{rank:1.5,isShowFooter:true},          },
{   path: '/yingfu/pact_list',        meta:{rank:2.5},                            },
{   path: '/yingfu/pact_detail',      meta:{rank:3.5},                            },
{   path: '/yingfu/expend_view',      meta:{rank:4.5},                            },
{   path: '/yingfu/jizhichu',         meta:{rank:5.5},                            },
{   path: '/yingfu/select_pact',      meta:{rank:6.5},                            },
{   path: '/yingfu/jiyingfu',         meta:{rank:7.5},                            },
]
  • Da alle Seiten im Cache gespeichert sind, lautet die Kernidee [Wann wird der Cache zerstört? ]. Mein Design ist: Der aktuelle Seitencache wird beim Wechsel zur nächsten Seite auf der gleichen Ebene gehalten und [der aktuelle Seitencache wird beim Zurückkehren zur vorherigen Seite zerstört].
  • In main.js habe ich die Methode Vue.mixin verwendet, um das Ereignis zum Verlassen der Route abzufangen, und die Funktion zum Zerstören des Seitencaches in der Methode Interception implementiert. Der Kerncode lautet wie folgt:
Vue.mixin({
    beforeRouteLeave:function(to, from, next){
        if (from && from.meta.rank && to.meta.rank && from.meta.rank>to.meta.rank)
        {//如果返回上一层,则摧毁本层缓存。
            if (this.$vnode && this.$vnode.data.keepAlive)
            {
                if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache)
                {
                    if (this.$vnode.componentOptions)
                    {
                        var key = this.$vnode.key == null
                                    ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '')
                                    : this.$vnode.key;
                        var cache = this.$vnode.parent.componentInstance.cache;
                        var keys  = this.$vnode.parent.componentInstance.keys;
                        if (cache[key])
                        {
                            if (keys.length) {
                                var index = keys.indexOf(key);
                                if (index > -1) {
                                    keys.splice(index, 1);
                                }
                            }
                            delete cache[key];
                        }
                    }
                }
            }
            this.$destroy();
        }
        next();
    },
});

Zusammenfassung: Tatsächlich wird durch die KeepAlive-Komponente der oberen Ebene, in der sich die Seitenkomponente befindet, die Cache-Liste im Objekt gewaltsam manipuliert. . .

Einfach und geradlinig, wenn auch nicht sehr elegant, ist es einfach zu bedienen, haha ​​:)

Ich hoffe natürlich trotzdem, dass die offizielle Support-API besser herauskommt.

@wanyaxing Ich kontrolliere das Caching der Seite durch Routing

Zum Beispiel habe ich /executed/ und seine untergeordnete Route /executed/chart/. Ich verwende auch die Mixin-Methode, um zu hacken, um Komponenten zu zerstören, die nicht zwischengespeichert werden müssen, wenn die Route verlässt. Was ich tun möchte, ist eine Route von das Elternteil zur Untermenge Das Elternteil wird zwischengespeichert und andere Bedingungen werden zerstört, so dass wir nur das Routing steuern müssen, ohne irgendwelche Attribute hinzuzufügen, ich bin faul;

// 支持页面保持
Vue.mixin({
  beforeRouteLeave(to, from, next) {

    if (!to.path.startsWith(from.path)) this.$destroy();

    next();

  }
});

Danke @wanyaxing , dein Code ist für mich sehr nützlich. Lassen Sie mich darauf verweisen

Ich habe herausgefunden, dass der Cache nicht zerstört wurde.Versuchen Sie Ihr Bestes, um mit @LinusBorg zu kommunizieren

@wanyaxing Ich habe nach einer Möglichkeit gesucht, den Cache zu erhalten, bin mit dem

Haha.
Auf dieser Grundlage empfiehlt Ihnen @leixu2txtek ein Plugin, kombiniert mit https://github.com/wanyaxing/vue-router-dann ist die Wirkung besser.
Verwenden Sie vue-router-then, um eine Unterseite auf der aktuellen Seite zu öffnen, und Sie können die Informationen oder Ereignisse der Unterseite auf der aktuellen Seite abrufen.
this.$routerThen.push('/chose').then(vm => {})

Um ein am häufigsten verwendete Beispiel zu geben, zum Beispiel beim Ausfüllen der Bestellseite, müssen Sie die Adressliste zur Auswahl öffnen.

<input v-model="price" v-model-link="'/select_address'" />

Dann in der von /select_address geöffneten Route nach Auswahl der Adresse ein Eingabeereignis auslösen und zur Seite zurückkehren.

<script>
methods:{
    clickSomeOne:function(value){
        this.$emit('input',value);
        this.$router.go(-1);
    },
}
</script>

Dies erfordert die direkte Interaktion zwischen Parent- und Child-Routing basierend auf der oben erwähnten Caching-Strategie. Es wird jedoch nach der Implementierung sehr interessant. Die Idee der Entwicklung ist sehr intuitiv. Sie müssen nicht daran denken, temporäre Daten in vuex zu speichern , öffnen Sie einfach die Seite, um die Daten abzurufen.

@fadexiii Meinen Sie, wenn Sie einen Router verwenden, sollte das Include den Namen in der dem Router entsprechenden Komponente enthalten?
---- router.js ----

import ComponentA from 'views/a
export default [
  {path: 'a', component: ComponentA, name: a}
]

---- Aufrufe/a.vue ----

export default {
  name: 'xxxa'
}

Was sollte in include gespeichert werden, ist ComponentA oder a oder xxxa?

@yiwuyu xxxa

@jkzing Was ist, wenn ich dieselbe Komponente zweimal lade, eine muss zwischengespeichert werden und die andere muss nicht zwischengespeichert werden?Ihre Komponentennamen sind gleich.

Ich bin auch auf dieses Problem gestoßen
Meta: {
keepAlive: true // muss zwischengespeichert werden
}
Beim Klicken auf "Schließen" auf "false" setzen
Dann ändere den Listener auf true
Siehe https://mp.csdn.net/postedit/82628953 für Details. Jetzt ist der Test kein Problem. Ich weiß nicht, ob es später Probleme geben wird.

Beim Wechseln der Registerkarte wird der Cache geschlossen und der Cache zerstört und beim nächsten Öffnen und erneuten Laden mit mehreren verschachtelten Sub-Routing-Seiten gilt dasselbe.

In der Tat, bevor Sie diese Frage einmal im Forum beantworten, können Sie keep-alive von include oder exclude tun.

Um dir ein einfaches Beispiel zu schreiben:
https://jsfiddle.net/jingkaizhao/m5tLg7wt/2/

Ich verstehe dieses Beispiel. Ich möchte hier die Götter fragen. Mein Geschäft ist so. Die linke Seite ist eine vertikale Registerkarte. Diese Registerkarte kann vom Benutzer dynamisch hinzugefügt oder gelöscht werden. Klicken Sie auf eine der Registerkarten, und auf der rechten Seite wird die entsprechende angezeigt. Diese Registerkarte.Ein Baum ist eigentlich derselbe Baum, aber die vom Baum ausgewählten Knoten sind unterschiedlich. Die ursprüngliche Idee ist, ein Tab-Element hinzuzufügen, einen Baum auf der rechten Seite hinzuzufügen, beim Wechseln von Tabs wird der Baum ausgeblendet und entsprechend angezeigt (V-Show), aber wenn es mehr Tabs gibt, gibt es viele Bäume auf der rechten Seite und die Dom-Knoten sind zu viele. Wenn Sie die Anzeige nicht ausblenden und v-if verwenden müssen, gibt es Baumzustände (ausgewählt, erweitert, gescrollt), die nicht gespeichert werden können, also dachte ich später von Keep-Alive, die den Staat retten kann. Aber ich bin eine Einzeldatei-Komponente von vue. Die Registerkarten befinden sich auf der Hauptseite. Der Baum ist eine Komponente, die importiert wird. Nach dem Import wird sie direkt in der Komponenteneigenschaft registriert. Wie kann ich mehrere Namen für erstellen? der Baum wie du gepostet hast? ? Aber eigentlich bin ich nur eine Komponente. Ich habe den Namen nur erstellt, um ihn mit dem linken Tab zu verknüpfen. Genauer gesagt, um ein Tab-Element auf der linken Seite zu löschen, löschen Sie auch den Baumpuffer, der diesem Tab-Element in Keepalive entspricht? Aber was sollen wir tun?

@leixu2txtek Ich habe diese PR aufgegeben.Durch das gewaltsame Löschen des Caches habe ich die Funktion des dynamischen Löschens der getarnten Cache-Komponente realisiert.

Ich verwende derzeit Caching auf der gesamten Site und implementiere die Funktion zum Löschen des Cache basierend auf Geschäftslogik, indem ich das Routing-Ereignis der verlassenden Seite abfange.Die folgenden Code-Snippets dienen als Referenz:

  • Setzen Sie die Router-Ansicht in das Keep-Alive, und die gesamte Site verwendet standardmäßig den Cache.
    <keep-alive><router-view class="transit-view"></router-view></keep-alive>
  • Ich habe alle Seiten in den Routen geschichtet. Zum Beispiel repräsentiert meta.rank die Seitenebene, wie 1,5 > 2,5 > 3,5 bedeutet, dass die zweite Ebene von der ersten Ebene zur dritten Ebene eingegeben wird.
routes: [
{   path: '/', redirect:'/yingshou', },
{   path: '/yingshou',                meta:{rank:1.5,isShowFooter:true},          },
{   path: '/contract_list',           meta:{rank:1.5,isShowFooter:true},          },
{   path: '/customer',                meta:{rank:1.5,isShowFooter:true},          },
{   path: '/wode',                    meta:{rank:1.5,isShowFooter:true},          },
{   path: '/yingfu',                  meta:{rank:1.5,isShowFooter:true},          },
{   path: '/yingfu/pact_list',        meta:{rank:2.5},                            },
{   path: '/yingfu/pact_detail',      meta:{rank:3.5},                            },
{   path: '/yingfu/expend_view',      meta:{rank:4.5},                            },
{   path: '/yingfu/jizhichu',         meta:{rank:5.5},                            },
{   path: '/yingfu/select_pact',      meta:{rank:6.5},                            },
{   path: '/yingfu/jiyingfu',         meta:{rank:7.5},                            },
]
  • Da alle Seiten im Cache gespeichert sind, lautet die Kernidee [Wann wird der Cache zerstört? ]. Mein Design ist: Der aktuelle Seitencache wird beim Wechsel zur nächsten Seite auf der gleichen Ebene gehalten und [der aktuelle Seitencache wird beim Zurückkehren zur vorherigen Seite zerstört].
  • In main.js habe ich die Methode Vue.mixin verwendet, um das Ereignis zum Verlassen der Route abzufangen, und die Funktion zum Zerstören des Seitencaches in der Methode Interception implementiert. Der Kerncode lautet wie folgt:
Vue.mixin({
    beforeRouteLeave:function(to, from, next){
        if (from && from.meta.rank && to.meta.rank && from.meta.rank>to.meta.rank)
        {//如果返回上一层,则摧毁本层缓存。
            if (this.$vnode && this.$vnode.data.keepAlive)
            {
                if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache)
                {
                    if (this.$vnode.componentOptions)
                    {
                        var key = this.$vnode.key == null
                                    ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '')
                                    : this.$vnode.key;
                        var cache = this.$vnode.parent.componentInstance.cache;
                        var keys  = this.$vnode.parent.componentInstance.keys;
                        if (cache[key])
                        {
                            if (keys.length) {
                                var index = keys.indexOf(key);
                                if (index > -1) {
                                    keys.splice(index, 1);
                                }
                            }
                            delete cache[key];
                        }
                    }
                }
            }
            this.$destroy();
        }
        next();
    },
});

Zusammenfassung: Tatsächlich wird durch die KeepAlive-Komponente der oberen Ebene, in der sich die Seitenkomponente befindet, die Cache-Liste im Objekt gewaltsam manipuliert. . .

Einfach und geradlinig, wenn auch nicht sehr elegant, ist es einfach zu bedienen, haha ​​:)

Ich hoffe natürlich trotzdem, dass die offizielle Support-API besser herauskommt.

Aber auf diese Weise wird der Speicher nicht freigegeben. Ich schalte Keepalive aus und es wird gut. Keepalive hinzufügen und dann manuell den Cache entfernen und den Speicher zerstören, steigt immer noch. Ich frage mich, ob Sie diesem Aspekt Beachtung geschenkt haben?

@Liudapeng Ich habe die Speichernutzung zuvor nicht sorgfältig untersucht.Ich habe einen groben Test durchgeführt und ihn nicht sorgfältig studiert, nachdem ich den Speicherabfall in der Zeitachse des Speicherdiagramms gesehen habe.

Ich bin in letzter Zeit etwas beschäftigt. Ich habe Ihre Nachricht vor zwei Tagen gesehen und hatte keine Zeit, Ihnen zu antworten.

Ich habe gerade einen weiteren Test gemacht, mehrmals wiederholt, um tief in die fünf oder sechs Ebenen der Seite einzusteigen und dann zur Startseite zurückzukehren.Die Ergebnisse der Speicherzeitleiste sind wie folgt:

  • Aktivieren Sie Keep-Alive und zerstören Sie die Komponente dynamisch (dh verwenden Sie die oben erwähnte Methode):
    > Man sieht deutlich den Speicherabfall in der Timeline, ich glaube der Speicher ist zerstört.
    snipaste_2018-09-29_17-53-09

Keep-alive nicht verwenden:

Da es kein Keepalive gibt, wird der Speicherstapel nicht sehr schnell sein, aber er wird immer höher (vielleicht wird mein Code in Eile geändert und es gibt an anderer Stelle Speicherlecks)
snipaste_2018-09-29_17-50-40

Aber im Allgemeinen denke ich, dass die Speicherauslastung nach der Verwendung der dynamischen Zerstörung immer noch im akzeptablen Bereich liegt. Wenn Sie also einen signifikanten Speicherzuwachs feststellen, sollten Sie überprüfen, ob das Bindungsereignis nicht zerstört wird, wenn die Komponente zerstört wird (was dazu führt, dass Obwohl die Komponente wird aus dem Cache-Array von keepAlive entfernt, sie wird nicht aus dem Speicher zerstört).

Bitte überprüfe es nocheinmal.

@wanyaxing ich habe das gleiche Problem in meinem Projekt,ohne Keep-alive:
image
Der Aufruf von $destory() der dynamischen Komponente funktioniert nicht, und ich finde, dass die JS-Heaps mit der Anzahl der Nodes höher werden. Es scheint, dass die dynamische Komponente DOMs erstellt hat, ohne sie zu zerstören.

@bigggge name ist das Attribut innerhalb der Komponente, nicht das Attribut der Route

Meine Frage ist noch bizarrer. Meine vue-Version ist 2.3.3. Seite A hat einen Code zum Scrollen, um die nächste Seite zu laden. Ich habe von Seite A zu Seite B gewechselt. Als Seite B gescrollt wurde, stellte ich fest, dass der Code für Seite A zum Laden der nächsten Seite würde noch ausgeführt werden. Wenn ich das globale Keep-Alive entferne, tritt das obige Problem nicht auf. Aber alle meine aktivierten sind wieder ungültig, ich muss sie verwenden.

Meine Frage ist noch bizarrer. Meine vue-Version ist 2.3.3. Seite A hat einen Code zum Scrollen, um die nächste Seite zu laden. Ich habe von Seite A zu Seite B gewechselt. Als Seite B gescrollt wurde, stellte ich fest, dass der Code für Seite A zum Laden der nächsten Seite würde noch ausgeführt werden. Wenn ich das globale Keep-Alive entferne, tritt das obige Problem nicht auf. Aber alle meine aktivierten sind wieder ungültig, ich muss sie verwenden.

Es kann durch die globale Überwachung verursacht werden, Sie können beim Scrollen beurteilen, ob es die aktuelle Route ist, und dann entscheiden, ob die nächste Seite geladen werden soll

Meine Frage ist noch bizarrer. Meine vue-Version ist 2.3.3. Seite A hat einen Code zum Scrollen, um die nächste Seite zu laden. Ich habe von Seite A zu Seite B gewechselt. Als Seite B gescrollt wurde, stellte ich fest, dass der Code für Seite A zum Laden der nächsten Seite würde noch ausgeführt werden. Wenn ich das globale Keep-Alive entferne, tritt das obige Problem nicht auf. Aber alle meine aktivierten sind wieder ungültig, ich muss sie verwenden.

Es kann durch die globale Überwachung verursacht werden, Sie können beim Scrollen beurteilen, ob es die aktuelle Route ist, und dann entscheiden, ob die nächste Seite geladen werden soll

Ja, ich verwende das Plug-In vue-infinite-scroll. Wenn ich das globale Keep-Alive verwende, wird das Überwachungsereignis nicht entfernt. Ich habe dieses Plug-In neu geschrieben.

@jkzing Was ist, wenn ich dieselbe Komponente zweimal lade, eine muss zwischengespeichert werden und die andere muss nicht zwischengespeichert werden?Ihre Komponentennamen sind gleich.

Ich habe auch diese Frage. Include kann diese Anforderung nicht erfüllen. Wenn mehrere Routing-Seiten einer Komponente entsprechen, gibt es nur einen Komponentennamen. Was soll ich tun?

Beim Wechseln der Registerkarte wird der Cache geschlossen und der Cache zerstört und beim nächsten Öffnen und erneuten Laden mit mehreren verschachtelten Sub-Routing-Seiten gilt dasselbe.

@heng1234Hallo, haben Sie dieses Problem gelöst?Wer kann eine Kontaktinformation zur Orientierung hinterlassen?

Wechseln Sie die Seiten nicht durch Routing und wechseln Sie nicht nach Komponenten
https://blog.csdn.net/qq_39313596/article/details/82628953

[email protected]

Von: Codezero123
Sendezeit: 03.12.2019 10:04
Empfänger: vuejs/vue
Cc: hlvy; Erwähnung
Betreff: Re: [vuejs/vue] Ich hoffe Keep-Alive kann die Funktion des dynamischen Löschens zwischengespeicherter Komponenten erhöhen (#6509)
Beim Wechseln der Registerkarte wird der Cache geschlossen und der Cache zerstört und beim nächsten Öffnen und erneuten Laden mit mehreren verschachtelten Sub-Routing-Seiten gilt dasselbe.
@heng1234Hallo, hast du dieses
Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder melden Sie sich ab.

@wanyaxing Sie sind für den Routing-Cache mit drei Ebenen nicht effektiv. Wenn beispielsweise in vue-element-admin mehrere Tag-Tags mit drei Ebenen aktiviert sind, wird durch das Wechseln des Tag-Tags die Cache-Komponente nicht zerstört, sondern nur ein Drittel geöffnet -level Routing-Tag-Tag. , Es kann zerstört werden. Aktivieren Sie beispielsweise das folgende Menü1-0 und Menü1-1.
Routing.
{ path: '/nested', component: Layout, redirect: '/nested/menu1/menu1-1', name: 'Nested', meta: { title: 'Nested Routes', icon: 'nested' }, children: [ { path: 'menu1', component: () => import('@/views/nested/menu1/index'), // Parent router-view name: 'Menu1', meta: { title: 'Menu 1' }, redirect: '/nested/menu1/menu1-1', children: [ { path: 'menu1-0', component: () => import('@/views/nested/menu1/menu1-0'), name: 'Menu1-0', meta: { title: 'Menu 1-0', noCache: true } }, { path: 'menu1-1', component: () => import('@/views/nested/menu1/menu1-1'), name: 'Menu1-1', meta: { title: 'Menu 1-1' } }, { path: 'menu1-2', component: () => import('@/views/nested/menu1/menu1-2'), name: 'Menu1-2', redirect: '/nested/menu1/menu1-2/menu1-2-1', meta: { title: 'Menu 1-2' }, children: [ { path: 'menu1-2-1', component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), name: 'Menu1-2-1', meta: { title: 'Menu 1-2-1' } }, { path: 'menu1-2-2', component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), name: 'Menu1-2-2', meta: { title: 'Menu 1-2-2' } } ] }, { path: 'menu1-3', component: () => import('@/views/nested/menu1/menu1-3'), name: 'Menu1-3', meta: { title: 'Menu 1-3' } } ] } ] }

`Vue.mixin({
beforeR outeLeave:function (to, from, next){
if (from.meta.noCache) {
if (this.$vnode && this.$vnode.data.keepAlive) {
if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache) {

      if (this.$vnode.componentOptions) {
        var key = this.$vnode.key == null
          ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '')
          : this.$vnode.key;
        var cache = this.$vnode.parent.componentInstance.cache;
        var keys = this.$vnode.parent.componentInstance.keys;
        if (cache[key]) {
          if (keys.length) {
            var index = keys.indexOf(key);
            if (index > -1) {
              keys.splice(index, 1);
            }
          }
          delete cache[key];
        }
      }
    }
    this.$destroy();
  }
}
next();

},
});`

Die Idee ist diese Art von Idee. Es stellt kein Problem mit der Idee dar. Wann Sie den Cache aufrufen und zerstören, hängt von der spezifischen Implementierung in Ihrem Unternehmen ab.

Diese Art von Szenario auf unserer Geschäftsseite sollte sehr Szenario sein:
1. Ich habe mehrere Seiten durchsucht und muss zwischengespeichert werden
2. Klicken Sie zum Beenden, Sie müssen den gesamten Cache leeren
3. Es gibt andere Aufforderungen zur Fehlerumleitung nach der Anmeldung, diese Seiten werden nicht zwischengespeichert
4. Die Anmeldung ist erfolgreich und die neue Seite wird weiterhin zwischengespeichert

Jetzt stellte ich fest, dass es unmöglich war, alle Caches zu löschen, wenn 2 erreicht wurde. Den maximalen Wert von Keep-Alive in vuex zu setzen und auf 1 zu setzen, ist immer noch ungültig, je nach Vue-Entwicklertools gibt es immer noch zwischengespeicherte Seiten.
Was mir noch seltsamer ist, ist, dass das Springen zu anderen Nicht-Login-Seiten in 3 das Mounten der zwischengespeicherten Seite in 1 auslöst und wenn man sich die Entwicklertools ansieht, sind diese Seiten alle inaktiv. Hey, das führt zu einer anderen Seitenlogik des Problems.
Nach langer Suche weiß ich immer noch nicht warum

Diese Art von Szenario auf unserer Geschäftsseite sollte sehr Szenario sein:
1. Ich habe mehrere Seiten durchsucht und muss zwischengespeichert werden
2. Klicken Sie zum Beenden, Sie müssen den gesamten Cache leeren
3. Es gibt andere Aufforderungen zur Fehlerumleitung nach der Anmeldung, diese Seiten werden nicht zwischengespeichert
4. Die Anmeldung ist erfolgreich und die neue Seite wird weiterhin zwischengespeichert

Jetzt stellte ich fest, dass es unmöglich war, alle Caches zu löschen, wenn 2 erreicht wurde. Den maximalen Wert von Keep-Alive in vuex zu setzen und auf 1 zu setzen, ist immer noch ungültig, je nach Vue-Entwicklertools gibt es immer noch zwischengespeicherte Seiten.
Was mir noch seltsamer ist, ist, dass das Springen zu anderen Nicht-Login-Seiten in 3 das Mounten der zwischengespeicherten Seite in 1 auslöst und wenn man sich die Entwicklertools ansieht, sind diese Seiten alle inaktiv. Hey, das führt zu einer anderen Seitenlogik des Problems.
Nach langer Suche weiß ich immer noch nicht warum

In Ihrem Szenario sollten Sie zum Zeitpunkt 2 erwägen, die Seite direkt zu aktualisieren, was die sicherste und direkteste Lösung ist.

Da include dem Namen der Komponente entspricht, was ist, wenn mehrere Routen einer Komponente entsprechen? Gibt es eine Möglichkeit, der gleichen Komponente einen anderen Namen zu geben?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

gkiely picture gkiely  ·  3Kommentare

bfis picture bfis  ·  3Kommentare

bdedardel picture bdedardel  ·  3Kommentare

guan6 picture guan6  ·  3Kommentare

aviggngyv picture aviggngyv  ·  3Kommentare