Nuxt.js的介绍和使用

3 篇文章 0 订阅

官网文档地址:
https://www.nuxtjs.cn/guide

Nuxt.js常见问题和优化:
https://blog.csdn.net/qq_36228377/article/details/123642604

1.安装

  • 使用npx
npx create-nuxt-app xxx
  • 使用yarn
yarn create nuxt-app <项目名>

安装选项

Project name                                //  项目名称
Project description                         //  项目描述
Use a custom server framework               //  选择服务器框架
Choose features to install                  //  选择安装的特性
Use a custom UI framework                   //  选择UI框架
Use a custom test framework                 //  测试框架
Choose rendering mode                       //  渲染模式
Universal                                   //  渲染所有连接页面
Single Page App                             //  只渲染当前页面

启动开发模式

npm run dev

打包

npm run build
npm run start

生成静态项目

npm run generate

2.目录结构

文件目录

├── node_modules 依赖包
├── assets 资源文件
├── components 复用组件目录
├── layouts 布局目录
├── middleware 中间件目录(每个页面加载前使用)
│── nuxt.config.js 个性化配置文件
├── package.json: 应用包配置文件
├── pages 页面
│ └── index.vue: 主页面
├── plugins 插件
├── static 静态文件目录
│ └── favicon.ico: 页签图标
├── store 状态管理
├── .gitignore: git版本管制忽略的配置
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
└── package-lock.json: 包版本控制文件

3.生命周期

需要注意的是,在任何 Vue 组件的生命周期内, 只有 beforeCreatecreated 这两个方法会在客户端和服务端被调用。其他生命周期函数仅在客户端被调用。

一个完整的服务器请求到渲染的流程图如下:
在这里插入图片描述

通过上面的流程图可以看出,当一个客户端请求进入的时候,处理流程为:

  1. 服务端有通过nuxtServerInit这个命令执行(在Storeaction中),在这里接收到客户端请求的时候,可以将一些客户端信息(登录信息)存储到Store
  2. 使用了middleware中间件机制,中间件其实就是一个函数,会在每个路由执行之前去执行,在这里可以做很多事情,或者说可以理解为是路由器的拦截器的作用。
  3. validate执行的时候对客户端携带的参数进行校验
  4. asyncDatafetch进入正式的渲染周期,asyncData向服务端获取数据,把请求到的数据合并到Vue中的data中,

3.1 nuxtServerInit

适用于对store的操作

store/index.js

// 主模块

//state
export const state = () => ({
  bNav: false,
  bLoading: false
})

//mutations
export const mutations = {
  M_UPDATE_NAV(state, payload) {
    state.bNav = payload
  },
  M_UPDATE_LOADING(state, payload) {
    state.bLoading = payload
  }
}

// actions
export const actions = {
  nuxtServerInit(store, { app: { $cookies } }) {
    // 初始化东西到store里 token信息
    // console.log('nuxtServerInit', store, context)
    console.log('nuxtServerInit')
    let user = $cookies.get('user') ? $cookies.get('user') : {err:2, msg: '未登录', token: ''}
    store.commit('users/M_UPDATE_USER', user)
  }
}

// getters
export const getters = {
  getNav(state) {
    return state.bNav ? '显示' : '隐藏'
  }
}

3.2 middleware

定义中间件:

middleware/auth.js

export default ({ store, route, redirect, params, query, req, res }) => {
  // context 服务端上下文
  // 全局守卫业务
  console.log('middleware nuxt.config.js outside')

  // store状态树信息
  // route 一条目标路由信息
  //redirect 路由的强制跳转
  // params query 校验参数的合理性
  // console.log('全局守卫前置守卫')
  // redirect('/login')
}

使用:
nuxt.config.js
在这里使用相当于全局的路由守卫

  // middleware
  router: {
    middleware: 'auth',
  },

页面层级的中间件使用/定义

layouts/default.vue
或者
pages/index.vue

  export default {
    // middleware: 'auth', // 页面层级的中间件定义
    middleware({ store, route, redirect, params, query }) {
      console.log('middleware layouts inside')
      // store状态树信息
      // route 一条目标路由信息
      //redirect 路由的强制跳转
      // params query 校验参数的合理性
      // console.log('layouts守卫前置守卫')
      // redirect('/reg')
    },
  }
</script>

中间件执行顺序:

nuxt.config.js(配置文件级别) > layouts(布局文件级别) > pages(页面级别)

3.3 validate

在动态路由对应的页面组件中配置一个校验方法用于校验动态路由参数的有效性。

pages/index.vue

同步模式:

validate({ params, query }) {
  return true // 如果参数有效
  return false // 参数无效,Nuxt.js 停止渲染当前页面并显示错误页面
}

异步模式:

async validate({ params, query, store }) {
  // await operations
  return true // 如果参数有效
  return false // 将停止Nuxt.js呈现页面并显示错误页面
}

3.4 asyncData && fetch

asyncData:

在服务器端获取并渲染数据。可以在渲染组件之前异步获取数据。

fetch:

用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。

pages/index.vue

  // 读取数据 返回给组件
  asyncData(context) {
    // 异步业务逻辑 读取服务端的数据
    console.log('asyncData');
    return {
      b: 2
    };
  },
  // 读数据 返回vuex
  fetch({ store }) {
    // 异步业务逻辑 读取服务端的数据提交给vuex
    console.log('fetch');
  },

3.4.1 ansycData的promise方法

我们在pages下面新建一个文件,叫做ansyData.vue。然后写入下面的代码:

<script>
import axios from 'axios'
export default {
  data(){
     return {
         name:'hello World',
     }
  },
  asyncData(){
      return axios.get('https://api.myjson.com/bins/1ctwlm')
      .then((res)=>{
          console.log(res)
          return {info:res.data}
      })
  }
}
</script>

这时候我们可以看到,浏览器中已经能输出结果了。asyncData的方法会把值返回到data中。是组件创建(页面渲染)之前的动作,所以不能使用this.info,

3.4.2 return的重要性

一定要return出去获取到的对象,这样就可以在组件中使用,这里返回的数据会和组件中的data合并。这个函数不光在服务端会执行,在客户端同样也会执行。

3.4.3 ansycData的promise并发应用

async asyncData(context) {
  let [newDetailRes, hotInformationRes, correlationRes] = await Promise.all([
    axios.post('http://www.huanjingwuyou.com/eia/news/detail', {
      newsCode: newsCode
    }),
    axios.post('http://www.huanjingwuyou.com/eia/news/select', {
      newsType: newsType, // 资讯类型: 3环评资讯 4环评知识
      start: 0, // 从第0条开始
      pageSize: 10,
      newsRecommend: true
    }),
    axios.post('http://www.huanjingwuyou.com/eia/news/select', {
      newsType: newsType, // 资讯类型: 3环评资讯 4环评知识
      start: 0, // 从第0条开始
      pageSize: 3,
      newsRecommend: false
    })
  ])
  return {
    newDetailList: newDetailRes.data.result,
    hotNewList: hotInformationRes.data.result.data,
    newsList: correlationRes.data.result.data,
    newsCode: newsCode,
    newsType: newsType
  }
},

3.4.4 ansycData的await方法

当然上面的方法稍显过时,现在都在用ansyc…await来解决异步,改写上面的代码。

<script>
import axios from 'axios'
export default {
  data(){
     return {
         name:'hello World',
     }
  },
  async asyncData(){
      let {data}=await axios.get('https://api.myjson.com/bins/8gdmr')
      return {info: data}
  }
}
</script>

3.4.5 注意事项+生命周期:

  • asyncData 方法会在组件(限于页面组件)每次加载之前被调用
  • asyncData 可以在服务端或路由更新之前被调用
  • 第一个参数被设定为当前页面的上下文对象
  • Nuxt会将 asyncData 返回的数据融合到组件的data方法返回的数据一并返回给组件使用
  • 对于 asyncData 方式实在组件初始化前被调用的,所以在方法内饰没办法通过this来引用组件的实例对象

4. 配置文件

nuxt.config.js文件介绍:

const pkg = require('./package')
module.exports = {
  mode: 'universal',    //  当前渲染使用模式
  head: {       //  页面head配置信息
    title: pkg.name,        //  title
    meta: [         //  meat
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: pkg.description }
    ],
    link: [     //  favicon,若引用css不会进行打包处理
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  loading: { color: '#fff' },   //  页面进度条
  css: [    //  全局css(会进行webpack打包处理)
    'element-ui/lib/theme-chalk/index.css'  
  ],
  plugins: [        //  插件
    '@/plugins/element-ui'
  ],
  modules: [        //  模块
    '@nuxtjs/axios',
  ],
  axios: {},
  build: {      //  打包
    transpile: [/^element-ui/],
    extend(config, ctx) {       //  webpack自定义配置
    }
  }
}

4.1 配置IP和端口

开发中经常会遇到端口被占用或者指定IP的情况。我们需要在根目录下的nuxt.config.js里对server项进行配置。比如现在我们想把IP配置成0.0.0.0,端口设置3001。

/nuxt.config.js

  server: {
    port : 3001,
    host: '0.0.0.0'
  },

配置好后,我们在终端中输入npm run dev,然后你会看到服务地址改为了127.0.0.1:1000.

4.2 配置全局CSS

在开发多页项目时,都会定义一个全局的CSS来初始化我们的页面渲染,比如把padding和margin设置成0,网上也有非常出名的开源css文件normailze.css。要定义这些配置,需要在nuxt.config.js里进行操作。

比如现在我们要把页面字体设置为红色,就可以在assets/css/common.css文件,然后把字体设置为红色。

/assets/css/common.css

html{
    color:red;
}

/nuxt.config.js

  css:['~assets/css/normailze.css'],

设置好后,在终端输入npm run dev 。然后你会发现字体已经变成了红色。

4.3 配置webpack的loader

在nuxt.config.js里是可以对webpack的基本配置进行覆盖的,比如现在我们要配置一个url-loader来进行小图片的64位打包。就可以在nuxt.config.js的build选项里进行配置

nuxt.config.js

build: {
    loaders:[
      {
        test:/\.(png|jpe?g|gif|svg)$/,
        loader:"url-loader",
        query:{
          limit:10000,
          name:'img/[name].[hash].[ext]'
        }
      }
    ],
    /*
    ** Run ESLint on save
    */
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }

4.4 全局修改seo的head信息

nuxt.config.js文件中,修改title为HelloWorld:

 head: {
    title: 'HelloWorld',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'Nuxt.js project' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

修改后需要重启服务才可生效

5. 路由

Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。

5.1 基本路由

假设 pages 的目录结构如下

└─pages
    ├─index.vue
    └─user
      ├─index.vue
      ├─one.vue

那么,Nuxt.js 自动生成的路由配置如下:

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'
    }
  ]
}

5.2 页面跳转

  1. 不要写成a标签,因为是重新获取一个新的页面,并不是SPA
  2. 使用<nuxt-link to="/users"></nuxt-link>
  3. this.$router.push('/users')

5.3 动态路由

  • 在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
  • 获取动态参数{{$route.params.id}}

5.4 跳转路由传递参数并且取值

路由经常需要传递参数,我们可以简单的使用params来进行传递参数,我们现在向新闻页面(news)传递个参数,然后在新闻页面进行简单的接收。

(1)使用nuxt传递参数

<template>
  <div>
    <ul>
      <li><nuxt-link :to="`informa/${item.newsCode}-${item.newsType}`"></li>
    </ul>
  </div>
</template>

注意:name其实指向的是路由(文件夹或文件名),而路由死活区分大小写的 , 所以to后面区分大小写!!!建议文件夹都写成小写的。

(2)使用nuxt接收参数

async asyncData(context) {
    let newsCode = context.route.params.code.split('-')[0]
    let newsType = context.route.params.code.split('-')[1]
},

(3)使用this.$router.push的params传递参数

传递参数  -- this.$router.push({path: ' 路由 ', query: {key: value}})
参数取值  -- this.$route.query.key
 
注: 使用这种方式,传递参数会拼接在路由后面,出现在地址栏

(4)使用this.$router.push的params传递参数

传递参数  -- this.$router.push({name: ' 路由的name ', params: {key: value}})
参数取值  -- this.$route.params.key
 
注: 使用这种方式,参数不会拼接在路由后面,地址栏上看不到参数
 
注意: 由于动态路由也是传递params的,所以在 this.$router.push() 方法中 path不能和params一起使用,否则params将无效。需要用name来指定页面。

5.5 路由参数校验

Nuxt.js可以让你在动态路由对应的页面组件中配置一个validate方法用于校验动态路由参数的有效性。该函数有一个布尔类型的返回值,如果返回true则表示校验通过,如果返回false则表示校验未通过。

export default {
  // nuxt中使用validate方法进行路由参数校验,这个方法必须返回一个布尔值,为true表示校验通过,为false表示校验失败。注意validate不能写到methods属性中。
  validate(obj) {
    // console.log(obj);
    // return true
    return /^\d+$/.test(obj.params.id)
  }
}

5.6 嵌套路由

  1. 添加一个Vue文件,作为父组件
  2. 添加一个与父组件同名的文件夹来存放子视图组件
  3. 在父文件中,添加组件,用于展示匹配到的子视图

5.7 扩展路由

给不存在的路由定义一些访问的页面或组件

  router: {
    // 扩展路由
    extendRoutes (routes, resolve) {
      console.log(routes)
      routes.push({
        name: 'root',
        path: '/index',
        component: resolve(__dirname, 'pages/index.vue')
      })
    }
  },

5.7 错误路由

通过编辑 layouts/error.vue 文件来定制化错误页面.

5.8 路由守卫

5.8.1 前置路由守卫

依赖中间件middleware或者plugin插件

5.8.2 后置路由守卫

使用vue的 beforeRouteleave钩子

plugins/router.js

/* 插件全局守卫 */
export default ({ app, redirect, params, query, store }) => {
  console.log('插件')
  // app == vue实例
  // redirect 跳转函数
  app.router.beforeEach((to, from, next) => {
    // 全局前置守卫 -- 插件
    // next(true)/false  next('/login')是错误的 和vue不一样
    // console.log('插件配置,', to)
    // if (to.name === 'login' || to.name === 'reg') {
    //   next()
    // } else {
    //   redirect({ name: 'login' })
    // }
    next()
  })

  // app.router.afterEach((to, from) => {
  //   console.log('插件全局后置守卫')
  // })
}

nuxt.config.js

  plugins: [
    '~/plugins/router',
  ],

6. Nuxt的路由动画效果

路由的动画效果,也叫作页面的更换效果。Nuxt.js提供两种方法为路由提供动画效果,一种是全局的,一种是针对单独页面制作。

6.1 全局路由动画

全局动画默认使用page来进行设置,例如现在我们为每个页面都设置一个进入和退出时的渐隐渐现的效果。我们可以先在根目录的assets/css下建立一个normailze.css文件。

(1)添加样式文件

/assets/css/normailze.css(没有请自行建立)

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

(2)文件配置

然后在nuxt.config.js里加入一个全局的css文件就可以了。

css:['assets/css/main.css'],

这时候在页面切换的时候就会有2秒钟的动画切换效果了,但是你会发现一些页面是没有效果的,这是因为你没有是组件来制作跳转链接。你需要进行更改。

比如我们上节课作的动态路由新闻页,你就需要改成下面的链接。

<li><nuxt-link :to="{name:'news-id',params:{id:123}}">News-1</nuxt-link></li>

改过之后你就会看到动画效果了。

6.2 单独设置页面动效

想给一个页面单独设置特殊的效果时,我们只要在css里改变默认的page,然后在页面组件的配置中加入transition字段即可。例如,我们想给about页面加入一个字体放大然后缩小的效果,其他页面没有这个效果。

(1)在全局样式assets/main.css 中添加以下内容

.test-enter-active, .test-leave-active {
    transition: all 2s;
    font-size:12px;
}
.test-enter, .test-leave-active {
    opacity: 0;
    font-size:40px;
}

(2)然后在about/index.vue组件中设置

export default {
  transition:'test'
}

这时候就有了页面的切换独特动效了。

总结:在需要使用的页面导入即可。

7. Nuxt的默认模版和默认布局

在开发应用时,经常会用到一些公用的元素,比如网页的标题是一样的,每个页面都是一模一样的标题。这时候我们有两种方法,第一种方法是作一个公用的组件出来,第二种方法是修改默认模版。这两种方法各有利弊,比如公用组件更加灵活,但是每次都需要自己手动引入;模版比较方便,但是只能每个页面都引入。

7.1 默认模板

Nuxt为我们提供了超简单的默认模版订制方法,只要在根目录下创建一个app.html就可以实现了。现在我们希望每个页面的最上边都加入“ 学习nuxt.js” 这几个字,我们就可以使用默认模版来完成。

app.html中:

<!DOCTYPE html>
<html lang="en">
<head>
   {{ HEAD }}
</head>
<body>
    <p>学习nuxt.js</p>
    {{ APP }}
</body>
</html>

这里的{{ HEAD }}读取的是nuxt.config.js里的信息,{{APP}} 就是我们写的pages文件夹下的主体页面了。需要注意的是HEAD和APP都需要大写,如果小写会报错的。

注意:如果你建立了默认模板后,记得要重启服务器,否则显示不会成功;但是默认布局是不用重启服务器的。

7.2 默认布局

默认模板类似的功能还有默认布局,但是从名字上你就可以看出来,默认布局主要针对于页面的统一布局使用。它在位置根目录下的layouts/default.vue。需要注意的是在默认布局里不要加入头部信息,只是关于标签下的内容统一订制。

需求:我们在每个页面的最顶部放入“学习nuxt.js” 这几个字,看一下在默认布局里的实现。

<template>
  <div>
    <p>学习nuxt.js</p>
    <nuxt/>
  </div>
</template>

这里的就相当于我们每个页面的内容,你也可以把一些通用样式放入这个默认布局里,但会增加页面的复杂程度。

总结:要区分默认模版和默认布局的区别,模版可以订制很多头部信息,包括IE版本的判断;模版只能定制里的内容,跟布局有关系。在工作中修改时要看情况来编写代码。

7.3 动态更改nuxt layout

  1. 在客户端动态更改nuxt的layout布局
    可以使用nuxt的setLayout方法:
<button @click="$nuxt.setLayout('h5')">
  1. 在服务端动态更改nuxt的layout布局
    可以使用nuxt提供的上下文context来动态生成当前页面的layout:
  layout(context) {
    console.log(context)
    if(....){
    	return 'pc';
    }else{
		return 'h5';
	}
  },

8. axios && 跨域

nuxt.config.js

  // 跨域
  axios: {
    proxy: true, // 开启跨域行为
    // prefix: '/api', //baseUrl
  },
  proxy: { // 代理
    '/api/': {
      target: 'http://localhost:3001', //代理转发地址
      changeOrigin: true,
      pathRewrite: {
        // '^/api': ''
      }
    }
  },
  	//为防止重复打包
	module.exports = {
	  build: {
	    vendor: ['axios']
	  }
	}

pages/index.vue

   async fetch({ $axios, store, error }) {
     let res = await $axios({
       url: 'xxx',
       params: {
         _limit: 1
       }
     })
     res.data && store.commit('home/M_UPDATE_HOME',{
       err: 0,
       data: res.data
     })
   }

9. plugins插件

在运行 Vue.js 应用程序之前执行 js 插件。这在您需要使用自己的库或第三方模块时特别有用。

注册一个全局的axios请求和返回拦截器插件

plugins/axios.js

// 拦截器

export default ({ $axios, redirect, route, store }) => {
  // 基本配置
  $axios.defaults.timeout = 10000;

  //请求时拦截
  $axios.onRequest(config => {
    console.log('发送请求时的拦截')
    // config.header.token = '加token'
	config.headers.token = store.state.user.token
    return config
  })

  //响应拦截
  $axios.onResponse(res => {
    console.log('响应时的拦截')
    // if (res.data.err === 2 && route.fullPath !== '/login') {
    //   redirect('/login?path=' + route.fullPath)
    // }
    return res
  })


  //错误处理
  $axios.onError(error => {
    const code = parseInt(error.response && error.response.status)
    if (code === 400) {
      redirect('/400')
    }
  })

}

nuxt.config.js

  // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
  plugins: [
    {
      src: '~/plugins/axios',
      ssr: true // 开启服务端渲染
    },
  ],

10. Vuex

数据和方法的定义:

store/index.js

// 主模块

//state
export const state = () => ({
  bNav: false,
  bLoading: false
})

//mutations
export const mutations = {
  M_UPDATE_NAV(state, payload) {
    state.bNav = payload
  },
  M_UPDATE_LOADING(state, payload) {
    state.bLoading = payload
  }
}

// actions
export const actions = {
  nuxtServerInit(store, { app: { $cookies } }) {
    // 初始化东西到store里 token信息
    // console.log('nuxtServerInit', store, context)
    console.log('nuxtServerInit')
    let user = $cookies.get('user') ? $cookies.get('user') : {err:2, msg: '未登录', token: ''}
    store.commit('users/M_UPDATE_USER', user)
  }
}

// getters
export const getters = {
  getNav(state) {
    return state.bNav ? '显示' : '隐藏'
  }
}

store/home.js

export const state = () => ({
  err: 1,
  data: {}
})

export const mutations = {
  M_UPDATE_HOME(state, payload) {
    state.err = payload.err
    state.data = payload.data
  }
}

export const actions = {
  A_UPDATE_HOME({ commit, state }, payload) {
    // 异步处理
    commit('M_UPDATE_HOME', { err: 0, data: {title: 'home模块 actions所传递的数据'} })
  }
}

store/users.js

export const state = () => ({
  err: 1,
  msg: '未登录',
  token: '',
  data: {}
})

export const mutations = {
  M_UPDATE_USER(user, payload) {
    state.err = payload.err
    state.msg = payload.msg
    state.data = payload.data
    state.token = payload.token
  }
}

export const actions = {
  A_UPDATE_USER({commit, user}, payload) {
    // 异步业务
    commit('M_UPDATE_USER', payload)
  }
}

数据和方法使用:

pages/index.vue

<script>
import { mapActions, mapGetters, mapState, mapMutations } from 'vuex';
export default {
  methods: {
    getStore() {
      //   this.$store.dispatch('users/A_UPDATE_USER', {
      //   err:0,
      //   msg: '登录成功',
      //   token: '假token',
      //   data: {
      //     title: 'user模块的actions提交出来的数据'
      //   }
      // })

      // this.$store.commit('users/M_UPDATE_USER', {
      //   err: 0,
      //   msg: '登录成功',
      //   token: '假token',
      //   data: {
      //     title: 'user模块的mutations提交出来的数据'
      //   }
      // });

      // this.A_UPDATE_USER({
      //   err: 0,
      //   msg: '登录成功',
      //   token: '假token',
      //   data: {
      //     title: 'user模块的actions提交出来的数据'
      //     }
      //   }
      // )

      this.M_UPDATE_USER({
        err: 0,
        msg: '登录成功',
        token: '假token',
        data: {
          title: 'user模块的mutations提交出来的数据'
         }
        }
      )

    },
    ...mapActions('users', ['A_UPDATE_USER']),
    ...mapMutations('users', ['M_UPDATE_USER'])
  },
  computed: {
    ...mapGetters(['getNav']),
    ...mapState(['bNav']),
    ...mapState('users', ['data'])
    // ...mapState({
    //   home: state => state.home.data // 直接使用home即可
    // })
  },
   async fetch({ $axios, store, error }) {
     let res = await $axios({
       url: 'xxx',
       params: {
         _limit: 1
       }
     })
     res.data && store.commit('home/M_UPDATE_HOME',{
       err: 0,
       data: res.data
     })
   }
};
</script>

11. UI框架的引入

插件中引入:

plugins/element-ui.js

import Vue from 'vue'
/整体引入
import ElementuI from 'element-ui'
vue.use(ElementUI)
//按需引入全局使用
import {Button} from 'element-ui'
vue.use(Button)

配置文件
nuxt.config.js

css:[
   'element-ui/lib/theme-chalk/index.css'
],
plugins: [
    {
    src: "~/plugins/element-ui",
    ssr:true//不支持ssr的插件只会在客户端运行不要给true
    //mode: 'server'//client// v2.44
    }
],
build:{
    transpile:[ /^element-ui/] 
}

这时就可以在pages中写页面进行element-ui的测试了

12. mixin混入定义全局方法

nuxt.config.js

plugins:[  //配置插件
	'~/plugins/mixins'
]

plugins/mixins.js

import Vue from 'vue'
let show = ()=>console.log('全局方法')
Vue.propotype.$show = show  //服务端钩子内部不可以使用,this不会执行vue实例

// 全局锅过滤器
import * as filters from '../assets/js/filter.js'
Object.keys(filters).forEach(key=>Vue.filter(key, filters[key]))

assets/js/filter.js

export function filerzero(n) {
  return n < 10 ? '0'+n : ''+n
}

export const date = time => {
  let d = new Date()
  d.setTime(time)
  let year = d.getFullYear()
  let month = d.getMonth()+1
  let date = d.getDate()
  let hour = d.getHours()
  let min = d.getMinutes()
  let sec = d.getSeconds()
  return `${year}${filerzero(month)}${filerzero(date)}${filerzero(hour)}:${min}:${sec}`
}

组件中使用:

pages/login.vue

mouted(){
	this.$show() //打印全局方法
}

13. Nuxt的错误页面和个性meta设置

当用户输入路由错误的时候,我们需要给他一个明确的指引,所以说在应用程序开发中404页面是必不可少的。Nuxt.js支持直接在默认布局文件夹里建立错误页面。

13.1 建立错误页面

在根目录下的layouts文件夹下建立一个error.vue文件,它相当于一个显示应用错误的组件。

<template>
  <div>
      <h2 v-if="error.statusCode==404">404页面不存在</h2>
      <h2 v-else>500服务器错误</h2>
      <ul>
          <li><nuxt-link to="/">HOME</nuxt-link></li>
      </ul>
  </div>
</template>
 
<script>
export default {
  props:['error'],
}
</script>

代码用v-if进行判断错误类型,需要注意的是这个错误是你需要在<script>里进行声明的,如果不声明程序是找不到error.statusCode的。

这里我也用了一个<nuxt-link>的简单写法直接跟上路径就可以了。

13.2 个性meta设置

页面的Meta对于SEO的设置非常重要,比如你现在要作个新闻页面,那为了搜索引擎对新闻的收录,需要每个页面对新闻都有不同的title和meta设置。直接使用head方法来设置当前页面的头部信息就可以了。我们现在要把New-1这个页面设置成个性的meta和title。

  1. 我们先把pages/news/index.vue页面的链接进行修改一下,传入一个title,目的是为了在新闻具体页面进行接收title,形成文章的标题。

/pages/news/index.vue

<li><nuxt-link :to="{name:'news-id',params:{id:123,title:'nuxt.com'}}">News-1</nuxt-link></li>
  1. 第一步完成后,我们修改/pages/news/_id.vue,让它根据传递值变成独特的meta和title标签。
<template>
  <div>
      <h2>News-Content [{{$route.params.id}}]</h2>
      <ul>
        <li><a href="/">Home</a></li>
      </ul>
  </div>
</template>
 
<script>
export default {
  validate ({ params }) {
    // Must be a number
    return /^\d+$/.test(params.id)
  },
  data(){
    return{
      title:this.$route.params.title,
    }
  },
//独立设置head信息
  head(){
      return{
        title:this.title,
        meta:[
          {hid:'description',name:'news',content:'This is news page'}
        ]
      }
    }
}
</script>

注意:为了避免子组件中的meta标签不能正确覆盖父组件中相同的标签而产生重复的现象,建议利用 hid 键为meta标签配一个唯一的标识编号。

14 静态资源和打包

14.1 静态资源

(1)直接引入图片
在网上任意下载一个图片,放到项目中的static文件夹下面,然后可以使用下面的引入方法进行引用

<div><img src="~static/logo.png" /></div>

“~”就相当于定位到了项目根目录,这时候图片路径就不会出现错误,就算打包也是正常的。

(2)CSS引入图片
如果在CSS中引入图片,方法和html中直接引入是一样的,也是用“~”符号引入。

<style>
  .diss{
    width: 300px;
    height: 100px;
    background-image: url('~static/logo.png')
  }
</style>

这时候在npm run dev 下是完全正常的。

14.2 打包

用Nuxt.js制作完成后,你可以打包成静态文件并放在服务器上,进行运行。

在终端中输入:

npm run generate

然后在dist文件夹下输入live-server就可以了。

总结:Nuxt.js框架非常简单,因为大部分的事情他都为我们做好了,我们只要安装它的规则来编写代码。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值