目錄
一、路由
二、視圖
三、異步數(shù)據(jù)
四、插件
系列教程
Nuxt.js教程(初識篇)
一、路由
1、基礎(chǔ)路由
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
//自動轉(zhuǎn)換成以下路由配置,因此,管理pages目錄內(nèi)容,就相當(dāng)于配置路由
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'user',
path: '/user',
component: 'pages/user/index.vue'
},
{
name: 'user-one',
path: '/user/one',
component: 'pages/user/one.vue'
}
]
}
2、動態(tài)路由
pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue //users沒有路由組件,_id是可選路由
--| index.vue
//加上‘_’前綴,即可配置動態(tài)路由
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}
3、動態(tài)路由校驗
//動態(tài)路由的層級名,是由相應(yīng)組件的validate函數(shù),通過名稱驗證來決定的
// user/_id.vue
export default {
validate ({ params }) {
// 規(guī)定改層級名,必須是數(shù)字
// localhost:3000/user/任意數(shù)字串,才可以訪問該組件
return /^\d+$/.test(params.test)
}
}
4、嵌套路由
pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue
//將頁面級的路由組件,抽離成單獨組件,內(nèi)部存在小型路由組件
router: {
routes: [
{
path: '/users',
component: 'pages/users.vue',
children: [
{
path: '',
component: 'pages/users/index.vue',
name: 'users'
},
{
path: ':id',
component: 'pages/users/_id.vue',
name: 'users-id'
}
]
}
]
}
5、動態(tài)嵌套路由
pages/
--| _category/
-----| _subCategory/
--------| _id.vue
--------| index.vue
-----| _subCategory.vue
-----| index.vue
--| _category.vue
--| index.vue
router: {
routes: [
{
path: '/',
component: 'pages/index.vue',
name: 'index'
},
{
path: '/:category',
component: 'pages/_category.vue',
children: [
{
path: '',
component: 'pages/_category/index.vue',
name: 'category'
},
{
path: ':subCategory',
component: 'pages/_category/_subCategory.vue',
children: [
{
path: '',
component: 'pages/_category/_subCategory/index.vue',
name: 'category-subCategory'
},
{
path: ':id',
component: 'pages/_category/_subCategory/_id.vue',
name: 'category-subCategory-id'
}
]
}
]
}
]
}
6、未知路由
pages/
--| people/
-----| index.vue
--| _.vue //localhost:3000、localhost:3000/people以外的路徑,都會匹配到_.vue這一頁面級路由組件
--| index.vue
//可用作錯誤頁
7、命名視圖
//使用<nuxt name="top"/>或<nuxt-child name="top"/>命名視圖,需要先配置
//nuxt.config.js
export default {
router: {
extendRoutes(routes, resolve) {
let index = routes.findIndex(route => route.name === 'main')
routes[index] = {
...routes[index],
components: {
default: routes[index].component,
top: resolve(__dirname, 'components/mainTop.vue')
},
chunkNames: {
top: 'components/mainTop'
}
}
}
}
}
8、過渡效果
//全局過渡
//assets/main.css
.page-enter-active, .page-leave-active {
transition: opacity .5s;
}
.page-enter, .page-leave-active {
opacity: 0;
}
//nuxt.config.js
css: [
'assets/main.css'
]
//局部過渡
//assets/test.css
.test-enter-active, .test-leave-active {
transition: opacity .5s;
}
.test-enter, .test-leave-active {
opacity: 0;
}
//nuxt.config.js
css: [
'assets/test.css'
]
//test.vue
export default {
transition: 'test'
}
9、中間件???????????????
二、視圖

??????????????嵌套關(guān)系
1、模板
//根目錄下,新建app.html
//app.html
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }} //layout
</body>
</html>
//插值表達式受配置文件控制
PS:新建app.html后,重啟服務(wù)器,才有模板效果。
2、布局
//默認(rèn)布局
// layouts/default.vue
<template>
<div>
<nuxt/> //page
</div>
</template>
//自定義布局
// layouts/myLayout.vue
<template>
//div內(nèi),加入自定義內(nèi)容
<div>
<nuxt/>
</div>
</template>
//標(biāo)識需要套用myLayout.vue的page組件
export default {
layout: 'myLayout'
}
//錯誤布局(存放在layout目錄的page)
// layouts/error.vue
<template>
<div class="container">
<h1 v-if="error.statusCode === 404">頁面不存在</h1>
<h1 v-else>應(yīng)用發(fā)生錯誤異常</h1>
<nuxt-link to="/">首 頁</nuxt-link>
</div>
</template>
<script>
export default {
props: ['error'],
layout: 'myLayout' // 你可以為錯誤頁面指定自定義的布局
}
</script>
4、頁面
特殊配置項
| 名稱 | 功能 |
|---|---|
| asyncData | 最重要的一個鍵, 支持異步數(shù)據(jù)處理,另外該方法的第一個參數(shù)為當(dāng)前頁面組件的上下文對象 |
| fetch | 與asyncData方法類似,用于在渲染頁面之前獲取數(shù)據(jù)填充應(yīng)用的狀態(tài)樹(store)。不同的是fetch方法不會設(shè)置組件的數(shù)據(jù) |
| head | 配置當(dāng)前頁面的 Meta 標(biāo)簽 |
| layout | 指定當(dāng)前頁面使用的布局(layouts根目錄下的布局文件) |
| loading | 如果設(shè)置為false,則阻止頁面自動調(diào)用this.$nuxt.$loading.finish()和this.$nuxt.$loading.start() |
| transition | 指定頁面切換的過渡動效 |
| scrollToTop | 布爾值,默認(rèn)false。 用于判定渲染頁面前是否需要將當(dāng)前頁面滾動至頂部 |
| validate | 校驗方法用于校驗動態(tài)路由 |
| middleware | 指定頁面的中間件,中間件會在頁面渲染之前被調(diào)用 |
5、html頭部
//nuxt.js使用vue-meta管理html頭部
//nuxt.config.js
head: {
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
],
link: [
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' }
]
}
三、異步數(shù)據(jù)
1、asyncData方法
(1)觸發(fā)時刻
asyncData方法會在組件(限于頁面組件)每次加載之前被調(diào)用,它可以在服務(wù)端或路由更新之前被調(diào)用。
(2)案例
export default {
//參數(shù):當(dāng)前頁面的上下文對象
async asyncData ({ params }) {
let { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
2、上下文對象
(1)使用 req / res 對象
//服務(wù)器端調(diào)用asyncData
export default {
async asyncData ({ req, res }) {
// 請檢查您是否在服務(wù)器端
// 使用 req 和 res
if (process.server) {
return { host: req.headers.host }
}
return {}
}
}
(2)訪問動態(tài)路由數(shù)據(jù)
//訪問路由對象的params
export default {
async asyncData ({ params }) {
return { params }
}
}
3、錯誤處理
export default {
asyncData ({ params, error }) {
return axios.get(`https://my-api/posts/${params.id}`)
.then((res) => {
return { title: res.data.title }
})
.catch((e) => {
error({ statusCode: 404, message: 'Post not found' })
})
}
}
四、插件
1、Vue插件
//vue插件使用前,必須做相應(yīng)的配置
//nuxt.config.js
//plugins目錄的vue插件
plugins: ['plugins/插件名']
//node_modules目錄的vue插件
build: {
transpile: ['插件名']
}
2、注入
(1)注入到Vue實例
// plugins/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']
}
//example-component.vue
export default {
mounted(){
this.$myInjectedFunction('test')
}
}
(2)注入到context
// plugins/ctx-inject.js
export default ({ app }, inject) => {
app.myInjectedFunction = (string) => console.log('Okay, another function', string)
}
//nuxt.config.js
export default {
plugins: ['~/plugins/ctx-inject.js']
}
//ctx-example-component.vue
export default {
asyncData(context){
context.app.myInjectedFunction('ctx!')
}
}
(3)注入到Vue實例、context、Vuex
// plugins/combined-inject.js
export default ({ app }, inject) => {
inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
//nuxt.config.js
export default {
plugins: ['~/plugins/combined-inject.js']
}
//ctx-example-component.vue
export default {
mounted(){
this.$myInjectedFunction('works in mounted')
},
asyncData(context){
context.app.$myInjectedFunction('works with context')
}
}
// store/index.js
export const state = () => ({
someValue: ''
})
export const mutations = {
changeSomeValue(state, newValue) {
this.$myInjectedFunction('accessible in mutations')
state.someValue = newValue
}
}
export const actions = {
setSomeValueToWhatever ({ commit }) {
this.$myInjectedFunction('accessible in actions')
const newValue = "whatever"
commit('changeSomeValue', newValue)
}
}
3、只在客戶端使用的插件
//規(guī)定插件使用環(huán)境,客戶端/服務(wù)器端
//nuxt.config.js
//舊版本
plugins: [
{ src: '~/plugins/both-sides.js' },
{ src: '~/plugins/client-only.js', ssr: 'false' },
{ src: '~/plugins/server-only.js', ssr: 'true' }
]
//Nuxt.js 2.4+
plugins: [
{ src: '~/plugins/both-sides.js' },
{ src: '~/plugins/client-only.js', mode: 'client' },
{ src: '~/plugins/server-only.js', mode: 'server' }
]
模塊
介紹
Nuxt.js模塊列表
基本模塊
異步模塊
常見模塊
Vuex狀態(tài)樹
使用狀態(tài)樹
fetch方法
nuxtServerInit方法