VUE-TO-NUXT
之前博客是用vue写的,由于SPA应用对SEO不友好,所以决定把项目用nuxt重构。
SPA是什么
SPA是一种网络应用程序(WebApp)模型。在传统的网站中,不同的页面之间的切换都是直接从服务器加载一整个新的页面,而在SPA这个模型中,是通过动态地重写页面的部分与用户交互,而避免了过多的数据交换。
Vue的SPA应用为什么对SEO不友好
如果你的应用程序初始展示 loading,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。
也就是说,当爬虫抓取页面完毕时,你的数据可能还没有渲染到页面,因此就难以保证我们的页面可以被搜索引擎正常收录。
Vue项目由一个<div id="app"></div>
包裹,里面的内容都是由js动态生成,而爬虫是无法抓取js代码,因此SPA应用对SEO不友好。
Nuxtjs是什么
Nuxt是一个vue版本的SSR框架,基于Nuxt,我们可以简单的把Vue的SPA应用转化成SSR单页面应用。当然,Nuxt也可以不做SSR,但我们的目标就是SSR,不然也没必要去修改。
Nuxt解决的问题:
1. 解决SPA中首屏慢的问题。
2. 减少了普通SPA对于SEO的不利影响。
安装
官方提供了一个模版,可通过vue-cli直接安装
/*
用过vue的,一般都有安装vue-cli。
如果没有安装vue-cli,先自行安装再运行以下命令。
*/
$ vue init nuxt-community/starter-template <project name>
生成的目录结构
├── .nuxt
├── assets
├── components
├── layouts
├── middleware
├── node_modules
├── pages
├── plugins
├── static
├── store
├── nuxt.config.js
├── package.json
├── README.md
简单说一下目录结构对应存放的内容
- assets: 存放静态资源,放置需要经过 webpack 打包处理的资源文件,如 scss,图片,字体等。
- components: 组件,页面的一部分。
- layouts: 布局。页面默认布局为 default,它规定了一个页面如何布局页面。
- middleware: 中间件。存放中间件。可以在页面中调用: middleware: 'middlewareName' 。
- node_modules: 安装的第三方库。
- pages: 页面。此目录下的.vue文件会自动生成一个router(看不到)。
(1) index.vue为根页面。
(2) 如果需要二级路由,则创建一个新的文件夹。
(3) 以_开头的.vue文件对应动态路由。
官网直通车 - plugins: 插件。安装的第三方库需要各自创建文件在这里导入。
- static: 静态文件。放置不需要经过 webpack 打包的静态资源。
- store: 状态管理。跟Vuex在vue中的写法有点不同。
- nuxt.config.js: 用于组织Nuxt.js 应用的个性化配置。
Vue项目重构为Nuxt
安装
通过vue-cli生成一个项目
$ vue init nuxt-community/starter-template my-web
$ cd my-web
$ npm install
$ npm run dev
项目启动,默认是3000端口。注意生成的项目已经包含vuex和vue-router。
安装第三方库
$ npm install element-ui highlight.js @nuxtjs/axios --save
这里就跟Vue不同了,在Vue里面我们需要在main.js导入第三方库,然后用Vue.use()。
在Nuxt,需要在plugins目录下创建对应的js文件,然后把需要原先写在main.js里面的内容写到创建的js文件中,如
//在plugins目录下新建element-ui.js
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(Element)
//在plugins目录下新建highlight.js
import Vue from 'vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/googlecode.css'
Vue.directive('highlight',function (el) {
let blocks = el.querySelectorAll('pre code');
blocks.forEach((block)=>{
hljs.highlightBlock(block)
})
})
注意@nuxtjs/axios比较特殊,有兴趣的可以自行搜索看看。
然后在nuxt.config.js中写入
//插件只在浏览器里使用,这种情况下下,你可以用 ssr: false ,使得插件只会在客户端运行,如果element-ui不这样写会报错。
plugins: ['~plugins/highlight.js',{ src: '@/plugins/element-ui.js', ssr: false }]
//这是 @nuxtjs/axios
modules: ['@nuxtjs/axios']
好了,第三方库已经安装并且可以使用了。
图片和common.css
图片放入assets目录,并在assets新建css文件夹,把common.css放入css文件夹,此时还需要通过配置common.css才能生效。
//nuxt.config.js
css: [
'~assets/css/common.css'
]
组件移到components目录
原先Vue项目有对应路由的component移到pages目录
修改根组件文件名为index.vue。二级页面新建文件夹,文件夹名为页面的名字,然后把页面放到文件夹下,修改名字为index.vue。
router-link改为nuxt-link
在layouts中新建布局
新建blog.vue,上下布局
<template>
<div id="blog">
<Introduce>
</Introduce>
<el-row type="flex" class="layout-flex" >
<el-col class="layout-menu-right">
<div class="layout-content">
<div class="layout-content-main">
<nuxt /> //就这里,如果页面是这个布局,页面会插入这里
</div>
</div>
</el-col>
</el-row>
</div>
</template>
给pages中对应页面加上layout
<script>
export default {
layout: 'blog'
}
</script>
以下是遇到的坑
博客导航栏公用一个组件导致的问题
在原先的Vue项目中,导航栏共用一个.vue组件,组件通过query来获取数据。
改为Nuxt项目后,点击导航,URL会改变,页面不会刷新(页面没有任何变化),解决办法是通过watch监听路由。
watch: {
$route() {
//this.$route.query.type
}
}
在created使用localstorage会报错
解决办法是改为在mounted中使用。
没有keep-alive
由于是服务端渲染,所以不支持组件的keep-alive。
store写法不同
原先的Vue项目Store写法:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state:{
},
getters: {
}
mutations: {
},
actions: {
}
})
Nuxt项目自带store目录,其中包含与模块对应的每个文件,并且state的值应该始终是function。
//需将状态导出为函数,将变量和操作作为 store/index.js 中的对象导出
import Vuex from 'vuex'
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
注意store修改需要通过mutation或者action,不然会报错。
网友评论