Nuxt.js详解

Nuxt.js

  • 1、 案例入门
    • 1.1、create-nuxt-app 介绍
    • 1.2、安装
    • 1.3 启动
    • 1.4、访问
  • 2、目录结构
    • 2.1、 目录
    • 1.2、别名
  • 3、路由
    • 3.1、路由概述
    • 3.2、基础路由
    • 3.3、动态路由
    • 3.4、动态命名路由
    • 3.5、默认路由
    • 3.6、嵌套路由
    • 3.7、过渡动效
      • 3.7.1 全局过渡动效设置
      • 3.7.2、 自定义动画
  • 4、视图
    • 4.1、默认模板
    • 4.2、默认布局
      • 4.2.1、 布局概述
      • 4.2.2、 布局分析
      • 4.2.3、 公共导航
    • 4.3、自定义布局
    • 4.4、错误页面
    • 4.5、Nuxt组件特殊配置
      • 4.5.1、 模板代码
      • 4.5.2、 head
  • 5、ajax操作
    • 5.1、整合 axios
      • 5.1.1 默认整合
      • 5.1.2 手动整合
      • 5.1.3、常见配置
    • 5.2、使用axios发送ajax
    • 5.3、使用asyncData发送 ajax
      • 5.3.1 发送一次请求
      • 5.3.2、发送多次请求
    • 5.4、使用fetch发送 ajax
    • 5.5、 插件:自定义axios
      • 5.1 客户端
      • 5.5.2 服务端
      • 5.5.3 插件配置总结
  • 6、Vuex 状态树
    • 6.1 根模块数据操作
    • 6.2 其他模块数据操作
    • 6.3 完整vuex模板
  • 7、nuxt流程总结

1、 案例入门

1.1、create-nuxt-app 介绍

  • Nuxt.js 提供了脚手架工具 create-nuxt-app

  • create-nuxt-app 需要使用 npx

  • npx 命令为 NPM版本5.2.0默认安装组件

1.2、安装

npx create-nuxt-app project-name

Nuxt.js详解_第1张图片

  • nuxtjs改善
    Nuxt.js详解_第2张图片

1.3 启动

npm run dev

Nuxt.js详解_第3张图片

1.4、访问

http://localhost:3000
Nuxt.js详解_第4张图片

2、目录结构

2.1、 目录

目录名称 描述
assets 资源目录,用于存放需要编译的静态资源。例如:LESS、SASS等
默认情况下,Nuxt使用Webpack若干加载器处理目录中的文件
components vue组件目录,Nuxt.js 不会增强该目录,及不支持SSR
layouts 布局组件目录
pages 页面目录,所有的vue视图,nuxt根据目录结构自动生成对应的路由。
plugins 插件目录
static 静态文件目录,不需要编译的文件
store vuex目录
nuxt.config.js nuxt个性化配置文件,内容将覆盖默认
package.json 项目配置文件

Nuxt.js详解_第5张图片

1.2、别名

  • 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>

3、路由

3.1、路由概述

  • Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
  • 要在页面之间切换路由,我们建议使用 标签。
标签名 描述
nuxt.js中切换路由
nuxt.js的路由视图
vue默认切换路由
vue默认路由视图

3.2、基础路由

  • 自动生成基础路由规则
路径 组件位置及其名称 规则
/ 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 文件

3.3、动态路由

  • 在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 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>

3.4、动态命名路由

  • 路径 /news/123 匹配_id.vue还是_name.vue
    Nuxt.js详解_第6张图片

  • 我们可以使用解决以上问题

    • 通过name 确定组件名称:“xxx-yyy”
    • 通过params 给对应的参数传递值
<nuxt-link :to="{name:'news-id',params:{id:1002}}">第2nuxt-link>
<nuxt-link :to="{name:'news-name',params:{name:1003}}">第3nuxt-link>

3.5、默认路由

路径 组件位置及其名称
不匹配的路径 pages/_.vue

3.6、嵌套路由

  • 创建嵌套子路由,你需要添加一个 父组件Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。

    • 要求:父组件 使用 显示子视图内容
pages/
--| book/						//同名文件夹
-----| _id.vue
-----| index.vue
--| book.vue					//父组件

  1. 编写父组件 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>

  1. 编写子组件 pages/child/book/list.vue
<template>
  <div>书籍列表div>
template>

<script>
export default {

}
script>

<style>

style>
  1. 编写子组件 pages/child/book/_id.vue
<template>
  <div>书籍详情{{$route.params.id}} div>
template>

<script>
export default {

}
script>

<style>

style>

3.7、过渡动效

3.7.1 全局过渡动效设置

  • Nuxt.js 默认使用的过渡效果名称为 page
    • .page-enter-active样式表示进入的过渡效果。
    • .page-leave-active样式表示离开的过渡效果。
  1. 创建 assets/main.css,编写如下内容:

.page-enter-active, .page-leave-active {
transition: opacity .5s;
}
.page-enter, .page-leave-active {
opacity: 0;
}

  1. nuxt.config.js 引入main.css文件

module.exports = {
css: [
‘assets/main.css’
]
}

3.7.2、 自定义动画

  • 如果想给某个页面自定义过渡特效的话,只要在该页面组件中配置 transition 字段即可:
  1. 在全局样式 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;
}

  1. 需要使用特效的vue页面编写如下:
export default {
  transition: 'test'
}

4、视图

4.1、默认模板

  • 定制化默认的 html 模板,只需要在应用根目录下创建一个 app.html 的文件。

  • 默认模板:

DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  body>
html>
  • 修改模板,对低版本IE浏览器进行支持(兼容IE浏览器)
DOCTYPE html>

<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  body>
html>

4.2、默认布局

4.2.1、 布局概述

  • 布局:Nuxt.js根据布局,将不同的组件进行组合。

  • 模板:html页面,是布局后所有组件挂载的基础。

  • Nuxt.js详解_第7张图片

4.2.2、 布局分析

  • layouts/default.vue 默认布局组件
    • 访问路径根据路由,确定执行组件
    • 组件具体显示的位置,有布局来确定
      Nuxt.js详解_第8张图片

4.2.3、 公共导航

  • 修改 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>

4.3、自定义布局

  • 在layouts目录下创建组件:layouts/blog.vue
<template>
	<div>
        开头<br/>
        <nuxt/>
        结束<br/>
    div>
  
template>

<script>
export default {

}
script>

<style>

style>

  • 在需要的视图中使用 blog布局
<script>
export default {
  layout: 'blog'
  //...
}
script>

Nuxt.js详解_第9张图片

4.4、错误页面

  • 编写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>
  • 解决问题: 404 、500、连接超时(服务器关闭)
  • 总结:所学习的技术中,有2种方式处理错误页面
    • 方式1:默认路径,_.vue (先执行)
    • 方式2:错误页面,~/layouts/error.vue

4.5、Nuxt组件特殊配置

页面组件实际上是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项

特殊配置项 特殊配置项
asyncData SSR进行异步数据处理,也就是服务器端ajax操作区域。
fetch 在渲染页面之前获取数据填充应用的状态树(store)
head 配置当前页面的 Meta 标签
layout 指定当前页面使用的布局
transition 指定页面切换的过渡动效
scrollToTop 布尔值,默认: false。 用于判定渲染页面前是否需要将当前页面滚动至顶部。

4.5.1、 模板代码

<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>

4.5.2、 head

  • html模板代码
<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>
  • 通过nuxt提供head属性,可以给单个也是设置:标题、外部css、外部js 等内容。
    Nuxt.js详解_第10张图片
<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>

5、ajax操作

5.1、整合 axios

5.1.1 默认整合

在构建项目时,如果选择axios组件,nuxt.js将自动与axios进行整合
Nuxt.js详解_第11张图片

5.1.2 手动整合

  1. 手动整合
    Nuxt.js详解_第12张图片

“dependencies”: {
“@nuxtjs/axios”: “^5.13.1”,
},

  1. 安装

npm install

  1. nuxt.config.js 以模块的方式添加axios
    Nuxt.js详解_第13张图片

modules: [
// https://go.nuxtjs.dev/axios
‘@nuxtjs/axios’,
],

5.1.3、常见配置

  • 修改 nuxt.config.js 进行baseURL的配置
    Nuxt.js详解_第14张图片

// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
baseURL:‘http://localhost:10010/’
},

5.2、使用axios发送ajax

在vue页面中,通过 this. a x i o s . x x x ( ) 操 作 a j a x 。 t h i s . axios.xxx() 操作ajax。this. axios.xxx()ajaxthis.axios 与之前 axios等效。

this.$axios.post("/search-service/search",this.searchMap).then( res => {
//获得查询结果
this.searchResult = res.data.data;
});

5.3、使用asyncData发送 ajax

  • asyncData中的ajax将在“前端服务端执行”,在浏览器看到是数据,而不是ajax程序。

5.3.1 发送一次请求

  • 语法:
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>

5.3.2、发送多次请求

语法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>

5.4、使用fetch发送 ajax

fetch 方法用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。
Nuxt.js详解_第15张图片

  1. 创建store/index.js
export const state = () => ({
  str: 0
})

export const mutations = {
  setData (state, value) {
    state.str = value
  }
}
    • 测试页面






5.5、 插件:自定义axios

5.1 客户端

  1. nuxt.conf.js中配置客户端插件,设置 mode 为 client
  plugins: [
    { src: '~plugins/api.js', mode: 'client' }
  ],

Nuxt.js详解_第16张图片

  1. 编写 plugins/api.js 对 内置的 $axios进行增强
    在这里插入图片描述
//自定义函数
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)
}

5.5.2 服务端

    • 配置服务端插件,设置 mode 为 server
    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)
  }
  

5.5.3 插件配置总结

//方式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',						//前端客户端 + 前端服务端
]

6、Vuex 状态树

6.1 根模块数据操作

  1. 创建 store/index.js 添加一个 counter变量,并可以继续累加操作
export const state = () => ({
  counter: 0
})

export const mutations = {
  increment (state) {
    state.counter++
  }
}
  1. 在页面中,使用
<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>

6.2 其他模块数据操作

  1. 创建其他模块 store/book.js
export const state = () => ({
  money: 0
})

export const mutations = {
  addmoney (state) {
    state.money += 5
  }
}
    • 使用指定模块中的数据





6.3 完整vuex模板

// 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
}

7、nuxt流程总结

Nuxt.js详解_第17张图片

你可能感兴趣的:(javascript,npm,vue.js)