Nuxt.js 是一个基于 Vue.js 的服务端渲染应用框架,它可以帮我们轻松的实现同构应用。
通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI渲染。
我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。
Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。
除此之外,我们还提供了一种命令叫: nuxt generate ,为基于 Vue.js 的应用提供生成对应的静态站点的功能。
我们相信这个命令所提供的功能,是向开发集成各种微服务(Microservices)的 Web 应用迈开的新一 步。
作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据 加载、中间件支持、布局支持等非常实用的功能。
Nuxt提供两种方式创建项目:
使用手动创建过程:
1. 初始化项目目录并安装nuxt
# 创建示例项目
mkdir nuxt-js
# 进入示例项目目录中
cd nuxt-js
# 初始化 package.json 文件
npm init -y
# 安装 nuxt
npm innstall nuxt
在package.json中scripts添加
"scripts": {
"dev": "nuxt --open",
},
2. 创建页面并启动项目
在根目录下创建pages目录,并创建index.vue文件
pages/
--| index.vue
启动项目
npm run dev
3. Nuxt中创建路由
Nuxt会跟据pages目录中的所有.vue文件生成应用的路由配置
假设 pages 的目录结构如下:
pages/
--| users/
-----| edit.vue
--| index.vue
那么,Nuxt自动生成路由配置如下(注意:直接创建.vue文件,自动生成)
routes: [
{
path: "/users/edit",
component: pages/users/edit,
name: "users-edit"
},
{
path: "/",
component: pages/users/index,
name: "index"
}
],
Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
1、路由导航
<nuxt-link>
组件2、动态路由
在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。 以下目录结构:
pages/
--| users/
-----| _id.vue
--| _dynamic/
-----| index.vue
--| index.vue
Nuxt生成对应的路由配置表为:
routes: [
{
path: "/users/:id",
component: pages/users/_id,
name: "users-id"
},
{
path: "/:dynamic.vue",
component: pages/_dynamic.vue/index,
name: "dynamic.vue"
},
{
path: "/",
component: pages/user/index,
name: "index"
},
],
3、嵌套路由
创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
需要在父组件中增加<nuxt-child/>
用于显示子视图内容
pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue
Nuxt.js 自动生成的路由配置如下:
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'
}
]
}
]
4、自定义路由配置
在 Nuxt.js 里面自定义路由,需要将动态路由_id.vue文件改为detail.vue文件。 以下目录结构:
改为文件只要不是下划线定义的都可以,如果不将_id.vue改为detail.vue则跳入动态路由_id.vue页面
pages/
--| users/
-----| detail.vue
-----| index.vue
-----| edit.vue
创建nuxt.config.js文件配置自定义路由
export default {
// nuxt配置自定义路由模块
router: {
// 扩展路由配置
extendRoutes (routes, resolve) {
routes.push(
{
//将detail.vue改为动态路由
name: 'users/detail',
path: '/users/(\\d+)',
component: resolve(__dirname, '@/pages/users/detail.vue')
},
{
//将http://localhost:3000/users/edit修改为http://localhost:3000/users/edit.html
name: 'users/edit',
path: '/users/edit.html',
component: resolve(__dirname, '@/pages/users/edit')
},
{
//将http://localhost:3000/users/edit修改为http://localhost:3000/users/b1_x2
name: 'users1',
path: '/users/:id?',
component: resolve(__dirname, '@/pages/users/index.vue')
},
{
//将http://localhost:3000/users/edit修改为http://localhost:3000/users/b1_x2/p1.html
name: 'users2',
path: '/users/:id/p(\\d+)\.html',
component: resolve(__dirname, '@/pages/users/index.vue')
},
)
}
}
}
1. 全局组件
根目录/
--| components/
-----| Header.vue
export default {
components: true,
}
<template>
<div>
<Header/>
</div>
</template>
2. 局部组件
根目录/
--| components_page/
-----| Header.vue
<template>
<div>
<Header/>
<nuxt />
<Footer/>
</div>
</template>
<script>
import Footer from "@/components_page/Footer";
export default {
components:{
Footer,
},
data () {
return {
};
},
};
</script>
根目录下创建layouts目录,default.vue为默认布局组件,以下目录结构:
根目录/
--| layouts/
-----| default.vue
<template>
<div>
<!-- 类似于页面入口 -->
<Header/>
<nuxt />
<Footer/>
</div>
</template>
<script>
import Footer from "@/components_page/Footer";
export default {
components:{
Footer,
},
data () {
return {
};
},
};
</script>
<style scoped lang="scss">
</style>
新增boo.vue组件
根目录/
--| layouts/
-----| default.vue
-----| boo.vue
在pages中需要页面中添加layout: “boo”,
<template>
<div>
users_index
</div>
</template>
<script>
export default {
// 默认layout设置自定义的布局组件 未设置的路由还会走默认的布局组件
layout: "boo",
data () {
return {
};
},
};
</script>
<style scoped lang="scss">
</style>
// nuxt.config.js
head: {
title: 'nuxt',
htmlAttrs: {
lang: 'zh'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ 'http-equiv': "X-UA-Compatible", content: 'IE=edge,chrome=1' },
{ name: 'format-detection', content: 'telephone=no' },
{ name: 'referrer', content: 'origin' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
],
script: [],
},
asyncData
的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。// 当你想要动态页面内容有利于 SEO 或者是提升首屏渲染速度的时候,就在 asyncData 中发请求拿数据
// 注意事项:1.只能在页面组件中使用,子组件中可通过props获取父组件异步数据 2.没有this,在组件初始化之前被调用
// 调用时机:1.获取服务端渲染数据(确保异步数据在渲染到客户端之前已经填充渲染完成,提高渲染速度,有利于SEO) 2.客户端路由更新之前也会被调用
async asyncData (context) {
//获取上下文对象
console.log(context)
// 此时输出在服务端执行
// 在浏览器也会输出 包裹在Nuxt SSR中
const res = await axios({
method: 'GET',
url: '/pc/story/index'
})
// 返回的对象可以直接在页面组件使用
// 在vue调试工具中有了posts和title
// asyncData返回的数据会和data中的混合
return {
list: res,
}
},
// 如果是非异步数据或者普通数据,则正常的初始化到 data 中即可
data () {
return {
list: [],
}
}
此方法只能在组件中使用
async fethch () {
const res = await axios({
method: 'GET',
url: '/pc/story/index'
})
this.list = res,
},
data () {
return {
list: [],
}
}
如果你需要的话,可以很方便的在服务端禁用 fetch 函数。
export default {
fetchOnServer: false
};
使用中间件对用户进行身份验证,并允许他们在验证通过后访问页面
//校验某个页面是否登录
export default function ({ app, redirect }) {
if (!app.$cookies.get('token')) {
return redirect('/user/login.html')
}
}
npm install swiper vue-awesome-swiper --save
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)
css: [
'@/node_modules/swiper/css/swiper.min.css',
],
plugins: [
{ src: "@/plugins/vue-awesome-swiper", ssr: false },
],
npm install animate.css --save
css: [
'@/assets/css/animate.css'
],
<h1 class="animate__animated animate__bounce">An animated element</h1>
npm install wowjs --save-dev
if (process.browser) {
// 在这里根据环境引入wow.js
var { WOW } = require("wowjs");
}
mounted() {
var wow = new WOW({
live: false
})
wow.init()
}
<div class="wow fadeInUp" data-wow-delay="50ms">fadeInUp动画效果</div>
cnpm install vue-lazyload --save-dev
import Vue from 'vue'
import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad, {
preLoad: 2.3, //预加载高度比例
error: "", //错误时加载图片
loading: 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==', //预加载图片
attempt: 2, //尝试加载图片数量
throttleWait: 500 // 截流等待
})
plugins: [
{ src: "@/plugins/vue-lazyload", ssr: false }
],
<img v-lazy="baseUrl+item.pictor" :alt="" :title="" class="" />。