Detaillierte Erläuterung des SSR-Server-Side-Rendering-Beispiels von Vue

Detaillierte Erläuterung des SSR-Server-Side-Rendering-Beispiels von Vue

Warum Server-Side Rendering (SSR) verwenden?

  • Bessere SEO, da Suchmaschinen-Crawler die vollständig gerenderte Seite direkt anzeigen können.
    Beachten Sie, dass Google und Bing synchrone JavaScript-Anwendungen derzeit problemlos indizieren. Hier kommt es vor allem auf die Synchronisierung an. Wenn Ihre Anwendung zunächst ein Gänseblümchenbild anzeigt, das geladen wird, und den Inhalt dann über Ajax abruft, wartet der Crawler nicht auf die asynchrone Fertigstellung, bevor er den Seiteninhalt abruft. Wenn SEO für Ihre Site jedoch von entscheidender Bedeutung ist und Ihre Seiten Inhalte asynchron abrufen, benötigen Sie möglicherweise Server-Side-Rendering (SSR), um dieses Problem zu lösen.
  • Schnellere Bereitstellung von Inhalten, insbesondere bei langsamen Netzwerken oder auf langsamen Geräten. Sie müssen nicht warten, bis das gesamte JavaScript heruntergeladen und ausgeführt wurde, bevor die vom Server gerenderte Auszeichnung angezeigt wird. Ihre Benutzer sehen also schneller die vollständig gerenderte Seite. Dies führt im Allgemeinen zu einer besseren Benutzererfahrung und ist von entscheidender Bedeutung für Anwendungen, bei denen die Zeit bis zur Bereitstellung von Inhalten direkt mit der Konvertierungsrate korreliert.

Bei der Verwendung von Server-Side-Rendering (SSR) gibt es auch einige Kompromisse:

  • Durch Entwicklungsbedingungen begrenzt. Browserspezifischer Code, der nur in bestimmten Lifecycle-Hooks verwendet werden kann. Einige externe Bibliotheken erfordern möglicherweise eine spezielle Behandlung, um in serverseitig gerenderten Anwendungen ausgeführt zu werden.
  • Weitere Anforderungen bezüglich Build-Setup und Bereitstellung. Im Gegensatz zu vollständig statischen Single-Page-Anwendungen (SPAs), die auf jedem statischen Dateiserver bereitgestellt werden können, erfordern serverseitig gerenderte Anwendungen einen Node.js-Server, um in der Umgebung ausgeführt zu werden.
  • Höhere serverseitige Belastung. Das Rendern einer vollständigen Anwendung in Node.js beansprucht offensichtlich mehr CPU als das bloße Bereitstellen statischer Dateien. Wenn Sie also mit hohem Datenverkehr rechnen, bereiten Sie sich entsprechend auf die Serverlast vor und verwenden Sie Caching-Strategien mit Bedacht.

Verzeichnisstruktur

1. Definieren Sie Verpackungsbefehle und Entwicklungsbefehle

Entwicklungsbefehle werden für die Client-Entwicklung verwendet

Verpackungsbefehle werden verwendet, um serverseitige Entwicklung bereitzustellen

–watch ist praktisch, um Dateien zu ändern und sie dann automatisch zu verpacken

"client:build": "webpack --config scripts/webpack.client.js --watch",
"Server:Build": "webpack --config scripts/webpack.server.js --watch",
"run:all": "gleichzeitig \"npm run client:build\" \"npm run server:build\""

So führen Sie client:build und server:build gleichzeitig aus

1.1 Paket.json

{
  "Name": "11.vue-ssr",
  "version": "1.0.0",
  "Beschreibung": "",
  "main": "index.js",
  "Skripte": {
    "client:dev": "webpack serve --config scripts/webpack.client.js",
    "client:build": "webpack --config scripts/webpack.client.js --watch",
    "Server:Build": "webpack --config scripts/webpack.server.js --watch",
    "run:all": "gleichzeitig \"npm run client:build\" \"npm run server:build\""
  },
  "Schlüsselwörter": [],
  "Autor": "",
  "Lizenz": "ISC",
  "Abhängigkeiten": {
    "gleichzeitig": "^5.3.0",
    "koa": "^2.13.1",
    "koa-router": "^10.0.0",
    "koa-static": "^5.0.0",
    "vue": "^2.6.12",
    "vue-router": "^3.4.9",
    "vue-server-renderer": "^2.6.12",
    "vuex": "^3.6.0",
    "webpack-merge": "^5.7.3"
  },
  "devAbhängigkeiten": {
    "@babel/core": "^7.12.10",
    "@babel/preset-env": "^7.12.11",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.0.1",
    "html-webpack-plugin": "^4.5.1",
    "vue-loader": "^15.9.6",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^5.13.0",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.2"
  }
}

1.2 Grundkonfiguration von webpack.base.js

// Die von webpack gepackte Eintragsdatei muss die Konfiguration exportieren // webpack webpack-cli
// @babel/core Babels Kernmodul // Babel-Loader ist eine Brücke zwischen Webpack und Babel // @babel/preset-env konvertiert es6+ in eine Low-Level-Syntax // Vue-Loader Vue-Template-Compiler analysiert .vue-Dateien und kompiliert Vorlagen // Vue-Style-Loader CSS-Loader analysiert CSS-Stile und fügt sie in Stil-Tags ein, Vue-Style-Loader unterstützt serverseitiges Rendering const path = require('path');
const HtmlWebpackPlugin = erfordern('html-webpack-plugin');
const VueLoaderPlugin = erforderlich('vue-loader/lib/plugin')
modul.exporte = {
    Modus: "Entwicklung",
    Ausgabe: {
        Dateiname: '[name].bundle.js', // Der Standard ist main, der Standard ist der dist-Verzeichnispfad: path.resolve(__dirname,'../dist')
    },
    Modul: {
        Regeln: [{
            Test: /\.vue$/,
            verwenden: „vue-loader“
        }, {
            Test: /\.js$/,
            verwenden: {
                Loader: 'babel-loader', // @babel/core -> voreingestellte Umgebung
                Optionen:
                    Voreinstellungen: ['@babel/preset-env'], // Sammlung von Plugins}
            },
            exclude: /node_modules/ // gibt an, dass Dateien unter node_modules nicht durchsucht werden müssen}, {
            Test: /\.css$/,
            verwenden: ['vue-style-loader', {
                Lader: "CSS-Lader",
                Optionen:
                    esModule: false, // Beachten Sie, dass vue-style-loader in Verbindung mit verwendet wird
                }
            }] // Von rechts nach links ausführen }]
    },
    Plugins: [
        neues VueLoaderPlugin() // Behoben]
}

1.3 Die Konfiguration von webpack.client.js ist die Client-Entwicklungskonfiguration, die die normale Konfiguration des Vue Spa-Entwicklungsmodus ist

const {merge} = erfordern('webpack-merge');
const base = erfordern('./webpack.base');
const Pfad = require('Pfad')
const HtmlWebpackPlugin = erfordern('html-webpack-plugin')
modul.exporte = merge(base,{
    Eintrag: {
        Client:Pfad.Auflösen(__Verzeichnisname, '../src/client-entry.js')
    },
    Plugins:[
        neues HtmlWebpackPlugin({
            Vorlage: Pfad.auflösen(__dirname, '../public/index.html'),
            Dateiname: „client.html“
            // Der Standardname ist index.html
        }),
    ]
})

1.4 Die Konfiguration webpack.server.js wird nach dem Verpacken für die Serverbereitstellung verwendet

const base = erfordern('./webpack.base')
const {merge} = erfordern('webpack-merge');
const HtmlWebpackPlugin = erfordern('html-webpack-plugin')
const Pfad = require('Pfad')
modul.exporte = merge(base,{
    Ziel: 'Knoten',
    Eintrag: {
        server:Pfad.auflösen(__dirname, '../src/server-entry.js')
    },
    Ausgabe:{
        libraryTarget:"commonjs2" // module.exports exportieren},
    Plugins:[
        neues HtmlWebpackPlugin({
            Vorlage: Pfad.auflösen(__dirname, '../public/index.ssr.html'),
            Dateiname:'server.html',
            excludeChunks:['Server'],
            minimieren:false,
            Kunde: '/client.bundle.js'
            // Der Standardname ist index.html
        }),
    ]
})

excludeChunks:['server'] importiert das Paket server.bundle.js nicht

Client ist eine Variable
minify ist nicht komprimiert

Dateiname ist der Name der HTML-Datei, die nach dem Verpacken generiert wird.

Vorlage: Vorlagendatei

2. Schreiben Sie HTML-Dateien

Zwei Portionen:

2.1 öffentlich/index.html

<!DOCTYPE html>
<html lang="de">
<Kopf>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=Gerätebreite, Anfangsmaßstab=1.0">
    <title>Dokument</title>
</Kopf>
<Text>
    <div id="app"></div>
</body>
</html>

2.2 öffentlich/index.ssr.html

<!DOCTYPE html>
<html lang="de">
<Kopf>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=Gerätebreite, Anfangsmaßstab=1.0">
    <title>Dokument</title>
</Kopf>
<Text>
    <!--vue-ssr-outlet-->

    <!-- ejs-Vorlage -->
    <script src="<%=htmlWebpackPlugin.options.client%>"></script>
</body>
</html>
<!--vue-ssr-outlet--> ist die feste Slot-Position, die vom Server zum Rendern des DOM verwendet wird. <%=htmlWebpackPlugin.options.client%> füllt die Variablen von htmlwebpackplugin

3. Schreiben Sie gemäß der normalen Vue-Entwicklung die entsprechenden Dateien

Definieren Sie eine app.js-Datei

src/app.js

Der Zweck der Konvertierung des Eintrags in eine Funktion besteht darin, bei jedem Rendern des Servers eine neue Instanz über diese Factory-Funktion zurückzugeben und so sicherzustellen, dass jeder Besucher seine eigene Instanz erhalten kann.

importiere Vue von „vue“;
App aus „./App.vue“ importieren
importiere createRouter aus './router.js'
importiere createStore aus „./store.js“
// Der Zweck der Konvertierung des Eintrags in eine Funktion besteht darin, bei jedem Rendern des Servers eine neue Instanz über diese Factory-Funktion zurückzugeben und so sicherzustellen, dass jeder Besucher seine eigene Instanz erhalten kann. export default () => {
    const router = createRouter();
    const store = erstelleStore()
    const app = new Vue({
        Router,
        speichern,
        rendern: h => h(App)
    });
    Rückgabe { App, Router, Store }
}

src/app.vue

<Vorlage>
  <div id="app">
    <router-link to="/">foo</router-link>
    <router-link to="/bar">Bar</router-link>
    <Router-Ansicht></Router-Ansicht>
  </div>
</Vorlage>
<Skript>
Standard exportieren {};
</Skript>

src/Komponente/Bar.vue

<Vorlage>
  <div>
    {{ $store.state.name }}  
   
  </div>
</Vorlage>

<Stil scoped="true">
div {
  Hintergrund: rot;
}
</Stil>

<Skript>
Standard exportieren {
    asyncData(store){ //Methode wird auf dem Server ausgeführt, aber diese Methode wird auf der Backend-Konsole ausgeführt.log('Serveraufruf')
       // axios.get('/Serverpfad')
        returniere Promise.resolve('Erfolg')
    },
    mounted(){ // Browser führt aus, Backend ignoriert}
}
</Skript>

src/Komponente/Foo.vue

<Vorlage>
    <div @click="anzeigen">foo</div>
</Vorlage>
<Skript>
Standard exportieren {
    Methoden:{
        zeigen(){
            Alarm(1)
        }
    }
}
</Skript>

src/router.js

importiere Vue von „vue“;
importiere VueRouter von „vue-router“;
importiere Foo aus './components/Foo.vue'
Importiere Bar aus './components/Bar.vue'
Vue.use(VueRouter); // Zwei globale Komponenten werden intern bereitgestellt Vue.component()


//Jeder, der auf den Server zugreift, muss ein Routing-System generieren export default ()=>{
    let router = neuer VueRouter({
        Modus: „Verlauf“,
        Routen:[
            {Pfad:'/',Komponente:Foo},
            {path:'/bar',component:Bar}, // Lazy Loading, lade die entsprechende Komponente dynamisch entsprechend dem Pfad {path:'*',component:{
                rendern:(h)=>h('div',{},'404')
            }}
        ]
    });
    Rückrouter;
}




//Zwei Möglichkeiten zur Front-End-Routing-Hash-Historie

// Hash # 

// Routing dient dazu, verschiedene Komponenten entsprechend unterschiedlicher Pfade zu rendern. Das Merkmal des Hash-Werts besteht darin, dass eine Änderung des Hash-Werts nicht dazu führt, dass die Seite erneut gerendert wird. Wir können die Änderung des Hash-Werts überwachen, um die entsprechende Komponente anzuzeigen (Verlauf kann generiert werden). Das Merkmal von hashApi besteht darin, dass es hässlich ist (der Server kann den Hash-Wert nicht abrufen).

// historyApi Die API von H5 ist wunderschön. Das Problem besteht darin, dass beim Aktualisieren eine 404-Fehlermeldung auftritt. 

src/store.js

importiere Vue von „vue“;
importiere Vuex von „vuex“;

Vue.use(Vuex);
//Verwenden Sie vuex auf dem Server, um Daten im globalen Variablenfenster zu speichern, und ersetzen Sie die vom Server gerenderten Daten durch die vom Browser gerenderten Daten. Export Standard ()=>{
    let store = neuer Vuex.Store({
        Zustand:{
            Name: „Zhufeng“
        },
        Mutationen:
            changeName(Status,Nutzlast){
                Zustand.Name = Nutzlast
            }
        },
        Aktionen: {
            Änderungsname({commit}){// store.dispatch('Änderungsname')
                returniere neues Promise((lösen,ablehnen)=>{
                    setzeTimeout(() => {
                        commit('Name ändern','jiangwen');
                        lösen();
                    }, 5000);
                })
            }
        }

    });

    wenn(Fenstertyp!='undefined' && Fenster.__INITIAL_STATE__){
        // Der Browser beginnt mit dem Rendern // Synchronisiere die gerenderten Ergebnisse des Backends mit der Kernmethode im Front-End vuex store.replaceState(window.__INITIAL_STATE__); // Ersetze es durch die vom Server geladenen Daten}
    Rückgabegeschäft;
}

4. Definieren Sie die Eingabedatei

Die Paketeintragsdatei des Client-Pakets:

src/client-entry.js ist die JS-Eintragsdatei für den Client

importiere createApp aus „./app.js“;
let {app} = erstelleApp();
app.$mount('#app'); // Clientseitiges Rendering kann client-entry.js direkt verwenden

src/server-entry.js Server-Eintragsdatei

Es handelt sich um eine Funktion, die vom Server ausgeführt wird, wenn er sie anfordert.

// Servereintrag importiere createApp von './app.js';


// Serverseitiges Rendering kann eine Funktion zurückgeben export default (context) => { // Der Server übergibt das URL-Attribut beim Aufruf der Methode // Diese Methode wird auf dem Server aufgerufen // Das Routing ist eine asynchrone Komponente, daher muss ich hier warten, bis die Route geladen ist const { url } = context;
    returniere neues Promise((auflösen, ablehnen) => { // renderToString()
        let { app, router, store } = createApp(); // vue-router
        router.push(url); // Zeigt einen permanenten Sprung/Pfad an router.onReady(() => { // Wartet, bis die Route zum Sprung abgeschlossen ist und die Komponente zum Auslösen bereit ist const matchComponents = router.getMatchedComponents(); // /abc


            if (matchComponents.length == 0) { //Keine Übereinstimmung mit der Front-End-Route return reject({ code: 404 });
            } anders {
                // matchComponents bezieht sich auf alle Komponenten, die mit der Route übereinstimmen (Komponenten auf Seitenebene)
                Versprechen.alles(matchComponents.map(Komponente => {
                    if (component.asyncData) { // Der Server findet die asyncData beim Rendern standardmäßig in der Komponente auf Seitenebene, erstellt außerdem ein Vuex auf dem Server und übergibt es an asyncData
                        gibt Komponente.asyncData(Store) zurück
                    }
                })).then(()=>{ // Standardmäßig wird eine Variable unter dem Fenster generiert. Dies geschieht standardmäßig // "window.__INITIAL_STATE__={"name":"jiangwen"}"
                    context.state = store.state; // Nachdem der Server ausgeführt wurde, wird der letzte Status in store.state gespeichert resolve(app); // app ist die Instanz, die die Daten erhalten hat })
            }
        })
    })



    // App entspricht newVue und wird nicht vom Router verwaltet. Ich hoffe, warten zu können, bis der Router springt, bevor ich serverseitiges Rendering durchführe // Wenn ein Benutzer eine nicht vorhandene Seite besucht, wie kann die Front-End-Route angepasst werden // Jedes Mal kann eine neue Anwendung generiert werden}

// Wenn der Benutzer die Leiste besucht: Ich führe das serverseitige Rendering direkt auf dem Server durch und das gerenderte Ergebnis wird an den Browser zurückgegeben. Der Browser lädt das JS-Skript, lädt das JS-Skript entsprechend dem Pfad und rendert die Leiste erneut

component.asyncData ist eine asynchrone Anfrage. Warten Sie, bis die Anfrage abgeschlossen ist, bevor Sie context.state = store.state festlegen. Zu diesem Zeitpunkt „window. INITIAL_STATE = {"name": "jiangwen"}“
Der Store des Clients kann das Fenster „INITIAL_STATE“ abrufen und neu zuweisen.

5. Definieren Sie die serverseitige Datei server.js, einen mit Knoten bereitgestellten Server, und fordern Sie die entsprechende Vorlagendatei an

Verwenden Sie koa und koa-router zur Anforderungsverarbeitung

vue-server-renderer ist ein Must-Have-Paket für serverseitiges Rendering

Koa-static verarbeitet Anfragen für statische Ressourcen wie JS-Dateien

serverBundle ist das gepackte js

Vorlage ist das HTML, das nach dem Servereintrag server:build gepackt ist

const Koa = erfordern('koa');
const app = new Koa();
const Router = erforderlich('koa-router');
const router = neuer Router();
const VueServerRenderer = erforderlich('vue-server-renderer').
const static = erforderlich('koa-static')

const fs = erfordern('fs');
const Pfad = require('Pfad')
const serverBundle = fs.readFileSync(Pfad.resolve(__dirname, 'dist/server.bundle.js'), 'utf8')
const template = fs.readFileSync(Pfad.resolve(__dirname, 'dist/server.html'), 'utf8');


// Erstellen Sie einen Renderer basierend auf der Instanz und übergeben Sie das gepackte JS und die Vorlagendatei const render = VueServerRenderer.createBundleRenderer(serverBundle, {
    Vorlage
})

// Anfrage an localhost:3000/ Übergeben Sie diese entsprechend dem URL-Parameter der Anfrage -》 {url:ctx.url} an serverBundle. Anschließend wird eine Seite mit der vollständigen DOM-Dekonstruktion der Route entsprechend dem gepackten .js-Routingsystem auf dem Server gerendert. router.get('/', async (ctx) => {
    console.log('springen')
    ctx.body = warte auf neues Promise((lösen, ablehnen) => {
        render.renderToString({url:ctx.url},(err, html) => { // Wenn CSS wirksam werden soll, können Sie die Rückrufmethode nur verwenden, if (err) reject(err);
            lösen (html)
        })
    })
    // const html = await render.renderToString(); // Einen String generieren // console.log(html)
})

// Wenn der Benutzer einen Serverpfad besucht, der nicht existiert, kehre ich zu Ihrer Homepage zurück. Wenn Sie über das Front-End-JS rendern, wird die Komponente entsprechend dem Pfad erneut gerendert. // Solange der Benutzer aktualisiert, sendet er eine Anfrage an den Server. router.get('/(.*)', async (ctx)=>{
    console.log('springen')
    ctx.body = warte auf neues Promise((lösen, ablehnen) => {
        render.renderToString({url:ctx.url},(err, html) => { // Zurück nach dem Rendern über serverseitiges Rendering if (err && err.code == 404) resolve(`nicht gefunden`);
            konsole.log(html)
            lösen (html)
        })
    })
})


// Wenn der Client eine Anfrage sendet, sucht er zuerst im „dist“-Verzeichnis app.use(static(path.resolve(__dirname,'dist'))); // Sequenzproblem app.use(router.routes());

// Stellen Sie sicher, dass Sie Ihre definierte Route verwenden, bevor Sie nach statischen Dateien suchen app.listen(3000);

5.1 Anforderung an localhost:3000/ Übergeben Sie diese gemäß dem Anforderungs-URL-Parameter -》 {url:ctx.url} an serverBundle. Es wird eine Seite mit der vollständigen DOM-Dekonstruktion der Route gemäß dem gepackten .js-Routingsystem auf dem Server gerendert.

Da die Komponente, die / entspricht, Foo ist, zeigt die Seite Foo an.



Der Quellcode der Webseite wird in DOM analysiert und kann für SEO verwendet werden

5.2 Wenn die Anfrage http://localhost:3000/bar ist

Dann lautet die Route /(.*)

renderToString übergibt URL

Werde gehen

Die Standardfunktion der Datei server-entry.js ist ebenfalls ein Vue. Sie enthält die gesamte ursprüngliche Logik des Clients, wird jedoch auf dem Server ausgeführt.

Die URL ist /bar

Entfernen Sie die Bar-Komponente entsprechend der Route /bar

Der Router springt zur Leiste und die Seite wird zur Leistenkomponente.

Das gleichzeitige Ausführen der Funktion asyncData kann den Speicher oder andere Daten neu schreiben

Denken Sie dann daran, context.state = store.state zuzuweisen, um das Statusobjekt des Stores zum Fenster hinzuzufügen.

Fenster.INITIAL_STATE = {"Name":"jiangwen"}

Denken Sie daran, store.js (window. INITIAL_STATE) erneut zu verarbeiten

store.replaceState(window. INITIAL_STATE ) dient zum Übertragen des Serverstatus auf den Client

Nachdem dist/server.html gepackt wurde, wird /client.bundle.js eingeführt, sodass koa-static für die statische Anforderungsverarbeitung erforderlich ist

<!DOCTYPE html>
<html lang="de">
<Kopf>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=Gerätebreite, Anfangsmaßstab=1.0">
    <title>Dokument</title>
</Kopf>
<Text>
    <!--vue-ssr-outlet-->

    <!-- ejs-Vorlage -->
    <script src="/client.bundle.js"></script>
</body>
</html>

6. Bereitstellung

6.1 Führen Sie den Befehl npm run run:all aus

"run:all": "gleichzeitig \"npm run client:build\" \"npm run server:build\""

Es dient zum Verpacken der Client- und Server-Ressourcenpakete einschließlich js, html usw.

Legen Sie dann die gesamte Datei server.js auf den Server.

Führen Sie node server.js aus, um den Node-Server zu starten

6.2 Richten Sie die in server.js angegebenen Dateien server.bundle.js und server.html einfach auf den entsprechenden Serverordner.

Befehl Erklärung

client:dev wird im Spa-Rendering-Modus entwickelt, SSR wird nicht berücksichtigt, client.bundle.js und client.html werden für die normale Spa-Bereitstellung verwendet
run:all Server-Side-Rendering-Modus ist sowohl für den Client als auch für den Server gedacht.

Bei der serverseitigen Verwendung wird client.bundle.js im Browser und server.bundle.js auf dem Server verwendet.

7. Zusammenfassung

1. SSR erfordert zunächst einen Knotenserver und das Vue-Server-Renderer-Paket.

2. Verwenden Sie einfach die normale Vue-Entwicklung und bedenken Sie, dass der Lebenszyklus „beforeMount“ oder „Mounted“ auf der Serverseite nicht verwendet werden kann.

3. Erstellen Sie server.js und setzen Sie koa oder express für die Anforderungsanalyse ein. Übergeben Sie dann serverBundle und Vorlage an

VueServerRenderer.createBundleRenderer-Funktion

Holen Sie sich ein Rendering

4. render.renderToString übergibt die angeforderte Route, z. B. /bar

5. Zu diesem Zeitpunkt wird die Standardfunktion serverBundle (abgeleitet vom Paket server-entry.js) eingegeben, eine Vue-Instanz-App erstellt, die Routing-Vue-Instanz analysiert und dann die Route übersprungen. Zu diesem Zeitpunkt hat sich nur die Vue-Instanz auf der Serverseite geändert und dies wurde noch nicht auf der Seite widergespiegelt.

6. Führen Sie die Funktion asyncData der entsprechenden Komponente aus, die store.state ändern kann. Weisen Sie den Wert dann context.state zu.

7. resolve(app) Zu diesem Zeitpunkt analysiert das Rendern in server.js das DOM entsprechend dem Routing-Status der Vue-Instanz-App zu diesem Zeitpunkt und gibt es an die Seite ctx.body = ...resolve(html) zurück;

8. Zu diesem Zeitpunkt erhält die Seite nach dem normalen Routing-Matching die DOM-Struktur

9. Es wird ein Fenster in HTML angezeigt. INITIAL_STATE = {"name":"zhufeng"} entspricht der Aufzeichnung des Store-Status des Servers.

10. Wenn der Client den Store ausführt, gibt es auf dem Server tatsächlich keinen geänderten Status. Führen Sie store.replaceState(window. INITIAL_STATE ); aus, um den Status auf dem Server zu ersetzen.

11. Die Gesamtsituation ist, dass sowohl der Server als auch der Client über ein JS-Paket verfügen. Führen Sie das JS-Paket im Voraus auf dem Server aus, analysieren Sie dann das DOM und zeigen Sie es an. Der Server ist fertig und die verbleibende Logik wird vom JS des Clients verarbeitet.

Konzeptkarte

Offizielle Website:

  • Die Versionen von vue-server-renderer und vue müssen übereinstimmen.
  • vue-server-renderer hängt von einigen nativen Node.js-Modulen ab und kann daher nur in Node.js verwendet werden. Wir werden in Zukunft möglicherweise einen einfacheren Build bereitstellen, der auf anderen JavaScript-Laufzeitumgebungen ausgeführt werden kann.

Zusammenfassen

Dies ist das Ende dieses Artikels über das serverseitige Rendering von Vue SSR. Weitere verwandte Inhalte zum serverseitigen Rendering von Vue SSR finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Anweisungen zur Verwendung von Vue-Router in Vue (einschließlich der Verwendung in SSR)
  • Implementierung des im Vuecli-Projekt integrierten SSR-Server-Side-Renderings
  • So erstellen Sie ein Vue-SSR-Projekt
  • So verwenden Sie Pre-Rendering anstelle von SSR in Vue
  • Implementierung der Vue SSR Just-in-Time-Kompilierungstechnologie
  • Einige Kenntnisse und detaillierte Konfiguration von VueSSR

<<:  Detaillierter Installationsprozess von mysql5.7.21 unter Win10

>>:  So konfigurieren Sie Nginx's Anti-Hotlinking

Artikel empfehlen

Detaillierte Erklärung des MySQL-Ausführungsplans

Die EXPLAIN-Anweisung liefert Informationen darüb...

Installations-Tutorial für virtuelle VMware-Maschinen unter Ubuntu 18.04

Installationsschritte 1. Erstellen Sie eine virtu...

MySQL 5.7.20 Win64 Installations- und Konfigurationsmethode

mysql-5.7.20-winx64.zipInstallationspaket ohne In...

Tutorial zum Deaktivieren und Aktivieren von Triggern in MySQL [Empfohlen]

Bei der Verwendung von MySQL werden häufig Trigge...

So schreiben Sie den Einführungsinhalt der Infoseite der Website

Alle Websites, ob offiziell, E-Commerce, soziale ...

MySQL-Replikation - ausführliche Erklärung und einfaches Beispiel

MySQL-Replikation - ausführliche Erklärung und ei...

So erkennen Sie mit Apache Tika, ob eine Datei beschädigt ist

Apache Tika ist eine Bibliothek zur Dateityperken...

Eine kurze Analyse des Zeitproblems von MySQL

Der Standardzeittyp (Datum/Uhrzeit und Zeitstempe...

So installieren Sie den MySQL 5.7.28-Binärmodus unter CentOS 7.4

Linux-Systemversion: CentOS7.4 MySQL-Version: 5.7...

So installieren und verwenden Sie Ubuntu Docker

Inhaltsverzeichnis 1. Automatische Installation m...