用prerender-spa-plugin(预渲染) + vue-meta-info(设置页面meta信息)对动态页面SEO 问题很多,当页面数据切换时,meta信息无法及时修改。。所以改用服务器渲染方式。。
关于nuxt的详细信息 --->官网: https://zh.nuxtjs.org/guide
一、安装
npx create-nuxt-app
二、目录结构
三、路由
Nuxt.js路由是依据 pages
目录结构自动生成。要在页面之间使用路由,建议使用<nuxt-link>
标签。
<nuxt-link to="/">首页</nuxt-link>
1.基础路由
2.动态路由:带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
3.嵌套路由:需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
4.全局路由过渡动效:Nuxt.js 默认使用的过渡效果名称为 page。
在 assets/
目录下创建共用的 CSS 文件:page-slide.css,
.page-enter {
transform: translateX(100px);
}
.page-leave,
.page-enter-to {
transform: translateX(0px);
}
.page-leave-to {
transform: translateX(-200px);
}
.page-enter-active,
.page-leave-active {
transition: opacity .5s, transform .5s;
}
.page-enter,
.page-leave-active {
opacity: 0;
}
在nuxt.config.js中插入全局css,需要其他过渡配置需要在transition中配置
css: [
'assets/css/page-slide.css'
],
四、模板
在开发应用时,经常会用到一些公用的元素,比如网页的标题是一样的,每个页面都是一模一样的标题。这时候我们有两种方法,第一种方法是作一个公用的组件出来,第二种方法是修改默认模板。这两种方法各有利弊,比如公用组件更加灵活,但是每次都需要自己手动引入;模板比较方便,但是只能每个页面都引入。
定制化默认的 html 模板,只需要在应用根目录下创建一个 app.html
的文件。
默认模板为:
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
{{HEAD}}
读取的是nuxt.config.js里的信息,{{APP}}
就是我们写的pages文件夹下的主体页面了。需要注意的是HEAD和APP都需要大写。
五、布局
默认布局:layouts/default.vue
布局写在layouts文件夹中,例:layouts/blog.vue (注意:添加 <nuxt/>
组件用于显示页面的主体内容。)
<template>
<div>
<div>我的博客导航栏在这里</div>
<nuxt/>
</div>
</template>
页面中引入布局:
export default {
layout: 'blog'
}
六、页面中的特殊配置
七、asyncData
asyncData在页面初始化前调用获取数据(可以在服务端或路由更新之前被调用。),无法通过this来引用组件实例。
Nuxt.js 会将 asyncData
返回的数据融合组件 data
方法返回的数据一并返回给当前组件。
第一个参数是上下文对象,可获取到动态路由参数。但query参数的改变不会调用asyncData方法,可以设置应通过页面组件的watchQuery
属性监听参数。
返回 Promise:
asyncData({params, error}) {
return axios.get(`https://api.myjson.com/bins/g5whc`)
.then((res) => {
console.log(res);
return {info: res.data};
})
.catch((e) => {
error({
statusCode: 404,
message: 'Post not found'
})
})
}
使用 async或await:
async asyncData({params}) {
console.log(params)
let { data } = await axios.get(`https://api.myjson.com/bins/g5whc`)
console.log({info: data })
return {info: data};
}
使用 回调函数:
export default {
asyncData ({ params }, callback) {
axios.get(`https://my-api/posts/${params.id}`)
.then((res) => {
callback(null, { title: res.data.title })
})
}
}
八、插件
1.使用第三方模块:
步骤:安装npm包,在组件中导入
npm install --save axios
<template>
<h1>{{ title }}</h1>
</template>
<script>
import axios from 'axios'
...
</script>
2.使用vue插件
步骤:在 plugins/
目录下创建相应的插件文件,并在 nuxt.config.js
中的 plugins
配置项中配置插件的路径。在组件中导入并用Vue.use()。
module.exports = {
plugins: ['~plugins/vue-notifications']
}
import Vue from 'vue'
import VueNotifications from 'vue-notifications'
Vue.use(VueNotifications)
3.使用位于node_modules的插件:
步骤:将其添加到 nuxt.config.js
中的transpile
构建选项
module.exports = {
build: {
transpile: ['vue-notifications']
}
}
4、将函数或属性值注入 Vue 实例
在plugin文件夹中创建vue-inject.js
import Vue from 'vue'
Vue.prototype.$myInjectedFunction = (string) => console.log("This is an example", string)
在nuxt.config.js中引入
export default {
plugins: ['~/plugins/vue-inject.js']
}
在组件中使用
export default {
mounted(){
this.$myInjectedFunction('test')
}
}
5.将函数或属性值注入context,在获得context的地方就能使用(例如在asyncData
和fetch
中)
在plugin文件夹中创建ctx-inject.js
export default ({ app }, inject) => {
app.myInjectedFunction = (string) => console.log('Okay, another function', string)
//如果同时注入vue实例中,写成如下形式:
inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
在nuxt.config.js中引入
export default {
plugins: ['~/plugins/ctx-inject.js']
}
在组件中使用
export default {
asyncData(context){
context.app.myInjectedFunction('ctx!')
}
}