脚本宝典收集整理的这篇文章主要介绍了

Nuxt — 也来说说vue服务端渲染

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。
<p><code></p> <h2 id="articleHeader0">Nuxt</h2> <p>随着现在vue和react的流行,许多网站都做成了SPA,确实提升了用户体验,但SPA也有两个弱点,就是SEO和首屏渲染速度。为了解决单页应用的痛点,基于vue和react的服务端渲染应运而生。由于公司的框架采用的是vue,所以就简单的研究了一下基于vue的服务端渲染框架——NUXT。在vue的官网有关于服务端渲染的详细介绍,而NUXT集成了利用<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>开发服务端渲染的应用所需要的各种配置,也集成了<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>2、vue-router、vuex、vux-meta(管理页面meta信息的),利用官方的脚手架,基本上是傻瓜式操作,不用写路由配置,不用写webpcak配置就可以跑起来一个基于服务端渲染的SPA。</p> <h2 id="articleHeader1">Nuxt特性</h2> <p>NUXT的特性包括:</p> <ul> <li>基于 <a href="http://www.js-code.com/tag/vue" title="浏览关于“Vue”的文章" target="_blank" class="tag_link">Vue</a>.js</li> <li>自动代码分层</li> <li>服务端渲染</li> <li>强大的路由功能,支持异步数据</li> <li>静态文件服务</li> <li>ES6/ES7 语法支持</li> <li>打包和压缩 JS 和 <a href="http://www.js-code.com/tag/css" title="CSS" target="_blank">CSS</a></li> <li><a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>头部标签管理</li> <li>本地开发支持热加载</li> <li>集成ESLint</li> <li>列表项目</li> <li>支持各种样式预处理器: SASS、LESS、 Stylus等等</li> </ul> <h2 id="articleHeader2">Nuxt目录结构</h2> <p>通过<code>vue init nuxt-community/starter-template &lt;project-name&gt;</code>生成的文件目录结构如下:</p> <p><span class="img-wrap"><img data-src="/img/bVbcsW5?w=182&amp;h=333" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="clipboard.png" title="clipboard.png" style="cursor: pointer;"></span></p> <p>其中有一些目录(layouts、pages、static、store、nuxt.config.js、package.json)是<code>Nuxt</code>保留的,不可以更改,需要注意一下。</p> <h2 id="articleHeader3">Nuxt路由</h2> <p><code>Nuxt</code>中的一大特点就是路由无需手动配置,会根据pages下的文件路径自动生成一套路由。如果路由中需要带参数,只需将pages下的文件已下划线_作为前缀即可。例如pages下的目录结构如下:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="pages/ --| user/ -----| index.vue -----| one.vue -----| _id.vue --| index.vue" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs sql"><code>pages/ <span class="hljs-comment">--| user/</span> <span class="hljs-comment">-----| index.vue</span> <span class="hljs-comment">-----| one.vue</span> <span class="hljs-comment">-----| _id.vue</span> <span class="hljs-comment">--| index.vue</span></code></pre> <p><code>Nuxt</code>自动生成的路由配置为:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'user', path: '/user', component: 'pages/user/index.vue' }, { name: 'user-one', path: '/user/one', component: 'pages/user/one.vue' }, { name: 'users-id', path: '/users/:id?', component: 'pages/users/_id.vue' }, ] }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs css"><code><span class="hljs-selector-tag">router</span>: { <span class="hljs-attribute">routes</span>: [ { name: <span class="hljs-string">'index'</span>, path: <span class="hljs-string">'/'</span>, component: <span class="hljs-string">'pages/index.vue'</span> }, { <span class="hljs-attribute">name</span>: <span class="hljs-string">'user'</span>, path: <span class="hljs-string">'/user'</span>, component: <span class="hljs-string">'pages/user/index.vue'</span> }, { <span class="hljs-attribute">name</span>: <span class="hljs-string">'user-one'</span>, path: <span class="hljs-string">'/user/one'</span>, component: <span class="hljs-string">'pages/user/one.vue'</span> }, { <span class="hljs-attribute">name</span>: <span class="hljs-string">'users-id'</span>, path: <span class="hljs-string">'/users/:id?'</span>, component: <span class="hljs-string">'pages/users/_id.vue'</span> }, ] }</code></pre> <p>而在vue文件中可以针对路由的参数进行校验,例如在<code>pages/users/_id.vue</code>文件中</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="export default { validate ({ params }) { // Must be a number return /^d+$/.test(params.id) } }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code><span class="hljs-keyword"><a href="http://www.js-code.com/tag/export" title="浏览关于“export”的文章" target="_blank" class="tag_link">export</a></span> <span class="hljs-keyword">default</span> { validate ({ params }) { <span class="hljs-comment">// Must be a number</span> <span class="hljs-keyword">return</span> <span class="hljs-regexp">/^d+$/</span>.test(params.id) } }</code></pre> <p>如果校验方法返回的值不为 <code>true</code>, <code>Nuxt</code> 将自动加载显示 404 错误页面。而这个错误页面需要写在指定的位置,也就是layout中error页面。接下来就来介绍有关视图相关的东西。</p> <h2 id="articleHeader4">Nuxt视图</h2> <p>可以在layouts目录下创建自定义的布局,可以通过更改 <code>layouts/default.vue</code> 文件来扩展应用的默认布局。需要在布局文件中添加 &lt;nuxt/&gt; 组件用于显示页面的主体内容,感觉跟vue中的slot方法类似。例如在默认布局中增加header和footer,这样每个页面都会加上header和footer。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<template></p> <div> <header>VUE SRR DEMO</header> <p> <nuxt></nuxt></p> <footer>COPYRIGHT LXY</footer> </p></div> <p></template>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name"><a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a></span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>VUE SRR DEMO<span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">nuxt</span>/&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>COPYRIGHT LXY<span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span></code></pre> <p>而上面说到的error页面,可以通过在layouts下增加error.vue文件来修改默认的错误页面。该页面可以接受一个error参数。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<template></p> <div class=&quot;container&quot;> <h1 v-if=&quot;error.statusCode === 404&quot;>页面不存在</h1> <h1 v-else>应用发生错误异常</h1> <p class=&quot;goback&quot;> <nuxt-link to=&quot;/&quot;>返回首页</nuxt-link> </p> </p></div> <p></template></p> <p><script> <a href="http://www.js-code.com/tag/export" title="export" target="_blank">export</a> default { props: ['error'], layout: 'self-aside' } </script>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"error.statusCode === 404"</span>&gt;</span>页面不存在<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">v-else</span>&gt;</span>应用发生错误异常<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"goback"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">nuxt-link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/"</span>&gt;</span>返回首页<span class="hljs-tag">&lt;/<span class="hljs-name">nuxt-link</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> { <span class="hljs-attr">props</span>: [<span class="hljs-string">'error'</span>], <span class="hljs-attr">layout</span>: <span class="hljs-string">'self-aside'</span> } </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre> <p>也可以给某个页面指定特定的模板,做到个性化布局。例如在上面的error页面中,我指定了一个<code>self-aside</code>的模板</p> <p>以上所说的都是有关布局和路由相关的东西,而还没有讲到有关服务端渲染的知识,究竟 <code>Nuxt</code> 是如何做到SSR的呢,关键人物要出场了。</p> <h2 id="articleHeader5">Nuxt asyncData 方法</h2> <p><code>Nuxt</code> 扩展了 <code>Vue.js</code>,增加了一个叫 <code>asyncData</code> 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。这个函数可了不得了,有了它,我们可以先从服务员拿到数据,在服务端解析好,拼成<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>字符串,返回给浏览器。</p> <p><code>asyncData</code>方法会在组件每次加载之前被调用,它可以在服务端或路由更新之前被调用。 可以利用 <code>asyncData</code>方法来获取数据,<code>Nuxt</code> 会将 <code>asyncData</code> 返回的数据融合组件 <code>data</code> 方法返回的数据一并返回给当前组件。这个方法只能用在页面组件中,在<code>componets</code>下在公共组件是不能调用该方法的,<code>Nuxt</code> 不会扩展增强该目录下 <code>Vue</code> 组件。</p> <div class="google-auto-placed ap_container" style="text-align: center; width: 100%; height: auto; clear: none;"><ins data-ad-format="auto" class="adsbygoogle adsbygoogle-noablate" data-ad-client="ca-pub-6330872677300335" data-adsbygoogle-status="done" style="display: block; margin: auto; background-color: transparent;"><ins id="aswift_4_expand" style="display: inline-table; border: none; height: 0px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 697px; background-color: transparent;"><ins id="aswift_4_anchor" style="display: block; border: none; height: 0px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 697px; background-color: transparent; overflow: hidden; opacity: 0;"><iframe width="697" height="175" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){setTimeout(h,0)}else if(h.match){try{h=s.upd(h,i)}catch(e){}w.location.replace(h)}}" id="aswift_4" name="aswift_4" style="left:0;position:absolute;top:0;border:0px;width:697px;height:175px;"></iframe></ins></ins></ins></div> <p>因为 <code>asyncData</code> 方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 <code><a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a></code> 来引用组件的实例对象。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="async asyncData ({ params, error }) { const { data } = await axios.get('https://jsonplaceholder.typicode.com/users') return { users: data.slice(0,5) } }," title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs cs"><code><span class="hljs-function"><span class="hljs-keyword">async</span> <span class="hljs-title">asyncData</span> (<span class="hljs-params">{ <span class="hljs-keyword">params</span>, error }</span>)</span> { <span class="hljs-keyword"><a href="http://www.js-code.com/tag/const" title="浏览关于“const”的文章" target="_blank" class="tag_link">const</a></span> { data } = <span class="hljs-keyword">await</span> ax<a href="http://www.js-code.com/tag/ios" title="浏览关于“ios”的文章" target="_blank" class="tag_link">ios</a>.<span class="hljs-keyword">get</span>(<span class="hljs-string">'https://jsonplaceholder.typicode.com/users'</span>) <span class="hljs-keyword">return</span> { users: data.<a href="http://www.js-code.com/tag/slice" title="浏览关于“slice”的文章" target="_blank" class="tag_link">slice</a>(<span class="hljs-number">0</span>,<span class="hljs-number">5</span>) } },</code></pre> <p>上面demo中asyncData返回的数据赋值给了users,这样我就可以在页面中像使用data里的数据一样去使用users,例如我在template下循环出users</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" <ul> <li v-for=&quot;item in users&quot; :key=&quot;item.name&quot;>{{item.name}}</li> </ul> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"item in users"</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">"item.name"</span>&gt;</span>{{item.name}}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></code></pre> <p>我现在去查看源代码,发现页面中li中的数据已经渲染过来了,也就是达到了服务端渲染。<br /><span class="img-wrap"><img data-src="/img/bVbcs3b?w=2754&amp;h=542" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="图片描述" title="图片描述" style="cursor: pointer;"></span></p> <p>附一张Nuxt渲染的流程图:<br /><span class="img-wrap"><img data-src="/img/bVbcs3A?w=596&amp;h=782" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="图片描述" title="图片描述" style="cursor: pointer;"></span></p> <p>项目源码地址:<a href="https://github.com/CuteSunLee/nuxt" rel="nofollow noreferrer" target="_blank">https://github.com/CuteSunLee...</a></p> <h2 id="articleHeader6">总结</h2> <p>整体感觉Nuxt还是很好上手的,利用脚手架,看看官方文档,写写demo,大致就能了解整个流程。但其中的具体实现细节,还需要去认真看看 <a href="https://ssr.vuejs.org/zh/" rel="nofollow noreferrer" target="_blank">https://ssr.vuejs.org/zh/</a></p> <p></code></p>

总结

以上是脚本宝典为你收集整理的

Nuxt — 也来说说vue服务端渲染

全部内容,希望文章能够帮你解决

Nuxt — 也来说说vue服务端渲染

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过