nuxtJs基础配置记录

nuxt学习记录

项目流程图
nuxtJs基础配置记录_第1张图片
其中以下基础配置是与我们当前开发的后台管理系统进行对标的,方便我们快速上手,方便使用

1.安装

nuxtJs基础配置记录_第2张图片
以上是本地安装所选项,具体安装所选项和安装后目录展示可以异步到这里https://blog.csdn.net/qq_28846389/article/details/116459936

2.项目实现

本来打算学习nuxt的,刚好有个后台管理系统入口的静态页面需要实现,就简单的撸了一下,初步主要涉及到资源引入,组件,组件数据传输,整体开发方式跟vue一样,只是组件需要放到components下,页面放到paga下面,然后就是打包部署,目前不需要服务端渲染,只需要打包后丢到nginx即可,即
静态应用部署

npm run generate

会生成一个dist文件,然后所有的静态资源都在这里

实现上述简单页面所遇到的问题
1.assets/static中资源引入
template,style中引入方法相同
~/assets/your-image.png

因为只是纯静态展示且只需要测试环境供内部人员使用,并未涉及到资源环境问题,考虑到后期项目需要,继续搭建以下功能:

1.环境配置(请求接口的api、资源路径,本地,测试,正式线)
2.axios的使用
3.axios拦截扩展
4.css,scss的引入配置
5.scss全局样式具体配置
6.px2rem插件配置

一.环境变量的配置

1.安装cross-env

npm i cross-env -D

2.配置环境变量BASE_URL,静态资源路径BASE_API(如果html与资源是相对路径,则无需配置)、NODE_ENV

//package.josn
"scripts": {
    "dev": "cross-env BASE_URL='后端服务器地址' BASE_API='后端服务器地址' NODE_ENV=development nuxt",
    "start": "cross-env BASE_URL='后端服务器地址' BASE_API='后端服务器地址' NODE_ENV=production nuxt start",
    "build": "cross-env BASE_URL='后端服务器地址' BASE_API='后端服务器地址' NODE_ENV=production nuxt build",
    "test": "cross-env BASE_URL='后端服务器地址' BASE_API='后端服务器地址' NODE_ENV=production nuxt generate",
    "generate": "cross-env BASE_URL='后端服务器地址' BASE_API='后端服务器地址' NODE_ENV=production nuxt generate"
  },

可以根据自己项目所需环境进行上述指令配置,与公司其他项目对标,一般需要以下3个环境
npm run dev 本地环境开发
npm run build:stage 测试线环境
npm run build:prod 正式线环境

3.在nuxt.config.js中进行配置

  //环境变量
    env: {
    BASE_URL: process.env.BASE_URL,
    NODE_ENV: process.env.NODE_ENV,
    BASE_API:process.env.BASE_API //静态资源路径
    },

4.使用

在使用axios进行数据拦截时,可以设置
export const request= axios.create({
    baseURL: process.env.BASE_URL
})
或者可以直接在template中直接使用,比如引入图片时
data:{
	return {
		hrefApi: process.env.BASE_API
	}
}
 <img :src="hrefApi" alt="">

参考链接:添加链接描述

二.axios的使用

1.安装

npm install @nuxtjs/axios

nuxt.config.js

modules: [
    '@nuxtjs/axios'
]

2.使用

在asyncData选项是在组件初始化前被调用的,所有在该选项中是没有办法使用this的,但是可以使用上下文对象
注意:asyncData只能在页面组件中使用,也就是pages目录下的组件,而不是components目录下的组件
```javascript
//其中context是上下文对象
async asyncData(context){
    const res = await context.$axios.$post(process.env.BASE_API+'/public/user/login',{"username":"admin","password":"xxx","roleType":1})
    //返回出去,可以在模板中直接使用
    return {
     token:res.data.token
     }
 }
//在组件的其他选项中可以直接使用
methods: {
   async getToken(){
     const res = this.$axios.$post(process.env.BASE_API+'public/user/login',{"username":"admin","password":"xxx","roleType":1})
   }
 }

三.扩展Axios

1.配置

如果需要通过注册拦截器或者改变全局设置来定制axios,需要创建一个nuxt plugin
nuxt.config.js

modules: [
    '@nuxtjs/axios'
],
plugins: [
    '~/plugins/axios'
  ],

2.拦截axios定义

plugins/axios.js

// import request from '@/utils/request'
import axios from 'axios'
export const request= axios.create({
    baseURL: process.env.BASE_URL
})
 
export default ({ store }) => {
    // 请求拦截器
    request.interceptors.request.use(function (config) {
        // Do something before request is sent
        return config;
    }, function (error) {
        // Do something with request error
        return Promise.reject(error);
    });
    // 响应拦截器
    request.interceptors.response.use(function (response) {
        // Any status code that lie within the range of 2xx cause this function to trigger
        // Do something with response data
        return response;
    }, function (error) {
        // Any status codes that falls outside the range of 2xx cause this function to trigger
        // Do something with response error
        return Promise.reject(error);
    });
}

3.api/request.js存放请求接口方法

import {request} from '@/plugins/axios'
export const login = data => {
    return request({
        method: 'POST',
        url: 'public/user/login',
        data
    })
}

4.使用

import {login} from '~/api/request'
async getToken(){
     const res = await login({"username":"admin","password":"xxx","roleType":1})
   }

参考链接添加链接描述

四.css引入

我们需要引入公共的初始化样式,比如reset
nuxt.config.js

css: [
    '~/assets/reset.css'
    ]

检测引入成功
在这里插入图片描述

五. 组件中使用scss

<style lang="scss" scoped>

1.安装sass-loader时报错,是因为安装的版本有问题

下面的版本能正常安装

“dependencies”:{
"node-sass": "^4.7.2",
"sass-loader": "7.0.3",
}
代码中测试
$color:red;
.test {
  color: $color;
  font-size: 20px;
}

2.全局样式

nuxt.config.js

css: [
     {src:'~/assets/sass/common.scss',lang:'scss'}
  ],

nuxtJs基础配置记录_第3张图片
直接使用,会出现上面的问题
解决方式:

npm i -D @nuxtjs/style-resources

nuxt.config.js

 
modules: [
    '@nuxtjs/style-resources'
],
styleResources: {
    scss: [
    	//把全局样式放到这里,同时把css节点中引用的scss删除
        '~/assets/sass/common.scss'
    ]
},
组件中lang="scss",就可以直接使用了

六. px转换为rem插件

1.插件js

plugins/px2rem.js

2.nuxt.config.js


  plugins: [
    { src: '@/plugins/custom/px2rem', ssr: false }
  ],

3.定义一个scss方法来处理px2rem

$phone: 750;
$remBase: $phone/7.5;
@function toRem($size) {
  $remSize: $size / $remBase;
  @return $remSize * 1rem;
}

4.组件中直接使用


.test {
  font-size: toRem(20);
}

在这里插入图片描述

七.封装属于自己的公共方法

1.plugins/utils.js

import Vue from 'vue'
let ownFun = function(){
	let message = function(msg){
     	msg&&console.log(msg)
     }
     let otherFun = function(){}
     return {
	message,
	otherFun
}
}
Vue.prototype.$log = ownFun()

2.nuxt.config.js

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

3.组件调用

<script>
export default {
  created() {
    this.$log.message('小老弟,你怎么回事')
  }
}
</script>

八.element-ui的全局与按需引入

1.新建plugins/element-ui.js

//全局引入
import Vue from 'vue'
import Element from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'

Vue.use(Element,{locale })
//局部使用
import Vue from 'vue'
import {Button,Input} from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'
Vue.use(Button,Input,{locale })

2.配置nuxt.config.js

css: [
    'element-ui/lib/theme-chalk/index.css'
  ],
  plugins: [
    '@/plugins/element-ui'
  ],

3.组件使用

<el-button>按钮</el-button>
<el-input/>

九.用户态

首先想到的是使用插件vuex-persistedstate,对state数据进行持久化存储

1.安装

在一般的vue-cli项目中,我们可以用vuex-persistedstate,它可以使vuex的状态持久化,页面刷新都不会丢失

npm install vuex-persistedstate  --save

2.创建plugins/vuex-persistedstate.js

import createPersistedState from 'vuex-persistedstate'

export default (context) => {
  createPersistedState({
    reducer(obj) {
      // 其中 username authority 为需要自动存储的 state
      const { token, token1 } = obj;
      return {token, token1 }
    }
  })(context.store);
}

3.nuxt.config.js

plugins: [
    { src: '~/plugins/vuex-persistedstate', ssr: false },
  ],

4.使用store/index.js

import createPersistedState from "vuex-persistedstate"
export const plugins = [createPersistedState()];

然后发现会报window is not define,修改以下两点后:
检查nuxt.config.js中是否将ssr置为false
将nuxt.config.js中mode设置为’spa’
百度后发现:
因为vuex-persistedstate原理是存放在localstorage中,由于在created钩子中不存在window对象(获取cookie、localStorage都需要window对象),如果我们想要获取用户态,然后根据用户态,去修改页面中用户状态,我们只能在mounted中进行操作,这样的话,我们在进入页面的一瞬间还是无法得知登录状态,体验上会有影响,会存在显示用户名等组件显示隐藏延迟。

  async asyncData(context){
    console.log(localStorage,'%c=======asyncData========','color:red;')
  }

nuxtJs基础配置记录_第4张图片

  created(){
    console.log(localStorage,'%c=======created========','color:red;')
  }

nuxtJs基础配置记录_第5张图片

  mounted () {
    console.log(localStorage,'%c=======mounted========','color:red;')
  }

在这里插入图片描述

怎么做更好呢?
nuxt非常友好,它提供了fetch钩子,还有nuxtServerInit,这两个钩子都运行在服务端并且我们能很快速地操作store
在asyncData,created,mounted选项中打印


  async asyncData(context){
    console.log('%c=======asyncData========','color:red;')
  },
  
  created () {
    console.log('%c=======created========','color:red;')
  }
  
  mounted () {
    console.log('%c=======mounted========','color:red;')
 }

nuxtJs基础配置记录_第6张图片

2.nuxtServerInit
状态树文件中指定了nuxtServerInit方法,nuxtJs调用它的时候会将页面的context上下文对象作为第2个参数传给它以供服务端调用,与fetch一样,不包括context.redirect和context.error方法,具体哪些参数可以查看官方文档。当我们想要将服务端的一些数据传到客户端,可以通过这个获取保存在状态中,客户端再从状态里取出来就好了。
nuxtServerInit:先把token存入cookie,这样每次请求都会自带cookie,那么利用nuxtServerInit里的参数 {req, res},去获取到请求附带的cookie,然后解析出token,然后再存入vuex。
推荐使用cookie插件cookie-universal-nuxt

1.安装cookie插件

npm i --save cookie-universal-nuxt

2.配置

modules: [
    // Simple usage
    'cookie-universal-nuxt'
 ]

参考链接:添加链接描述

3.使用

//组件未初始化时,需要使用上下文对象调用
//eg:
aysncData(context){
	context.$cookies.set('name',value)
	context.$cookies.get('name')
}
//组件已经初始化,可以直接使用this
create(){
	this.$cookies.set('name',value)
	this.$cookies.get('name')
}

nuxtServerInit使用

store/index.js

import Vuex from 'vuex'
import cookieparse from '~/plugins/cookieparse'
import { login} from '~/api/request'
export const state = () => ({
  token: null
})

export const mutations = {
  saveToken(state, token) {
    console.log('store.token.save = ' + token)
    state.token = token
  }
}

export const actions = {
  async nuxtServerInit({ commit }, app) {
    console.log('00000000000')
  }
}

然后发现nuxtServerInit并未执行,mode改成universal之后,nuxtServerInit可以运行

运行结果:
在这里插入图片描述
mode的这两种模式有什么区别呢?
最直观的区别应该就是
spa不是ssr渲染,而universal是服务器端渲染
参考链接:添加链接描述

十.性能优化

1.打包优化

查看文件,vendors/app.js有6.3M
在这里插入图片描述
使用插件babel-plugin-component实现懒加载,优化打包体积

1.安装
npm i babel-plugin-component -D
2.nuxt.config.js
build: {
	    // 为 JS 和 Vue 文件设定自定义的 babel 配置。
	    babel: {
	      plugins: [
	        [
	          'component', { libraryName: 'element-ui', styleLibraryName: 'theme-chalk' }
	        ]
	      ]
	    }
	}

再运行后
在这里插入图片描述

2.analyze

nuxtJs基础配置记录_第7张图片

1.安装、
# NPM
npm install --save-dev webpack-bundle-analyzer
2.nuxt.config.js
 build: {
    analyze: true
    // or
    analyze: {
      analyzerMode: 'static'
    }
  }
3.运行,会自动打开分析页面
npx nuxt build --analyze 
//or
// npx nuxt build --a

优化前
nuxtJs基础配置记录_第8张图片
优化
1.plugins/element-ui.js

import Vue from 'vue'
// import Element from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'
import { Button,Input } from 'element-ui'

import '../assets/stylesheets/element-variables.scss'

Vue.use(Button,{locale})
Vue.use(Input,{locale})

2.assets/stylesheets/element-variables.scss

// element-variables.scss
/* 样式--按需引入 */
@import "../../node_modules/element-ui/packages/theme-chalk/src/button";
@import "../../node_modules/element-ui/packages/theme-chalk/src/input";

优化后的结果:
nuxtJs基础配置记录_第9张图片

你可能感兴趣的:(nuxtjs)