
About server rendering: The Vue official website introduces that there are requirements for the Vue version as well as for the server, which needs to support the nodejs environment.
Trade offs for using SSR:
Advantages:
Deficiency: (Problems encountered in development)
1.One set of code and two sets of execution environments will cause various problems. For example, the server does not have window and document objects, and the processing method is to add judgment.
If it is the client, it will execute:
<pre class="brush:py;"> If (process.browser) { Console.log (window) } </pre>
Refer to the npm package. For those with dom operations, such as wowjs, you cannot use import instead:
<pre class="brush:py;"> If (process.browser) { Var {WOW} = require ('wowjs') Require ('wowjs/css/libs/animate.css') } </pre>
2.Nuxt asyncData method, which gets the data before initializing the page, but only if called by the page component:
<pre class="brush:py;"> / / load multiple APIs concurrently: Async asyncData ({app, query}) { Let [resA, resB, resC] = await Promise.all ([ App.$axios.get ('/ api/a') App.$axios.get ('/ api/b') App.$axios.get ('/ api/c') ])
Return { DataA: resA.data DataB: resB.data DataC: resC.data } } </pre>
Get the parameters in asyncData:
1.Obtain dynamic routing parameters, such as:
<pre class="brush:py;"> / list/:id' = = >'/ list/123 </pre>
Receive:
<pre class="brush:py;"> Async asyncData ({app, query}) { Console.log (app.context.params.id) / / 123 } </pre>
2.Get url? Get parameters, such as:
<pre class="brush:py;"> / list?id=123 </pre>
Receive:
<pre class="brush:py;"> Async asyncData ({app, query}) { Console.log (query.id) / / 123 } </pre>
3.If you use the v-if syntax, you will probably encounter this error when deploying online: Error while initializing app DOMException:
Error while initializing app DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
at Object.We [as appendChild]
According to the 1552 prompt of issue on github nuxt, v-if should be changed to v-show syntax.
At Nuxt When js performs generate static packaging, dynamic routing will be ignored.
<pre class="brush:py;"> -| pages/ ---| index.vue ---| users/ -----| _ id.vue </pre>
Dynamic routing is required to be a static page. You need to specify the values of dynamic routing parameters and configure them in the routes array.
<pre class="brush:py;"> / / nuxt.config.js Module.exports = { Generate: { Routes: [ '/ users/1' '/ users/2' '/ users/3' ] } } </pre>
Run the package, and you can see the packaged page. But what if the value of the route dynamic parameter is dynamic rather than fixed? Use a function that returns the Promise object type, Use a callback is a function of callback (err, params).
<pre class="brush:py;"> / / nuxt.config.js Import axios from 'axios'
Export default { Generate: { Routes: function () { Return axios.get ('https://my-api/users') .then ((res) = > { Return res.data.map ((user) = > { Return { Route:'/ users/' + user.id Payload: user } }) }) } } } </pre>
The payload that we can now access from / users/_id.vue is as follows:
<pre class="brush:py;"> Async asyncData ({params, error, payload}) { If (payload) return {user: payload} Else return {user: await backend.fetchUser (params.id)} } </pre>
If you have a lot of dynamic routing parameters, such as commodity details, there may be tens of millions of them. You need an interface to return all the id, then traverse the id when packaging, and package it locally. If a product is modified or removed from the shelves, it has to be repackaged, and it is also very slow and unrealistic to pack in large quantities.
Advantages:
Deficiency: It is not applicable if there are many dynamic routing parameters.
If you only use SEO to improve a few marketing pages (for example, /, /about, /contact, etc.), then you may need to pre-render. Instead of using a web server to dynamically compile HTML in real time, use pre-rendering At build time (build time), you simply generate a static HTML file for a specific route. The advantage is that it is easier to set up pre-rendering and can use your front end as a completely static site.
<pre class="brush:py;"> $cnpm install prerender-spa-plugin-save </pre>
Vue cli 3 vue.config.js configuration:
<pre class="brush:py;"> Const PrerenderSPAPlugin = require ('prerender-spa-plugin') Const Renderer = PrerenderSPAPlugin.PuppeteerRenderer Const path = require ('path') Module.exports = { ConfigureWebpack: config = > { If (process.env.NODE_ENV! = = 'production') return Return { Plugins: [ New PrerenderSPAPlugin ({ // the path to the generated file can also be the same as that packaged by webpakc. // the following sentence is very important! // there can only be one level of this directory. If the directory hierarchy is greater than one level, there will be no error when it is generated, and it will only be stuck during pre-rendering. StaticDir: path.join (_ _ dirname,'dist') // corresponding to your own routing file, for example, if a has parameters, it needs to be written as / a/param1. Routes: ['/','/ product','/about'] // this is very important. If this section is not configured, it will not be precompiled. Renderer: new Renderer ({ Inject: { Foo: 'bar' } Headless: false // document.dispatchEvent (new Event ('render-event')) in main.js, and the event names of both should correspond to each other. RenderAfterDocumentEvent: 'render-event' }) }) ] } } } </pre>
Add in main.js:
<pre class="brush:py;"> New Vue ({ Router Render: h = > h (App) Mounted () { Document.dispatchEvent (new Event ('render-event')) } }). $mount ('# app') </pre>
Note: mode: "history" must be set in router. When you package it, you can see the file. Package it out of the folder / index.html. For example: about = > about/index.html, which contains html content.
Advantages:
Deficiency:
Phantomjs is a headless browser based on webkit kernel, that is, there is no UI interface, that is, it is a browser. It's just that the artificial operations such as clicking and turning pages need to be designed and implemented. Although "PhantomJS announced the termination of development", it has satisfied the SEO processing of Vue.
This solution is actually a bypass mechanism, and the principle is to determine whether the access source UA is crawler access through Nginx configuration. If so, the crawler request from the search engine is forwarded to a node server, then parse the complete HTML through PhantomJS and return it to the crawler.
Specific code is stamped here: vue-seo-phantomjs.
To install global phantomjs, local express, test:
<pre class="brush:py;"> $phantomjs spider.js 'https://www.baidu.com' </pre>
If you see a push of html on the command line, congratulations, you have conquered PhantomJS. After startup, or use postman to increase the value of User-Agent to Baiduspider in the request header, the effect is the same.
Deploy online: Node, pm2, phantomjs and nginx related configurations should be installed online:
<pre class="brush:py;"> Upstream spider_server { Server localhost:3000 }
Server { Listen 80 Server_name example.com
Location / { Proxy_set_header Host $host:$proxy_port Proxy_set_header X-Real-IP $remote_addr Proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
If ($http_user_agent ~ * "Baiduspider | twitterbot | facebookexternalhit | rogerbot | linkedinbot | embedly | quora link preview | outbrain | pinterest | slackbot | vkShare | W3C_Validator | bingbot | Sosospider | Sogou Pic Spider | Googlebot | 360Spider") { Proxy_pass http://spider_server; } } } </pre>
Advantages:
Deficiency:
If you build a large website, such as a mall, don't hesitate to use the SSR server to render directly. Of course, there are also corresponding problems. The community is mature and the English is better, All problems can be solved easily. If it's just a personal blog or a company official website, the other three can be used. If you want to optimize the SEO of projects that have been developed with SPA and support node servers, please use Phantomjs.