如果我们需要对现有的vue项目进行ssr改造,使用nuxt.js是一个不错的选择。这里用作例子的“现有项目”是一个“高仿”饿了么外卖APP的spa。不过我没有把全部功能开发出来(全部做出来就不得了了),只是做出几个基本界面意思意思
下面就以这个demo为小白鼠进行ssr改造
准备
现有目录
很明显,这是使用vue-cli搭建的项目
其中prod.server.js是build之后的启动文件
dataa.json文件是模拟数据,在build/dev-server.js中会用到它
安装与配置
安装nuxt
npm install --save-dev nuxt
新建nuxt文件夹
我们需要在根目录下建立一个nuxt文件夹,该文件夹的内部组织按照nuxt本身的应用目录架构进行组织(参考)
注意,在static目录下有一个logo.png,它将作为项目图标,在nuxt.config.js中这张图片的地址直接写成/logo.png。下一节会对nuxt文件夹的组织进行详细说明。
新建并设置nuxt.config.js
当然,我们也需要在根目录下创建nuxt.config.js文件用于组织Nuxt.js 应用的个性化配置,在这个项目中,需要进行设置的点有:
源码目录路径
head中的meta以及link(主要是图标)
全局的css样式
项目中需要使用图片和字体文件,虽然nuxt默认对其进行配置,但我们需要重新定义部分内容(项目中是扩大limit)
项目中使用了sass,需要对其进行配置
所以,nuxt.config.js的代码如下
module.exports = { // 设置nuxt源码目录路径 srcDir: "nuxt/", head: { title: "sell-nuxt", meta: [ { charset: "utf-8" }, { name: "viewport", content: "width=device-width, initial-scale=1,user-scalable=no,maximum-scale=1.0,minimum-scale=1.0" } ], link: [ { rel: "shortcut icon", type: "image/png", // 注意图片的路径直接指向static下的logo.png href: "/logo.png" } ] }, css: [ "~assets/reset.css" ], build: { vendor: ['axios'], loaders: [ { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'img/[name].[hash:7].[ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'fonts/[name].[hash:7].[ext]' } }, { test: /\.scss$/, loader: "vue-style-loader!css-loader!sass-loader" } ] } }
配置package.json
package.json是npm的配置文件,现在,我们需要对script选项进行配置
"scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate", "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", "precommit": "npm run lint" }
可以参考nuxt的命令列表
改造后的目录
其中有个nuxt.api.js,这个文件是为完成ssr改造后的项目提供api接口的,使用koa,运行在3001端口
nuxt文件夹组织
因为我们已经把项目代码开发出来了,所以nuxt文件夹里面的大部分代码可以直接从已有代码中拷贝
layouts
布局目录 layouts 用于组织应用的布局组件,nuxt可通过添加 layouts/default.vue 文件来扩展应用的默认布局,在layouts下新建default.vue
<template> <div> <v-header v-bind:seller="seller"></v-header> <v-tab></v-tab> <nuxt/> </div> </template> <script> import axios from 'axios'; // 引入组件 import header from "~/components/header/header.vue"; import tab from "~/components/tab/tab.vue"; export default { data:function(){ return { seller:{} } }, created:function(){ axios.get("http://localhost:3001/seller").then(res=>{ console.log(res.data); this.seller = res.data.data; }); }, components:{ "v-header":header, "v-tab":tab } } </script> <style lang="scss"> </style>
<nuxt/> 组件用于显示页面的主体内容,即“商品”、“评论”、“商家”这几个部分
pages
nuxt依据 pages 目录结构自动生成 vue-router 模块的路由配置,这无疑是非常方便的
不难看出goods、patings、seller分别对应“商品”、“评论”、“商家”
这样子设置,则nuxt自动生成的路由配置如下