vue项目改造nuxt 利于seo
一、安装nuxt:
$ npm install --save nuxt (如果 vue-cli 没有安装, 需先通过 npm install -g vue-cli 来安装)
二、创建nuxt项目:
npx create-nuxt-app <项目名> (用yarn:yarn create nuxt-app <项目名>)
创建会有一些选择,可以根据自己项目需要进行选择,因为我的项目用到了elementUi,axios,eslint,所有选了这些,其他2项都默认,这样会自动安装我选好的依赖,如果没选后期自己下依赖也可以
选完后就创建好了一个nuxt项目,目录结构是这样的
├── assets // 资源文件。用于组织未编译的静态资源入LESS、SASS 或 JavaScript
│ └── logo.jpg // 默认logo图片
├── components // 组件。用于自己编写的Vue组件,比如滚动组件,日历组件,分页组件
│ └── AppLogo.vue // 默认logo组件
├── layouts // 布局。页面都需要有一个布局,默认为 default。它规定了一个页面如何布局页面。所有页面都会加载在布局页面中的 <nuxt /> 标签中。
│ └── default.vue // 默认模板页面,类似mvc中的layout
├── middleware // 中间件。存放中间件。可以在页面中调用: middleware: 'middlewareName' 。
├── pages // 页面。一个 vue 文件即为一个页面。
│ └── index.vue // 默认首页面
├── plugins // 用于存放JavaScript插件的地方
│ └── element-ui.js // 上边我们安装的UI框架
├── static // 用于存放静态资源文件,比如图片,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。
├── store // 用于组织应用的Vuex 状态管理。
├── .editorconfig // 开发工具格式配置
├── .eslintrc.js // ESLint的配置文件,用于检查代码格式
├── .gitignore // 配置git不上传的文件
├── nuxt.config.js // 用于组织Nuxt.js应用的个性化配置,比如网站title,已便覆盖默认配置
├── package.json // npm包管理配置文件
└── README.md // 说明文档
这时候可以用npm run dev 启动了,细心的同学会发现没有router文件,确实nuxt不需要自己配置路由文件,pages中的文件名就是你的路由,执行完npm run dev会发现目录会多一个.nuxt 文件,
这是程序启动自动生成的,里面会有一个router.js,就是自动生成的路由,目录结构是这样的
三、开始改造
1、把我们原vue项目下的src,直接拷贝到现在的nuxt根目录下(src和pages一级),把根目录下的components,layouts,page,store全部删掉(为了方便区分,不删也可以),
在nuxt.config.js配置 srcDir:'src/' 重定向默认目录,这样就把以前默认根目录改成src目录,src/pages里面存放的是所有的vue文件,index.vue是默认展示页
把plugins放到我们src目录下(因为plugins要存放js插件),把我们src下的views改为pages
2、把原vue项目的app.vue中的代码拷贝放到layout/defalut.vue中
3、原vue项目的main.js放到plugins下,然后在nuxt.config.js中引入,这是我用到的所有的js插件,如果你还有其他引用也要放到这里引入
4、如果原项目mian.js里面有引入css文件一定要提出来,把全局引入的css都统一放到src/style目录下,然后在nuxt.config.js中引入
5、配置生产模式和开发模式请求不同地址
在根目录创建env.js 内容
module.exports = { dev: { MODE: 'development', ENV_API: 'https://base.exploring.cn/test-jzm-server' //测试服务器地址 }, pro: { MODE: 'production', ENV_API: 'https://base.exploring.cn/test-jzm-server' // 正式服务器地址 } }
在nuxt.config.js 中引入env.js 然后配置env
const env = require('./env’) module.exports = { env: { BASE_API: env[process.env.MODE].ENV_API }
这样配置完就axios请求生产和开发地址就配置好了,这个时候通过npm run dev 就可以看到你的项目了(如果你原vue 项目的路由和文件名不同名的时候就要修改一下有跳转路由的地方就可以)
6、如果项目用引入svg文件的还需要在nuxt.config.js中配置
build: { const svgRule = config.module.rules.find(rule => rule.test.test(".svg")); svgRule.exclude = [path.resolve(__dirname, "./src/assets/svg")]; // Includes /assets/icons/svg for svg-sprite-loader config.module.rules.push({ test: /\.svg$/, include: [path.resolve(__dirname, "./src/assets/svg")], loader: "svg-sprite-loader", options: { symbolId: "icon-[name]" } }); return configs }
这个时候项目便可以正常运行起来了,你会发现跟我们原来vue项目还是差不都,打包的时候并没有把动态数据静态化
这个时候就需要asyncData做服务端提前渲染
7、asyncData渲染组件(仅限于pages下的页面,components下的组件不可以用)之前异步获取数据
async asyncData() { const getBannersres = await getBanners() const bannerLists = getBannersres.data.items const getHotListres = await getList({isHot:true,sort:'hot_order_no',order:'asc',limit:5}) var hotLists = getHotListres.data.data.items const hotTotal = getHotListres.data.data.total const getRouterListres = await getList({page: 1, limit: 5, menuId: 2, sort: 'order_no', order: 'asc'}) const routerLists = getRouterListres.data.data.items const getThemeListres = await getList({page: 1, limit: 5, themeId: -1, sort: 'order_no', order: 'asc'}) const themeLists = getThemeListres.data.data.items const getAddressMenures = await getAddressMenu() const addressLists = getAddressMenures.data.data.items return { bannerLists, hotLists, hotTotal, routerLists, themeLists, addressLists } }
asyncData 方法是在组件初始化之前调用的,所以this关键字不能用 ,
我这里的getBanners是提前引入的接口请求,然后拿到的值通过return 返回,return返回的变量都要和页面要用的变量名(data定义过)一致,这样就可以在页面加之前把动态数据拿过来,并进行渲染了,这时候右键查看源码就可以看到动态数据了
8、components组件想提前加载数据可以用vueX
比如菜单这样的组件是需要提前加载数据利于网页爬虫去爬这些链接,asyncData又不能在这里用,这个时候就可以用vuex了
你的请求要写在actions 中的nuxtServerInit里,这里可以参考https://zh.nuxtjs.org/guide/vuex-store,写的很详细就不多阐述了
不需要安装vuex,因为nuxtjs已经提供了
import { getMenus } from '@/api' export const state=()=>({ menus: [] }) export const mutations= { setMeuns (state, value) { state.menus = value } } export const actions= { async nuxtServerInit({ commit}, { req }) { const getMenusres = await getMenus() let tempMenus = [],menus = getMenusres.data.data.items; menus.forEach(item => { if (!item.parentid) { tempMenus.push(item) } }) commit("setMeuns", tempMenus); }
vue页面使用直接写在computed里即可
computed:{ menus(){ console.log(this.$store.state.menus) return this.$store.state.menus } },
8、部署发布
如果是多环境打包的话要在package.json中配置一下,我多配置了一个测试环境,如果你有更多可以多配,打包时候可以npm run generate:xx (xx:是你配置的环境名,如果生产环境可以不加:xx)
Nuxt.js 提供了两种发布部署应用的方式:服务端渲染应用部署 和 静态应用部署(可以参考https://zh.nuxtjs.org/guide/commands)
我使用的是静态应用部署,因为这个同时具有预渲染所有页面的优势,并具有较高的SEO优化和页面加载能力
打包完会在根目录生成一个dist 文件,里面是生成的静态目录和文件
9、配置mate标签
在nuxt.config.js中配置titile 和mate
head: { title: ‘your title', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { name: 'keywords', content: ‘content'}, { hid: 'description', name: 'description', content: 'content' }, ], link: [ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } ] },
这样基本配置就改造完毕,我们是门户网站没有使用动态路由,如果你的是动态路由请参考其他动态路由配置
nuxt.js 是项目改造现学现用的,理解不透彻,有写的不对的地方欢迎留言指正。