Nuxt.js 提供了脚手架工具 create-nuxt-app
create-nuxt-app
需要使用 npx
npx 命令为 NPM版本5.2.0默认安装组件
npx create-nuxt-app
project-name
npm run dev
目录名称 | 描述 |
---|---|
assets | 资源目录,用于存放需要编译的静态资源。例如:LESS、SASS等 默认情况下,Nuxt使用Webpack若干加载器处理目录中的文件 |
components | vue组件目录,Nuxt.js 不会增强该目录,及不支持SSR |
layouts | 布局组件目录 |
pages | 页面目录,所有的vue视图,nuxt根据目录结构自动生成对应的路由。 |
plugins | 插件目录 |
static | 静态文件目录,不需要编译的文件 |
store | vuex目录 |
nuxt.config.js | nuxt个性化配置文件,内容将覆盖默认 |
package.json | 项目配置文件 |
assets 资源的引用:~ 或 @
// HTML 标签
// CSS
background-image: url(~assets/13.jpg);
background-image: url(~/assets/13.jpg);
background-image: url(@/assets/13.jpg);
static 目录资源的引用:/ 直接引用
//html标签
//css
background-image: url(/12.jpg);
举个栗子吧
<template>
<div>
<img src="~assets/13.jpg" style="height:100px;width:100px;" alt="">
<img src="/12.jpg" style="height:100px;width:100px;" alt="">
<div class="img1">div>
<div class="img2">div>
div>
template>
<script>
export default {
}
script>
<style>
.img1 {
height: 100px;
width: 100px;
background-image: url(~assets/13.jpg);
background-size: 100px 100px;
display: inline-block;
}
.img2 {
height: 100px;
width: 100px;
background-image: url(/12.jpg);
background-size: 100px 100px;
display: inline-block;
}
style>
标签。标签名 | 描述 |
---|---|
|
nuxt.js中切换路由 |
|
nuxt.js的路由视图 |
|
vue默认切换路由 |
|
vue默认路由视图 |
路径 | 组件位置及其名称 | 规则 |
---|---|---|
/ | pages/index.vue | 默认文件 index.vue |
/user | pages/user/index.vue | 默认文件 index.vue |
/user/one | pages/user/one.vue | 指定文件 |
栗子
1:访问路径,由pages目录资源的名称组成(目录名称、文件的名称)
资源位置: ~/pages/user/one.vue
访问路径:http://localhost:3000/user/one
2:每一个目录下,都有一个默认文件 index.vue
资源位置: ~/pages/user/index.vue
访问路径:http://localhost:3000/user
/user
可以匹配的文件pages/user.vue
文件 【优先级高】pages/user/index.vue
文件路由中路径匹配 | 组件位置及其名 |
---|---|
/ | pages/index.vue |
/user/:id | pages/user/_id.vue |
/:slug | pages/_slug/index.vue |
/:slug/comments | pages/_slug/comments.vue |
栗子:获得id值,创建资源 user/_id.vue
<template>
<div>
查询详情 {{this.$route.params.id}}
div>
template>
<script>
export default {
transition: 'test',
mounted() {
console.info(this.$route)
},
}
script>
<style>
style>
<nuxt-link :to="{name:'news-id',params:{id:1002}}">第2nuxt-link>
<nuxt-link :to="{name:'news-name',params:{name:1003}}">第3nuxt-link>
路径 | 组件位置及其名称 |
---|---|
不匹配的路径 | pages/_.vue |
创建嵌套子路由,你需要添加一个 父组件Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
显示子视图内容pages/
--| book/ //同名文件夹
-----| _id.vue
-----| index.vue
--| book.vue //父组件
pages/child/book.vue
<template>
<div>
<nuxt-link to="/child/book/list">书籍列表nuxt-link> |
<nuxt-link to="/child/book/123">书籍详情nuxt-link> |
<hr>
<nuxt-child />
div>
template>
<script>
export default {
}
script>
<style>
style>
pages/child/book/list.vue
<template>
<div>书籍列表div>
template>
<script>
export default {
}
script>
<style>
style>
pages/child/book/_id.vue
<template>
<div>书籍详情{{$route.params.id}} div>
template>
<script>
export default {
}
script>
<style>
style>
.page-enter-active
样式表示进入的过渡效果。.page-leave-active
样式表示离开的过渡效果。assets/main.css
,编写如下内容:.page-enter-active, .page-leave-active {
transition: opacity .5s;
}
.page-enter, .page-leave-active {
opacity: 0;
}
module.exports = {
css: [
‘assets/main.css’
]
}
transition
字段即可:assets/main.css
中添加名称为test
的过渡效果.test-enter-active, .test-leave-active {
transition: all 2s;
font-size:12px;
}
.test-enter, .test-leave-active {
opacity: 0;
font-size:40px;
}
export default {
transition: 'test'
}
定制化默认的 html 模板,只需要在应用根目录下创建一个 app.html 的文件。
默认模板:
DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
head>
<body {{ BODY_ATTRS }}>
{{ APP }}
body>
html>
DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
head>
<body {{ BODY_ATTRS }}>
{{ APP }}
body>
html>
layouts/default.vue
<template>
<div>
<nuxt-link to="/">首页nuxt-link> |
<nuxt-link to="/user/login">登录nuxt-link> |
<nuxt-link to="/user/123">详情nuxt-link> |
<nuxt-link to="/about">默认页nuxt-link> |
<nuxt-link to="/nuxt/async">asyncnuxt-link> |
<hr/>
<Nuxt />
div>
template>
<template>
<div>
开头<br/>
<nuxt/>
结束<br/>
div>
template>
<script>
export default {
}
script>
<style>
style>
<script>
export default {
layout: 'blog'
//...
}
script>
layouts/error.vue
页面,实现个性化错误页面<template>
<div>
<div v-if="error.statusCode == 404">
404 页面不存在 {{error.message}}
div>
<div v-else>
应用程序错误
div>
<nuxt-link to="/">首 页nuxt-link>
div>
template>
<script>
export default {
props: ['error']
}
script>
<style>
style>
_.vue
(先执行)~/layouts/error.vue
页面组件实际上是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项
特殊配置项 | 特殊配置项 |
---|---|
asyncData | SSR进行异步数据处理,也就是服务器端ajax操作区域。 |
fetch | 在渲染页面之前获取数据填充应用的状态树(store) |
head | 配置当前页面的 Meta 标签 |
layout | 指定当前页面使用的布局 |
transition | 指定页面切换的过渡动效 |
scrollToTop | 布尔值,默认: false。 用于判定渲染页面前是否需要将当前页面滚动至顶部。 |
<template>
<h1 class="red">Hello {{ name }}!h1>
template>
<script>
export default {
//异步处理数据, 每次加载之前被调用
asyncData (context) {
// called every time before loading the component
return { name: 'World' }
},
//用于在渲染页面之前获取数据填充应用的状态树(store)
fetch () {
// The fetch method is used to fill the store before rendering the page
},
//配置当前页面的 Meta 标签
head: {
// Set Meta Tags for this Page
},
// and more functionality to discover
...
}
script>
<style>
.red {
color: red;
}
style>
<html>
<head>
<meta charset="UTF-8" />
<title>我是标题title>
<link rel="stylesheet" type="text/css" href="css外部文件"/>
<script src="js外部文件" type="text/javascript" charset="utf-8">script>
head>
<body>
body>
html>
<template>
<div>
详情页 {{$route.params.id}} <br/>
<div class="bg2">div>
<div class="bg3">div>
div>
template>
<script>
export default {
head: {
title: '详情页',
link: [
{rel:'stylesheet',href:'/style/img.css'},....
],
script: [
{ type: 'text/javascript', src: '/js/news.js' }
]
}
}
script>
<style>
.bg2 {
background-image: url('~static/img/2.jpg');
width: 300px;
height: 300px;
background-size: 300px;
}
style>
在构建项目时,如果选择axios组件,nuxt.js将自动与axios进行整合
“dependencies”: {
“@nuxtjs/axios”: “^5.13.1”,
},
npm install
modules: [
// https://go.nuxtjs.dev/axios
‘@nuxtjs/axios’,
],
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
baseURL:‘http://localhost:10010/’
},
在vue页面中,通过 this. a x i o s . x x x ( ) 操 作 a j a x 。 t h i s . axios.xxx() 操作ajax。this. axios.xxx()操作ajax。this.axios 与之前 axios等效。
this.$axios.post("/search-service/search",this.searchMap).then( res => {
//获得查询结果
this.searchResult = res.data.data;
});
export default {
async asyncData( context ) { //context就相当于其他地方的this
//发送ajax
let { data } = await context.$axios.get('路径','参数')
// 返回结果
return {变量: 查询结果从data获取 }
},
}
<template>
<div>{{echo}}div>
template>
<script>
export default {
async asyncData(context) {
// 发送ajax
let {data} = await context.$axios.get('/service-consumer/feign/echo/abc')
// 返回数据
return {
echo: data
}
},
}
script>
<style>
style>
语法1:
export default {
async asyncData( content ) {
let [结果1,结果2] = await Promise.all([ ajax请求1, ajax请求2])
return {
变量1: 结果1,
变量2: 结果2
}
},
}
语法2:
export default {
async asyncData( content ) {
let [{数据:别名1},{数据:别名2}] = await Promise.all([ ajax请求1, ajax请求2])
return {
变量1: 别名1,
变量2: 别名2
}
},
}
<template>
<div>{{echo}} {{echo2}}div>
template>
<script>
export default {
async asyncData(context) {
// 发送ajax
let [{data:echo}, {data:echo2}] =
await Promise.all([
context.$axios.get('/service-consumer/feign/echo/abc'),
context.$axios.get('/service-consumer/client/echo/abc')
])
// 返回数据
return {
echo,
echo2
}
},
}
script>
<style>
style>
fetch 方法用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。
store/index.js
export const state = () => ({
str: 0
})
export const mutations = {
setData (state, value) {
state.str = value
}
}
{{$store.state.str}}
nuxt.conf.js
中配置客户端插件,设置 mode 为 client plugins: [
{ src: '~plugins/api.js', mode: 'client' }
],
//自定义函数
const request = {
test : (params) => {
return axios.get('/service-consumer/feign/echo/abc',{
params
})
},
}
var axios = null
export default ({ $axios }, inject) => {
//3) 保存内置的axios
axios = $axios
//4) 将自定义函数交于nuxt
// 使用方式1:在vue中,this.$request.xxx()
// 使用方式2:在nuxt的asyncData中,content.app.$request.xxx()
inject('request', request)
}
plugins: [
{ src: '~plugins/api.js', mode: 'client' },
{ src: '~plugins/api.server.js', mode: 'server' },
],
~~~
2. * 编写 `plugins/api.server.js` 对 内置的 $axios进行增强
~~~javascript
const request = {
test : (params) => {
return axios.get('/service-consumer/feign/echo/abc',{
params
})
},
}
var axios = null
export default ({ $axios, redirect, process }, inject) => {
//赋值
axios = $axios
//4) 将自定义函数交于nuxt
// 使用方式1:在vue中,this.$request.xxx()
// 使用方式2:在nuxt的asyncData中,content.app.$request.xxx()
inject('request', request)
}
//方式1:通过src设置文件,通过mode设置模式
plugins: [
{ src: '~/plugins/apiclient.js', mode: 'client' }, //前端客户端
{ src: '~/plugins/apiserver.js', mode: 'server' }, //前端服务端
{ src: '~/plugins/api.js' } //前端客户端 + 前端服务端
]
//方式2:通过命名来确定模式
plugins: [
'~/plugins/api.client.js', //前端客户端
'~/plugins/api.server.js', //前端服务端
'~/plugins/api.js', //前端客户端 + 前端服务端
]
store/index.js
添加一个 counter变量,并可以继续累加操作export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
<template>
<div>
首页 {{counter}}
<input type="button" value="+" @click="increment"/>
div>
template>
<script>
import { mapState,mapMutations } from 'vuex'
export default {
computed: {
...mapState(['counter'])
},
methods: {
...mapMutations(['increment'])
},
}
script>
<style>
style>
store/book.js
export const state = () => ({
money: 0
})
export const mutations = {
addmoney (state) {
state.money += 5
}
}
首页 {{money}}
// state为一个函数, 注意箭头函数写法
const state = () => ({
user: 'jack'
})
// mutations为一个对象
const mutations = {
setUser(state, value) {
state.counter = value
}
}
// action执行mutation
const actions = {
userAction (context,value){
// 可以发送ajax
context.commit('setUser',value)
}
}
// 获取数据
const getters = {
getUser (state) {
return state.user
}
}
export default {
namespace: true, // 命名空间
state,
mutations,
actions,
getters
}