周亚博的个人博客

  • 首页
  • 盛夏光年
  • 陪风去荡
  • 布响丸啦
我频繁记录着 因为生活值得
  1. 首页
  2. 盛夏光年
  3. 正文

nuxt笔记

2022-09-22 213点热度 0人点赞 0条评论

Nuxt.js中文官网

1、CSRvsSSR

什么是CSR(Client-Side Render)

客户端渲染,用户发送请求返回页面,此时只是一个模板页面。通过接口请求数据使用模板引擎渲染页面,将渲染的内容进行展示。

什么是SSR(Server-Side Render)

用户请求页面,后端获取数据,在后端将页面进行渲染,将完整的页面结构返回给浏览器

  • 客户端渲染可以减轻服务端的压力,实现前后端分离开发,SEO优化较差
  • 服务端渲染有较好的SEO优化,但是对服务器性能有较高的要求

2、Nuxt框架

Nuxt就是基于Vue的一个应用框架,采用服务端渲染,让SPA应用也可以拥有SEO

直接安装nuxt

npx create-nuxt-app <project-name>
# 注意:在NPM版本5.2.0默认安装了npx,在命令行窗口输入npm --version可查看当前版本号

通过vue-cli创建nxt+starter-template模板

vue init nuxt-community/starter-template <project-name>

image-20220921223250020

创建nuxt+express模板

它比基础模板多出一个api文件夹

vue init nuxt/express <project-name>

3、生命周期

nuxt生命周期

nuxtServerInit
/**服务器初始化加载时候调用
 * /store/index.js
*/
export const actions = {
  nuxtServerInit(store,context){
    // 初始化东西到store中
  }
}
middleware
/**配置中间件
 * /nuxt.config.js
*/
module.exports = {
  router:{
    middleware:'auth'
  }
}

/**
 * 方法一:在middleware文件夹中定义
 * /middleware/auth.js 
*/
export default (content)=>{
  // 可以接受服务端上下文信息({store,route,redirect,params,query,req,res})
  // 可以进行全局守卫任务
}

/**
 * 方法二:在布局文件夹layouts中定义
 * /layouts/default.vue
*/
export default {
    middleware:'auth',  // 定义在外部的中间件
  middleware(){
    // 定义在内部的中间件
  }
}

/**
 * 方法三:在页面文件夹pages中定义
 * /pages/index.vue
*/
export default {
    middleware:'auth',  // 定义在外部的中间件
  middleware(){
    // 定义在内部的中间件
  }
}

所有的中间件都可以获取上下文信息参数

总结执行顺序:nuxt.config.js文件 ——> 布局 ——> 页面

validata
/**用于校验进入页面的参数,所以配置在pages文件夹中
 * /pages/index.vue
*/

<script>
export default {
    validate({params,query}){
    // 进行参数有效性的校验
    return true // 校验通过
  }
} 
</script>

在布局层(layouts)创建error.vue文件作为错误页面,捕获错误

该页面名称不可自定义,通过props:['error']接收错误信息


asyncData和fetch
/** 进入页面前的异步请求
 * /pages/index.vue
*/
<script>
export default {
    asyncData(context){
        // asyncData读取数据合并到目标组件
        return { a:1 }
    },
    fetch({$axios,store,error}){
        // fetch读取数据通过mutations修改数据状态
        store.commit('home/M_UPDATE_HOME',这是要传递额数据)
    }
} 
</script>
beforeCreate
created

以上两个生命周期同时运行在客户端和服务端


beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed

都是运行在客户端的生命周期,客户端不存在组件缓存,所以没有激活和失活两个钩子


总结:

  • 客户端执行的生命周期中可以获取window对象和this
  • 服务端可以获取上下文环境

4、路由

约定的形式

在pages文件夹中新建不同的页面,在layouts文件夹中使用<nuxt/>作为路由展示区,类似vue中的<router-view/>

  • 该文件夹下的所有vue文件都会被认为是一级路由目标文件,无需配置
  • 如果需要二级路由,则需要在pages文件下新建文件夹实现二级路由

声明式跳转

<!-- 直接跳转到某个页面 -->
<nuxt-link to='/'>首页</nuxt-link>
<!-- 
    目的:跳转到携带参数的动态路由 /goods/1?a=1
    实现:goods文件夹下新建 _id.vue 文件作为动态路由的文件 id是动态的
    注意:参数params的key对应文件名
-->
<nuxt-link :to={name:'goods-id',params:{id:1},query:{a:1}}>
  首页
</nuxt-link>

扩展路由配置
/*
* 在/nuxt.config.js文件中
**/

module.exports = {
  router:{
    extendRoutes(routes,resolve){
      // 配置一个index路由
      routes.push({
        name:'index',
        path:'/index',
        component:resolve(__dirname,'pages/index.vue')
      })
    }
  }
}
路由守卫

路由守卫可以在中间件和插件中实现

前置守卫

1、全局守卫

  • nuxt.config指向middleware
/** 配置中间件
 * /nuxt.config.js
*/
module.exports = {
  router:{
    middleware:'auth'
  }
}

/**
 * /middleware/auth.js 
*/
export default ({store,route,redirect,params,query,req,res})=>{
  // 可以接受服务端上下文信息({store,route,redirect,params,query,req,res})
  // 配置全局守卫
  redirect('/login')
}
  • layouts中定义中间件
// 类似vue中的App根组件,进行路由拦截
export default {
    middleware:'auth', // 直接指向middleware
  middleware({store,route,redirect,params,query,req,res}){
    // 或者直接在这里实现业务逻辑
    redirect('/login')
  }
}

2、组件独享守卫

  • 在pages文件夹中通过middleware实现组件独享守卫(前置)

后置beforeRouteLeave钩子

后置守卫

  • 在pages页面中通过vue中beforeRouteLeave实现独享后置守卫
    beforeEouteLeave((to,from,next)=>{
    // 组件独享后置守卫
    })
    

通过插件也可以实现前置守卫和后置守卫

  • 在plugins文件夹下新建routers.js文件

  • 在nuxt.config.js文件plugins配置项中配置该文件

    // ~表示当前项目,直接从根目录查找
    plugins:[
    '~/plugins/router'
    ]
    
  • 在文件中实现路由守卫
    /* router.js */
    export default ({app,redirect,params,query,store})=>{
    app.router.beforeEach((to,from,next)=>{
      // 前置守卫,只能通过redirect跳转,而不能使用next()跳转
    })
    app.router.afterEach((to,from)=>{
      // 后置守卫,没有next
    })
    }=
    

5、数据交互

模块安装
@nuxtjs/axios、@nuxtjs/proxy
模块配置
// nuxt.config.js
modules:[
    '@/nuxtjs/axios'    // 只需要添加axios
]
模块使用
exoprt default {
    async asyncData({axios}){
    let res = awaitaxios({url:'请求地址'})
    console.log(res)
    // 将数据合并到组件内部
    return {
      title:res.data.title
    }
  },
  async fetch({$axios}){
    // 这里可以使用vuex管理数据
  }
}
跨域配置
// nuxt.config.js
axios:{
  proxy:true,        // 开启代理
  perfix:'/api'  // 请求前缀(可选)
},
proxy:{
  '/api':{
    target:'代理的地址',
    pathRewrite:{
      '^api':''
    }
  }
}
请求拦截
// nuxt.config.js文件
plugins:[
  {
    src:'~/plugins/axios.js',
    ssr:true    // 服务端渲染
  }
]
-----------------------------------------------------------------
// plugins/axios.js文件
export default function({axios,redirect,route,store}){
  // 基本配置axios.defaults.timeout = 1000
  // 请求拦截
  axios.onRequest(config=>{
    config.headers.token=''
    return config
  })
  // 响应拦截axios.onResponse(res=>{
    // 响应码判断
    return res
  })
  // 错误处理
  $axios.onError(error=>{
    return error
  })
}

6、自定义Loading

// nuxt.config.js
module.exports = {
  // 1、配置实现加载时顶部出现加载条
  loading:{
    color: '#399',
    height: '3px'
  }
  // 2、自定义loading
  loading: '~/components/loading.vue'
}
<!-- loading.vue -->
<template>
    <div v-if="loading">loading...</div>
</template>
<script>
    export default {
    data:()=>({
      loading:false
    }),
    methods:{
      start(){
        this.loading = true
      },
      finish(){
        this.loading = false
      }
    }
  }
</script>

7、状态管理

vuex的使用
/**
 * /store/index.js
*/
// 暴露出一个对象
export const state=()=>({
  a:1
})

export const getters = {}

export const mutations = {}

export const actions = {
  nuxtServerInit(store,context){
    // 初始化东西到store中
  }
}
模块化使用

对不同页面的数据进行不同文件的管理,直接创建不同的文件,代码格式相同

访问的时候需要说明模块名称

this.$store.dispatch('user/UPDATE_USER')

vuex的辅助函数

mapState | mapGetters | mapMutations | mapActions

methods:{
  ...mapMutations('user',['M_UPDATE_USER']),
  ...mapActions('user',['A_UPDATE_USER'])
},
computed:{
  // 获取主模块数据
  ...mapGetters(['getNav']),
  ...mapState(['nav'])
  // 获取user模块数据
    ...mapState('user',['userName']),
  // 如果数据冲突,可以通过对象形式获取数据,实现名称自定义
  ...mapState({
    homeName:state=>state.userName
  })
}
状态持久化

登录状态保持的步骤:

  • 登录时候,token存入vuex + 持久化存储
  • 刷新后,通过nuxtServerInit读取持久化token,同步vuex
  • axios拦截器读取vuex,将token写入请求头

8、使用elementUI

插件文件夹pluigns下新建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

module.export = {
  css:[
    'element-ui/lib/theme-chalk/index.css'
  ]
}

在nuxt.config.js中配置插件

module.export = {
  plugins:[
    {
      src:'~/plugins/element-ui',
      // 不支持服务端渲染的设置为false
      ssr:true
    }
  ]
}

9、全局定义

通过插件实现全局的定义,在plugins/mixins.js中编写全局定义

全局方法
import Vue from 'vue'
let show = ()=>{ // 这是一个全局方法 }
// 将方法挂载到Vue原型上,服务端内部的钩子不能使用
 Vue.prototype.$show = show
全局过滤器

如果都将全局定义写在一个文件中,数量过于庞大,但是因为nuxt文件目录使用的特殊性,故将文件定义在资源目录assets中

/**
 * /assets/js/filters.js    
*/
export function fillZero(n){
  return n<10 ? `0${n}` : n
}
--------------------------------------
/* 导入
 * /plugins/mixins.js
*/
import * as filters from '../assets/js/filters'
// 遍历结果绑定到Vue过滤器中
Object.keys(filters).forEach(key=>Vue.filter(key,filters[key]))
全局指令

同上,编写指令方法,导入后通过Vue.directive('指令名称',指令方法)使用

全局组件

耗费一点内存,但是不需要逐个导入组件

引入组件,通过Vue.component('组件名称')注册到全局


除此之外还有全局样式等

10、meta信息注入

nuxt.config.js配置head属性

module.exports = {
  head:{
    title:'网站标题',
    meta:[
      { charset:'utf-8' },
      { name:'viewport',content:'width=device-width,initial-scale=1'},
      // 避免子组件中的 meta 标签不能正确覆盖父组件中相同的标签而产生重复的现象
      // 建议利用 hid 键为 meta 标签配一个唯一的标识编号
      { hid:'description',name:'description',content:'项目描述信息' }
    ],
    link:[
      {rel:'icon',type:'image/x-icon',href:'/favicon.ico'}
    ]
  }
}

对页面单独配置,在页面文件中使用head函数

exports default {
    head(){
    return {
      meta:[]
    }
  }
}
标签: nuxt 服务端渲染
最后更新:2022-09-24

粥呀Bo

所谓惊喜,就是苦苦等候的兔子来了,后面却跟着狼

点赞
< 上一篇
下一篇 >

文章评论

取消回复
目录
  • 1、CSRvsSSR
  • 2、Nuxt框架
  • 3、生命周期
    • nuxtServerInit
    • middleware
    • validata
    • asyncData和fetch
    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • beforeDestroy
    • destroyed
  • 4、路由
    • 约定的形式
    • 扩展路由配置
    • 路由守卫
  • 5、数据交互
    • 模块安装
    • 模块配置
    • 模块使用
    • 跨域配置
    • 请求拦截
  • 6、自定义Loading
  • 7、状态管理
    • vuex的使用
    • 模块化使用
    • vuex的辅助函数
    • 状态持久化
  • 8、使用elementUI
  • 9、全局定义
    • 全局方法
    • 全局过滤器
    • 全局指令
    • 全局组件
  • 10、meta信息注入

COPYRIGHT © 2022 zhouyaker.cn. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

陕ICP备2022009272号