初始化创建项目
yarn create nuxt-app <项目名>
css预编译
安装 yarn add node-sass scss-loader sass-loader --save-dev
路由管理
在nuxt中路由已经被集成到框架中,所以不需要再单独引入配置,而且当页面文件创建后, router会生成响应的路由,路由文件在.nuxt/router.js文件,用法上基本不变, 与vue-router用法不同部分记录如下
跳转与传参
- nuxt路由跳转同样是分为两种方式(声明式和编程式),不同的是在nuxt中用跳转标签nuxt-link而不是router-link
- 传参demo如下
1 <nuxt-link :to="{name:'home',params:{newsId:3306}}">home1</nuxt-link>
2 接收参数
3 asyncData({ params }) {
4 console.log('home1', params);
5 },
6 <nuxt-link :to="{path:'home',query:{newsId:3306}}">home2</nuxt-link>
7 接收参数
8 asyncData({ query }) {
9 console.log('home2', query);
10 },
页面切换动效
路由动效分为全局动效和单独页面动效
- 创建动效文件,在asset文件下创建动效样式文件(这里定义文件名changePage.css)
- 定义动画效果,这里定义简单的淡入淡出效果
// 页面默认的页面切换类名为page-enter、page-enter-active、page-leave-active .page-enter-active, .page-leave-active { transition: opacity 1s; } .page-enter, .page-leave-active { opacity: 0; }
引入定义的动效文件,在nuxt.config.js文件中配置中引入该css文件
定义单独页面动效
- 在页面文件中定义样式类名
1 export default {
2 transition: 'home'
3 }
在css文件中定义动画效果
.home-enter-active, .home-leave-active { transition: all 2s; font-size: 12px; } .home-enter, .home-leave-active { opacity: 0; font-size: 40px; }
嵌套路由
开发业务中,有时难免会遇到需要二级甚至多层路由嵌套,官方文档中的二级路由介绍也是过于简单,为此又多掉了几根头发 这里就拿官网文档的例子作为讲解
1 第一:假设要创建一个user的二级路由,文件结构如:
2
3 pages/
4 --| users/ //2、最容易创建与user.vue文件同名的文件夹,这样nuxt就会识别出我们的意图,原来是要创建嵌套路由
5 //假如文件夹与user.vue不同名,那么该文件夹下的文件同样被生成一级路由
6 -----| _id.vue
7 -----| index.vue
8 --| users.vue // 1、首先要有user.vue文件
9
10 第二:Nuxt.js 自动生成的路由配置如下:
11 router: {
12 routes: [
13 {
14 path: '/users',
15 component: 'pages/users.vue',
16 children: [
17 {
18 path: '',
19 component: 'pages/users/index.vue',
20 name: 'users'
21 },
22 {
23 path: ':id',
24 component: 'pages/users/_id.vue',
25 name: 'users-id'
26 }
27 ]
28 }
29 ]
30 }
31 第三:在一级页面中显示二级页面
32 <template>
33 <div class="page-me">
34 <div>一级页面的相关内容、、、</div>
35 <nuxt-child /> //二级页面的视图窗口,相当于Vue Router的<router-view></router-view>
36 </div>
37 </template>
路由拦截/鉴权
nuxt的路由拦截与Vue Router不同,需要引入中间件 的概念,好在文档介绍比较容易理解,现梳理如下
- 需要在指定的文件夹middleware/ 下创建路由拦截文件(文件不限数量)
- 一个中间件接收 context 作为第一个参数,context包含了包括vuex等在内相关数据信息,以此通过数据执行相关逻辑
export default function (context) {
context.userAgent = process.server ? context.req.headers['user-agent'] : navigator.userAgent
}
在nuxt.config.js为全局页面定义路由拦截
module.exports = {
router: {
middleware: 'stats'//中间件文件名
}
}
当然不想全局定义路由拦截也可以为单独的页面定义路由拦截
//具体的页面
export default {
middleware: 'stats'
}
错误页设置
一个完成项目,404或其他错误页面总是要有的,对此nuxt已经封装了404页面跳转,在layouts文件夹下创建error.vue文件(文件名必须是error.vue),组件接收error对象参数,通过参数的状态码判断页面错误原因
<template>
<div class="container">
<h2 v-if="error.statusCode == 404">这是404页面</h2>
<h2 v-else>这是500页面</h2>
</div>
</template>
<script>
export default {
props: ['error'], //nuxt已经封装好返回的
mounted() {
console.log('error', this.error);
}
};
</script>
接口请求
安装
- 安装:yarn add @nuxtjs/axios
- 同正常的axios用法相同,不做详细解释
本地代理
- npm i @nuxtjs/proxy -D
- 在 nuxt.config.js 配置文件中添加对应的模块,并设置代理
- 配置了代理,本地开发时axios就不能使用baseURL(打包时,baseURL还是需要放开)
1 modules: ['@nuxtjs/axios','@nuxtjs/proxy'],
2 axios: {
3 proxy: true
4 },
5 proxy: {//代理可以设置多个
6 '/api': {// /api是指真实接口域名后的一个层级
7 target: 'http://example.com',//真实接口域名
8 pathRewrite: {
9 '^/api' : '/'// "/api"与上面的api相同
10 }
11 }
12 }
axios API封装
- axios的封装与常规vue项目相同,不同的区别是需要在配置文件中将封装文件引入
plugins: ["@/plugins/element-ui", "~/plugins/api.js"]
api访问本地开发
通过设置IP地址,这样就可以通过IP访问本地项目环境
//package.json中配置
"devDependencies": {},
"config": {
"nuxt": {
"host": "0.0.0.0",
"port": "5000"
}
}
asyncData
用于服务端或路由更新之前被调用(如果这里进行接口请求,页面会等接口返回结果后才发生跳转),方法的第一个参数被设定为当前页面的上下文对象(即包含路由、参数等等的一些列信息),可用于请求一个或多个接口,并将返回的数据融合到组件的data中,改方法与mounted函数同级,只在页面模块的文件内生效,在组件模块文件内不生效,由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。
写法一
asyncData(context) {
return (
axios.get('https://api.myjson.com/bins/8gdmr1').then(res => {
return { info: res.data };
//注意,return返回的最好是key:value对象,直接return导致不利于从实例data中查找使用,如:
//return (res.data),因为没有设定key,返回的数据虽然融合到实例的data上,但没有key则没法通过key值查找使用
}),
axios.get('https://api.myjson.com/bins/8gdmr').then(res => {
return { info: res.data };
})
);
},
写法二
async asyncData({ params }) {
const { data } = await axios.get('https://api.myjson.com/bins/8gdmr');
return { info: data };
},
Vuex
nuxt中集成了vuex,不需要新安装插件,Nuxt.js 会尝试找到应用根目录下的 store 目录,并引用 vuex 模块,将 vuex 模块 加到 vendors 构建配置中去,设置 Vue 根实例的 store 配置项。
以上是官方文档原话,大白话翻译就是:nuxt已经集成了vuex不需要手动安装,nuxt会直接找到vuex文件,并把vuex配置到项目中,然后就想正常vue一样使用即可
创建与使用
- 1、vuex不需要新创建实例,即不需要new Vuex.Store({})
- 2、state的值应该始终是function,为了避免返回引用类型,会导致多个实例相互影响,即
//正确写法
export const state = () => ({
counter: 0
})
//错误写法
export const state = {
counter: 0
}
数据持久化
为避免页面刷新数据状态丢失,需要对vuex数据持久化,nuxt的vuex数据持久化与vue项目稍有不同,这里推荐的是nuxt-vuex-localstorage
- 安装
- 配置文件引入
//nuxt.config文件中引入 modules: ["nuxt-vuex-localstorage"]
欢迎大佬指教
项目中虽然在使用vuex,但遇到的问题依然很多,使用起来总是磕磕绊绊,欢迎留言指教
部分配置介绍
meta标签设置
既然是为了SEO优化,那么总是少不了mate标签关键字设定,mate标签分为定义全局和单个页面配置
- 配置文件定义全局
head: {
title: process.env.npm_package_name || "",
meta: [
{ charset: "utf-8" },
{
name: "viewport",
content: "width=device-width, initial-scale=1"
},
{
hid: "description",
name: "description",
content: process.env.npm_package_description || ""
}
],
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }]
},
设置页面独有关键字
export default {
data () {
return {
title: 'Hello World!'
}
},
head () {
return {
title: this.title,
meta: [
{ hid: 'description', name: 'description', content: 'My custom description' }
]
}
}
}