nuxt项目开发


nuxt项目开发

  • nuxt 项目开发
    • 先安装一下,按照nutx文档来就可以
    • 样式预处理器
    • 接口管理
    • 路由鉴权
    • nuxt使用vuex和nuxtServerInit
    • 打包后部署

nuxt 项目开发

因为项目需要,使用到nuxt,找了很多资料,然后抄袭 淮城一只猫这位大佬的笔记做的,重复的东西我就不写啦,只是把自己应用中遇到的问题,记录一下
还写了一个小demo会放到码云上,接口是真实的,大佬们不要搞我哈,求放过

先安装一下,按照nutx文档来就可以

1
2
npx create-nuxt-app <项目名>
或者yarn create nuxt-app <项目名>

在这里插入图片描述

样式预处理器

1
2
npm install -D sass-loader node-sass  // 安装SASS预处理器
npm install -s @nuxtjs/style-resources   // 安装nuxt.js 样式模块(需要在页面中注入一些变量和mixin而不必每次都导入它们时 )

在nuxt.config.js添加:

1
2
3
4
5
6
7
8
export default {
  modules: [
    '@nuxtjs/style-resources'
  ],
  styleResources: {
    scss: './assets/style/variables.scss'
  }
}

然后就可以随处直接使用定义过的变量或函数

接口管理

跟那位大佬有所不同 我这边操作token用的是cookie-universal-nuxt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
export default function ({ $axios, redirect, route, app, $router }) {
  $axios.onRequest((config) => {  //可以在里面设置一下请求头,根据自己项目需要配置
  //下面是我设置的token
    const token = app.$cookies.get('token')//建议使用cookie-universal-nuxt一个获取cookie的插件 这个可以在服务端使用  ssr渲染有一个很大的问题,就是第一次请求服务端时获取token问题
    // add token
    if (token) { config.headers.Authorization = token } else {
    //当没有token的时候做白名单判断,哪些是可以访问的
      const WhiteList = ['/home', '/login', '/register']//白名单
      const WhiteNum = WhiteList.filter((item) => {
        return item === route.path
      })
      if (WhiteNum.length === 0) {
        return redirect('/login')
      }
    }
    // console.log('请求地址:' + config.url)
  })
  /**
   * 响应
   */
  $axios.onResponse((response) => {
    // token无效,强制登出 根据后端返回自行更改
    // if (response.data.code === 10001) {
    //   const self = this
    //   self.$router.push('/login')
    //  }
  })
  /**
   * 错误
   */
  $axios.onError((error) => { // 通过code状态码判断接口是否出错
    console.log(error.response.status)
    const code = parseInt(error.response && error.response.status)
    if (code === 401) { // 需要登录
      redirect('/login')
    } else if (code === 403) { // 无权限访问
      redirect('/home')
    }
  })
}

然后在nuxt.config.js里面导入。这里没有什么不同接口文件那边有些改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default {
  plugins: [
    '@/plugins/axios'
  ],
   modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
  ],
   axios: {
    proxy: true,
    baseURL: 'http://localhost:5000'
  },
  proxy: {
    '/api': {
      target: 'http://localhost:5000',
      pathRewrite: {
        '^/api': '/api'
      }
    }
  }
 }

为了方便后期维护接口管理,可以在项目根目录新建/api文件夹,目录下面可以新建一些接口文件:

1
2
3
4
/api
- `index.js` # 首页接口管理
- `user.js` # 用户接口管理
- `cart.js` # 购物车接口管理

这接口文件做了些许改变
当时请求的数据会被data的对象包着
列如:data:{ id:1 }
但是我只是想传{ id : 1 }就做了一些改动 ,代码如下
user.js

1
2
3
4
5
6
7
8
9
10
11
12
13
const apiPrefix = process.env.NODE_ENV === 'development' ? '/api' : '/api'
//post请求
export const userLogin = ({ $axios }, data) => {
  return new Promise((resolve, reject) => {
    resolve($axios.$post(`${apiPrefix}/users/login`, data))
  })
}
//get请求
export const userInfo = ({ $axios }) => {
  return new Promise((resolve, reject) => {
    resolve($axios.$get(`${apiPrefix}/users/current`))
  })
}

项目调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { userLogin,userInfo  } from '~/api/user'
export default {
  data(){
    return {
        formDat:{
          name:'',
          pwd:''
        }
    }
  }
  mounted() {
   this.userInfo()
  },
  methods: {
     // 异步加载数据,页面挂载完成后执行
     async  userInfo() {  //get
         const self = this;
         const data = await userInfo(self);
         console.log(data); // 返回接口信息
     },
     async  userLogin() {  //post
         const self = this;
         const data = await userInfo(self,self.formDat);
         console.log(data); // 返回接口信息
     }
  }
}

路由鉴权

在/middleware文件夹新建auth.js文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export default function ({ app, route, req, store, redirect }) {
  //const isClient = process.client   Boolean类型 直接在浏览器地址栏上访问会触发(服务端渲染)
  //const isServer = process.server   Boolean类型 页面内路由跳转会触发(客户端)
  //有特殊需求可以根据上面做改变
  const WhiteList = ['/home', '/login', '/register']  //白名单
  const token = app.$cookies.get('token')
    if (token === undefined) {  //未登录的时候
        const WhiteNum = WhiteList.filter((item) => {
          return item === route.path
        })
        // console.log(WhiteNum.length)
        if (WhiteNum.length === 0) {
          return redirect('/login')//未登录访问非白名单的时候
        }
    }
}

这里标注一下哈,有一个坑
nuxt如果不设置根路径显示哪一个页面,有时候会一直在这里刷新,成为死循环,整个浏览器都不好关闭,一直在那里转圈圈??
我的解决方法:在pages目录下的index.vue添加默认页面

1
2
3
4
5
6
7
8
9
10
11
<template>
  <Home />
</template>
<script>
import Home from '~/pages/home/index'
export default {
  components: {
    Home
  }
}
</script>

nuxt使用vuex和nuxtServerInit

Nuxt.js 内置引用了 vuex 模块,所以不需要额外安装。
Nuxt.js 支持两种使用 store 的方式,你可以选择使用:

普通方式: store/index.js 返回一个 Vuex.Store 实例
模块方式: store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index.js 是根模块)
我建了一个根模块和user模块
为了方便数据管理和好的渲染效果在vuex请求和存储全局数据方便各组件使用
在store目录下新建index.js和user.js:
index.js----主要是为了调用nuxtServerInit
user.js----为了方便管理,用户数据存储在这个模块,可以结合自己项目创建符合的模块文件
必须要注意!!!
nuxtServerInit方法必须在/store/index.js里面,放到其他文件不会触发 代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//inde.js
const actions = {
  async nuxtServerInit ({ commit }, { app, req }) { // 在地址栏输入地址访问或者刷新的时候触发
    // 下面可以根据自己项目更改,这里只是做了一个demo
    const token = app.$cookies.get('token')
    if (token) {
      req.headers.Authorization = token // 在请求头添加token 我后端是koa2 jwt验证
      const data = await Promise.all([
        app.$axios.$get('/api/users/current')
      ])
      if (data[0].code === 200) { // 请求成功
        await commit('user/SET_isLogin', true)
        await commit('user/SET_name', data[0].phone)
      }
    }
  }
}
export default {
  actions
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//user.js
export const state = () => ({ // state里面存放的是变量,如果你要注册全局变量,写这里
  isLogin: false,
  token: '',
  avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',   //用了网络上的图片,如有侵权,我麻溜就改
  name: '',
  roles: ['admin']   //根据需要是否要配置权限
})
const mutations = { // 修改store中的变量的方法,如果你要改变变量的值,就写这(vuex中state中的值不能直接修改)
  SET_isLogin (state, value) {
    state.isLogin = value
  },
  SET_token (state, value) {
    state.token = value
  },
  Remove_token (state) {
    state.token = ''
  },
  SET_name (state, value) {
    state.name = value
  }
}
export default {
  namespaced: true, // 命名空间
  state, // 这里你用到了哪几个属性就写哪几个,不需要的可以注释掉
  // getters,
  // actions,
  mutations
}

打包后部署

npm build //打包
npm start //测试
上传

1
2
3
4
5
6
7
8
.nuxt             # 打包后的文件
/assets           # 能被webpack处理的项目资源
/node_modules     # 可以上传package.js文件,之后在npm安装  
/plugins          # 项目插件
/server           # ssr模式的要上传这个文件
/static           # 不被webpack处理的静态资源
nuxt.config.js    # Nuxt.js配置文件
package.json      # npm包管理器文件

部署的时候建议用pm2部署
pm2 start npm --name “project” – run start
名字使用package.json里面的name
服务跑起来之后,在用nginx配置一下就ok啦