Maison  >  Article  >  interface Web  >  Fonction de rendu côté serveur Vue.js et ASP.NET Core

Fonction de rendu côté serveur Vue.js et ASP.NET Core

小云云
小云云original
2018-01-18 13:54:092632parcourir

Utilisez Vue.js sur le front-end, le rendu côté serveur Vue n'était pas pris en charge jusqu'à la deuxième version. Dans cet exemple, je souhaite montrer comment intégrer la fonctionnalité de rendu côté serveur Vue.js avec ASP.NET Core. Côté serveur, nous avons utilisé le package Microsoft.AspNetCore.SpaServices, qui fournit l'API ASP.NET Core afin que nous puissions utiliser des informations contextuelles pour appeler le code JavaScript hébergé par Node.js et injecter la chaîne HTML résultante dans la page rendue.

Dans cet exemple, l'application affichera une liste de messages et le serveur n'affichera que les deux derniers messages (triés par date). Les messages restants peuvent être téléchargés depuis le serveur en cliquant sur le bouton « Obtenir un message ».

La structure du projet est la suivante :


.
├── VuejsSSRSample
| ├── Properties
| ├── References
| ├── wwwroot
| └── Dependencies
├── Controllers
| └── HomeController.cs
├── Models
| ├── ClientState.cs
| ├── FakeMessageStore.cs
| └── Message.cs
├── Views
| ├── Home
| | └── Index.cshtml
| └── _ViewImports.cshtml
├── VueApp
| ├── components
| | ├── App.vue
| | └── Message.vue
| ├── vuex
| | ├── actions.js
| | └── store.js
| ├── app.js
| ├── client.js
| ├── renderOnServer.js
| └── server.js
├── .babelrc
├── appsettings.json
├── Dockerfile
├── packages.json
├── Program.cs
├── project.json
├── Startup.cs
├── web.config
├── webpack.client.config.js
└── webpack.server.config.js

Comme vous pouvez le voir, l'application Vue se trouve sous le dossier VueApp et comporte deux composants. , Un simple magasin Vuex contenant une mutation et une action et quelques autres fichiers dont nous parlerons ensuite : app.js, client.js, renderOnServer.js, server.js.

Implémentation du rendu côté serveur Vue.js

Pour utiliser côté serveur Pour le rendu, nous devons créer deux bundles différents à partir de l'application Vue : un pour le côté serveur (exécuté par Node.js) et un autre pour l'application hybride qui s'exécutera dans le navigateur et sur le client.

app.js

Amorce l'instance Vue dans ce module. Il est utilisé par les deux bundles.


import Vue from 'vue';
import App from './components/App.vue';
import store from './vuex/store.js';
const app = new Vue({
 store,
 ...App
});
export { app, store };

server.js

Le point d'entrée de ce bundle de serveur exporte une fonction, qui a un attribut de contexte, peut être utilisé pour transmettre toutes les données de l'appel de rendu.

client.js

Le point d'entrée du bundle client, qui remplace le store par un objet Javascript global nommé INITIAL_STATE (qui sera créé par le pré-rendu module) état actuel et monte l'application sur l'élément spécifié (.my-app).


import { app, store } from './app';
store.replaceState(__INITIAL_STATE__);
app.$mount('.my-app');

Configuration du Webpack

Afin de créer le bundle, nous devons ajouter deux Fichiers de configuration Webpack (un pour le serveur et un pour la version client) N'oubliez pas d'installer Webpack si vous ne l'avez pas déjà fait : npm install -g webpack.


webpack.server.config.js
const path = require('path');
module.exports = {
 target: 'node',
 entry: path.join(__dirname, 'VueApp/server.js'),
 output: {
 libraryTarget: 'commonjs2',
 path: path.join(__dirname, 'wwwroot/dist'),
 filename: 'bundle.server.js',
 },
 module: {
 loaders: [
  {
  test: /\.vue$/,
  loader: 'vue',
  },
  {
  test: /\.js$/,
  loader: 'babel',
  include: __dirname,
  exclude: /node_modules/
  },
  {
  test: /\.json?$/,
  loader: 'json'
  }
 ]
 },
};
webpack.client.config.js
const path = require('path');
module.exports = {
 entry: path.join(__dirname, 'VueApp/client.js'),
 output: {
 path: path.join(__dirname, 'wwwroot/dist'),
 filename: 'bundle.client.js',
 },
 module: {
 loaders: [
  {
  test: /\.vue$/,
  loader: 'vue',
  },
  {
  test: /\.js$/,
  loader: 'babel',
  include: __dirname,
  exclude: /node_modules/
  },
 ]
 },
};

Exécutez webpack --config webpack.server.config.js Si l'opération réussit, vous pouvez trouver le service dans /wwwroot/dist/bundle. bundle de terminaux server.js. Pour obtenir le bundle client, veuillez exécuter webpack --config webpack.client.config.js. Le résultat correspondant se trouve dans /wwwroot/dist/bundle.client.js.

Implémentation du rendu groupé

Ce module sera exécuté par ASP.NET Core, qui est responsable de :

Le rendu celui que nous avons créé avant Le bundle serveur

définit **window.__ INITIAL_STATE__** sur l'objet envoyé depuis le serveur


process.env.VUE_ENV = 'server';
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, '../wwwroot/dist/bundle.server.js')
const code = fs.readFileSync(filePath, 'utf8');
const bundleRenderer = require('vue-server-renderer').createBundleRenderer(code)
module.exports = function (params) {
 return new Promise(function (resolve, reject) {
 bundleRenderer.renderToString(params.data, (err, resultHtml) => { // params.data is the store's initial state. Sent by the asp-prerender-data attribute
  if (err) {
  reject(err.message);
  }
  resolve({
  html: resultHtml,
  globals: {
   __INITIAL_STATE__: params.data // window.__INITIAL_STATE__ will be the initial state of the Vuex store
  }
  });
 });
 });
};

Implémentation de la partie ASP.NET Core

Comme mentionné précédemment, nous avons utilisé le package Microsoft.AspNetCore.SpaServices, qui fournit des TagHelpers pour appeler facilement le Javascript hébergé par Node.js ( dans les coulisses, SpaServices utilise le package Microsoft.AspNetCore.NodeServices pour exécuter Javascript).

Views/_ViewImports.cshtml

Pour utiliser les TagHelpers de SpaServices, nous devons les ajouter à _ViewImports.


@addTagHelper "*, Microsoft.AspNetCore.SpaServices"
Home/Index
public IActionResult Index()
{
 var initialMessages = FakeMessageStore.FakeMessages.OrderByDescending(m => m.Date).Take(2);
 var initialValues = new ClientState() {
 Messages = initialMessages,
 LastFetchedMessageDate = initialMessages.Last().Date
 };
 return View(initialValues);
}

Il récupère les deux derniers messages (triés par date dans l'ordre inverse) du MessageStore (certaines données statiques uniquement à des fins de démonstration) et crée un objet ClientState qui sera utilisé comme état initial du magasin Vuex.

État par défaut du magasin Vuex :


const store = new Vuex.Store({
 state: { messages: [], lastFetchedMessageDate: -1 },
 // ...
});

ClientState 类:

public class ClientState
{
 [JsonProperty(PropertyName = "messages")]
 public IEnumerable<Message> Messages { get; set; }

 [JsonProperty(PropertyName = "lastFetchedMessageDate")]
 public DateTime LastFetchedMessageDate { get; set; }
}

Vue de l'index

Enfin , nous avons l'état initial (du serveur) et l'application Vue, il n'y a donc qu'une seule étape : utiliser asp-prerender-module et asp-prerender-data TagHelper pour restituer les valeurs initiales de l'application Vue dans la vue.


@model VuejsSSRSample.Models.ClientState
<!-- ... -->
<body>
 <p class="my-app" asp-prerender-module="VueApp/renderOnServer" asp-prerender-data="Model"></p>
 <script src="~/dist/bundle.client.js" asp-append-version="true"></script>
</body>
<!-- ... -->

asp-prerender-module L'attribut est utilisé pour spécifier le module à rendre (dans notre cas VueApp/renderOnServer ). Nous pouvons utiliser l'attribut asp-prerender-data pour spécifier un objet qui sera sérialisé et envoyé à la fonction par défaut du module en tant que paramètre.

Vous pouvez télécharger l'exemple de code original à partir de l'adresse suivante :

http://github.com/mgyongyosi/VuejsSSRSample

Recommandations associées :

Explication détaillée des exemples de rendu côté serveur React

Solution de rendu côté serveur de page DIY_html/css_WEB-ITnose

Pratique de rendu côté serveur Nuxt Vue.js

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn