nuxt从零搭建登录鉴权asyncData异步数据

nuxt_ehr

初始化项目

npx create-nuxt-app nuxt_ehr

请添加图片描述

npm run dev

运行 http://localhost:3000/

创建路由

  • pages 目录结构自动生成模块的路由配置,更复杂的路由配置可以查看路由文档
  1. 清空 pages/index.vue 内容,并创建 pages/info.vue 文件(随便写点内容此时一下路由显示)

当前结果:此时可以手动切换 //info 两个路径
下一步:创建全局样式文件

创建全局样式文件

  1. 创建样式文件 assets/css/common.less
  2. nuxt.config.js 配置文件中引入全局样式内容 css: ['@/assets/css/common.less']
  3. 安装依赖 npm i less-loader@6
  4. nuxt.config.js 配置 less-loader
    build: {
          
          
      loaders: {
          
          
        less: {
          
          
          lessOptions: {
          
          
            javascriptEnabled: true
          }
        }
      }
    }
    
  5. 创建 assets/css/vars.less,改变主题颜色,同时增加主题颜色样式选择器(引入组件库的.less 样式文件并覆盖其主题变量)
  6. npm i @nuxtjs/style-resourcesvars.less 文件中定义了用于覆盖主题变量的@primary-color,如果页面组件中想要用这个变量需要 @import 这个文件,而 @nuxtjs/style-resources 这个库就解决了这个麻烦的步骤,无需@import 就可以直接读取变量作为全局变量使用)
  7. nuxt.config.js 文件增加配置内容
    buildModules: [
      '@nuxtjs/style-resources'
    ],
    styleResources: {
          
          
      less: '@/assets/css/vars.less'
    },
    

更多样式配置可以查看The css property
更多关于 buildModulesmodules 的配置以及不同点可以查看 Modules directory

当前结果:可以在 common.less 中添加全局样式内容,在 vars.less 中定义的样式变量或者覆盖组件库默认主题变量,在页面组件 style 中可以直接使用这些变量
下一步:提取全局菜单结构,并可以通过菜单切换路由显示

创建全局菜单

菜单属于公共部分,路由切换不会改变菜单内容(除了样式变化)

  • 程序的默认布局是 layouts/default.vue (如果不修改可以没有这个文件),可通过添加 layouts/default.vue 文件来扩展应用的默认布局(别忘了在布局文件中添加 <Nuxt/> 组件用于显示页面的主体内容,即 <Nuxt /> 才是显示页面组件内容的位置)
  • layouts 目录中的每个文件 (顶级) 都将创建一个可通过页面组件中(pages 下组件)的 layout 属性访问的自定义布局(不指定就是默认布局 default
  • components 文件夹中的组件会自动注册成全局组件
  1. 创建 layouts/default.vue 布局文件,并修改内容(插入全局菜单组件)
  2. 清空 components 下的所有全局组件内容
  3. 创建全局菜单组件 components/app-header.vue 文件

当前结果:访问 / 可以看到 components/app-header.vuepages/index.vue 内容的显示
下一步:登录获取当前登录名以及菜单内容

鉴权逻辑

token校验 && 状态持久化思路:
登录时,同步 vuex && cookie,强制刷新后,nextServerInit 取出 cookie,并同步 vuex, axios 拦截去读取 vuex。

  • store 文件夹下新建文件,nuxt 就会自动导入 Vuex,且添加 store 选项到 vue 实例上
  • nuxtServerInit 可以接收服务端的一些数据(如登录信息),从而将其保存在状态管理中,客户端就可以从状态管理中去获取
  • 只有主模块(store/index.js) 才能接收 nuxtServerInit action
  1. 创建状态管理主模块 store/index.js (此时 auth.js 函数中自动多了一个状态树参数 store)并通过 nuxtServerInit 来获取并保存当前登录信息到状态管理树中
  2. 创建用户信息状态管理文件 store/user.js (通过 store.state.user.xxx来获取对应的状态值)
  3. 创建鉴权中间件 middleware/auth.jsauth.js 的判断逻辑为当前用户是否登录(store.state.user.token 是否有值),没登录需要跳转至登录页
  4. nuxt.config.js 配置 router: {middleware: 'auth'},每次路由变化都会经过鉴权判断是否登录
  5. 创建登录页面 pages/login.vue

nuxt 有三个地方可以设置中间件,也可以设置异步中间件,路由中间件 will be called for every route change,关于中间件更多详细设置可以查看 middleware
nuxt中配置store可以查看Store directory

当前结果:因为一直没有登录,所以 token 一直是空,会一直在登录页面
下一步:完成接口请求配置,实现登录保存用户信息进入首页

登录登出逻辑

  1. 使用node创建一个本地服务器( server 为服务器内容)模拟后端,用于登录请求或后端数据获取
  2. npm i @nuxtjs/axios 并在 nuxt.config.js 中配置 modules: ['@nuxtjs/axios'] (此时在页面组件中可以通过 this.$axios.xxx('/api/kkk') 发送请求了)
  3. npm i @nuxtjs/proxy(由于mock的服务器端口跟nuxt项目端口不同,此时请求数据会有跨域问题),在 nuxt.config.js 中配置
    modules: [
      '@nuxtjs/axios',
      '@nuxtjs/proxy'
    ],
    axios: {
          
          
      proxy: true,
      credential: true
    },
    proxy: {
          
          
      '/api/': {
          
          
        target: 'http://localhost:3333/',
        pathRewrite: {
          
          
          '^/api/': '/',
          changeOrigin: true
        }
      }
    }
    
  4. 拦截请求统一处理,创建处理文件 plugins/request.js 并在 nuxt.config.js 中配置 plugins: [..., '@/plugins/request']
  5. npm i cookie-universal-nuxt 并在 nuxt.config.jsmodules 中加入配置,使得上下文中可以获取到 $cookie
  6. 登录成功后存储用户信息到 cookie 和 vuex 中
  7. 退出登录时候清除cookie 和 vuex的值

页面组件 asyncData 获取异步数据

  • asyncData 方法会在组件(限于页面组件)每次加载之前被调用,也因为如此,在该方法内是没有办法通过 this 来引用组件的实例对象的
  • Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件
// pages/index.vue
data() {
    
    
  return {
    
    
    
  }
},
async asyncData({
     
     $axios}) {
    
    
  const {
    
     result } = await $axios.get('/api/home/userinfo')
  let _userInfo = [
    {
    
    label: '姓名:', key: 'name', value: ''},
    {
    
    label: '部门:', key: 'apartment', value: ''},
    {
    
    label: '岗位级别:', key: 'level', value: ''},
    {
    
    label: '名片岗位:', key: 'business', value: ''},
    {
    
    label: '直接上级:', key: 'supervisor', value: ''},
    {
    
    label: '入职日期:', key: 'start', value: ''}
  ]
  for(let key in result.user_info) {
    
    
    const _idx = _userInfo.findIndex(item => item.key === key)
    _userInfo[_idx].value = result.user_info[key]
  }
  return {
    
    
    userPhoto: result.user_photo,
    userInfo: _userInfo
  }
},

更多使用方法和配置可以查看异步数据 asyncData

改写loading样式

默认 loading 是头部黑色进度条的样式,下面重写 loading 样式

  • loading 组件需要遵循给定约定,即 start 为开始的样式,finish 为结束时的样式
  1. 创建 components/loading.vue 文件
  2. nuxt.config.js 配置 loading: '@/components/loading'

改写error页面

  1. 创建 layouts/error.vue 文件,传入约定式参数 props: ['error']

代码

相关代码可以直接查看 代码

猜你喜欢

转载自blog.csdn.net/weixin_43443341/article/details/126975015