一、引入并创立nuxt我的项目
确认曾经装置 npx ( npx
依附于 npm 5.2.0
装置引入)
npx create-nuxt-app <my-project>
或者在 npm
v6.1版本后 能够这样创立:
npm init nuxt-app@latest <my-project>
或者用: yarn:
yarn create nuxt-app <my-project>
二、引入axios库
1、应用nuxt自带模块
npm i @nuxtjs/axios -s
1) 、在 nuxt.config.js
中引入
export default { /* ** Runtime Config */ publicRuntimeConfig: { axios: { baseURL: 'https://api.nuxtjs.dev' } }, /* ** Modules - https://nuxtjs.org/docs/2.x/directory-structure/modules */ modules: ['@nuxtjs/axios']}
2) 、页面内应用 $axios
获取数据,并用 $config
获取 API 接口的 URL
async asyncData({$axios}) { let { res } = await $axios.get(`https://xxx.com/api/xxx`) console.log(res) }
3) 、设置公共拦挡
在 ~/plugins
创立 axios.js
文件
export default function ({store, redirect, req, router, $axios }) { // baseUrl能够在下面的配置中,也可在这儿配置 $axios.defaults.baseURL = 'http://XXX/api'; if(process.server){ // 获取服务端的token,对应函数请自行封装 var token = getcookiesInServer(req).token; } if(process.client){ // 获取客户端token,对应函数请自行封装 var token = getcookiesInClient('token'); } // request拦截器 $axios.onRequest(config => { if(process.client){ // 客户端下,申请进度条开始 NProgress.start(); } // 将获取到token退出到申请头中 config.headers.common['Authorization'] = token; }); // response拦截器,数据返回后,能够先在这里进行一个简略的判断 $axios.interceptors.response.use( response => { if(process.client){ // 客户端下, 申请进度条完结 NProgress.done(); } // return response if(response.data.code == 401){ // 返回401,token验证失败 removeToken("token"); // 重定向到登录页面, 这里做一个判断,容错:req.url 未定义 if(req.url){ redirect("/sign?ref="+req.url) }else{ redirect("/sign") } }else if(response.data.code == 404){ // 重定向到404页面 redirect("/") } else{ // 申请接口数据失常,返回数据 return response } }, error => { if(process.client){ NProgress.done(); } if(error.response.status == 500){ // http状态500,服务器外部谬误,重定向到500页面 redirect("/500.htm") } if(error.response.status == 404){ // http状态500,申请API找不到,重定向到404页面 redirect("/404.html") } return Promise.reject(error.response) // 返回接口返回的错误信息 })}
2、内部引入axios
npm i axios -s
1) 、创立request文件夹
在文件夹内创立 http.js
文件, urls
文件夹, apis
文件夹
http.js
import axios from 'axios'import Vue from 'vue'const ajax = axios.create({ baseURL: process.env.baseUrl, timeout: 30 * 1000})// 申请拦截器ajax.interceptors.request.use( config => { // const Token = getToken() // if (Token) { // config.headers['token'] = getToken() // } config.headers['Content-Type'] = 'application/json;chartset=utf-8' // config.headers["Authorization"] = "Bearer atwerjjhqkwehtjhsdfqwehjhwrgqre"; return config }, error => { throw new Error(`申请谬误: ${error}`) })// 响应拦截器ajax.interceptors.response.use( response => { if (response.status === 200) { // 解决返回流文件报错 if (response.config.responseType === 'blob') { var reader = new FileReader() reader.readAsText(response.data) reader.onload = e => { const result = JSON.parse(e.target.result) if (result.code !== 200) { Vue.prototype.$message.error(result.msg) } } } if (response.data.code === 200) { return response.data.data } else { Vue.prototype.$message.error(response.data.message) return Promise.reject(response.data) } } else { return response } }, error => { throw new Error(error) // throw new Error(`申请谬误: ${error}`) })/* * @params {config} 参数从API传递过去 * @params @{config} {url} 申请地址 * @params @{config} {data} 申请数据 */export function get(config) { let obj = { url: config.url, method: 'get', params: { ...config.data, } } return ajax(obj)}export function post(config) { let obj = { url: config.url, method: 'post', data: { ...config.data, } } return ajax(obj)}export function upload(config) { let obj = { url: config.url, method: 'post', data: config.data, headers: { 'Content-Type': 'multipart/form-data' } } return ajax(obj)}
urls文件夹下创立对应模块的url信息
例如 urls/user.js
export default { userinfo: '/user/userinfo', userList: '/user/userList'}
apis文件夹下创立对应模块的api函数
例如 apis/user.js
import { get, post } from '../http.js'import user from '../urls/user'export function getUserinfo(params) { return get({ url: userUrls.userinfo, params })}export function getUserList(params) { return post({ url: userUrls.userList, params })}
页面内失常应用咱们熟知的形式引入api函数去调接口获取数据
3、axios跨域配置
1) 、应用官网axios模块时的配置
export default { axios: { proxy: true, prefix: '/api', // baseURL credentials: true, retry: { retries: 3 } }, proxy: { '/api': { target: 'http://192.168.xxx.xxx:xxxx', // 代理地址 changeOrigin: true, pathRewrite: { '^/api': '', //将 /api 替换掉 } }, }}
2) 、应用官网axios模块,引入官网模块 @nuxtjs/proxy
配置
npm i @nuxtjs/proxy -D
在 nuxt.config.js
中配置
modules: [ '@nuxtjs/axios', '@nuxtjs/proxy'],proxy: [ [ '/api', { target: 'http://localhost:3001', // api主机 pathRewrite: { '^/api' : '/' } } ]]
3) 、应用内部引入的形式
配合后端部署设置nginx
三、登录状态长久化
npm i -S cookie-universal-nuxt
在 nuxt.config.js
中配置
modules: [ // 登录状态长久化 ['cookie-universal-nuxt', { parseJSON: true }]],
四、引入ant-design-vue组件库
npm i -S ant-design-vuenpm install babel-plugin-import --save-dev
1、按需引入配置
// nuxt.config.js{ build: { babel: { plugins: [ [ 'import', { libraryName: 'ant-design-vue', libraryDirectory: 'es', style: true // 默认不应用该选项,即不导入款式 , 留神 ant-design-vue 应用 js 文件引入款式 // true 示意 import 'ant-design-vue/es/component/style' // 'css' 示意 import 'ant-design-vue/es/component/style/css' } ] ] } }}
在 ~/plugins
文件夹创立 antd-ui.js
文件
import Vue from 'vue'Vue.config.productionTip = falseimport { Button } from 'ant-dsign-vue'Vue.use(Button)
2、antd-icon
过大
不是所有的图标咱们都能用到
在 ~/plugins
文件夹创立 antd-icons.js
文件
export { // 须要应用到的 Icons InfoCircleFill, DownOutline, UpOutline, RightOutline, LeftOutline} from '@ant-design/icons'
// nuxt.config.jsconst CompressionPlugin = require('compression-webpack-plugin')const path = require('path')export default { build: { vendor: ['axios', 'ant-design-vue'], // 解决less加载应用不了的问题 loaders: { less: { javascriptEnabled: true } }, analyze: { analyzerMode: 'static' }, // 应用Babel与特定的依赖关系进行转换 transpile: [/ant-design-vue/], extend(config, ctx) { // 配置eslint if (ctx.isClient) { config.module.rules.push({ enforce: 'pre', test: /\.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules)/ }) // ant-design-vue 的icon组件,按需引入须要的图标,文件太大 config.resolve.alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, './plugins/antd-icons.js') // 引入须要的 } }, // 打包构建优化 plugins: [ new CompressionPlugin({ test: /\.js$|\.html$|\.css/, // 匹配文件名 threshold: 10240, // 对超过10kb的数据进行压缩 deleteOriginalAssets: false // 是否删除原文件 }) ], optimization: { splitChunks: { minSize: 10000, maxSize: 250000 } } }}
留神: 这儿装置 compression-webpack-plugin
插件会报错,指定插件版本就行了
npm i --save-dev compression-webpack-plugin@6.1.1
揭示:图标应用<a-icon type="close"></a-icon>来显示
如果有组件内应用的,例如
<a-rate v-model="val"> <a-icon #character type="star"></a-icon></a-rate>
五、国际化
1、引入i18n
npm i vue-i18n --save
2、在 plugins
下创立 i18n.js
// nuxt.config.jsexport default { plugins: [ '@/plugins/antd-ui', { src: '@/plugins/lazy-load', ssr: false }, '@/plugins/i18n.js', { src: '~/plugins/lodash.js', ssr: false }, { src: '~/plugins/moment.js', ssr: false }, { src: '@/plugins/vue-swiper.js', mode: 'client' }, ],}
import Vue from 'vue'import VueI18n from 'vue-i18n'Vue.use(VueI18n)export default ({ app, store }) => { // Set i18n instance on app // This way we can use it in middleware and pages asyncData/fetch app.i18n = new VueI18n({ locale: store.state.locale, fallbackLocale: store.state.locale, messages: { 'en-US': require('@/language/en-US.json'), 'zh-CN': require('@/language/zh-CN.json') }, silentTranslationWarn: true }) app.i18n.path = link => { // 如果是默认语言,就省略 if (app.i18n.locale === app.i18n.fallbackLocale) { return `/${link}` } return `/${app.i18n.locale}/${link}` }}
3、在 middleware
下创立 `i18n.js
// nuxt.config.jsexport default { router: { middleware: ['i18n'] },}
export default function({ isHMR, app, store, route, params, error, redirect }) { const defaultLocale = app.i18n.fallbackLocale // If middleware is called from hot module replacement, ignore it if (isHMR) return // Get locale from params const locale = params.lang || defaultLocale if (store.state.locales.indexOf(locale) === -1) { return error({ message: '页面未找到.', statusCode: 404 }) } // Set locale // store.commit('SET_LANG', locale) app.i18n.locale = store.state.locale // If route is /<defaultLocale>/... -> redirect to /... if (locale === defaultLocale && route.fullPath.indexOf('/' + defaultLocale) === 0) { const toReplace = '^/' + defaultLocale + (route.fullPath.indexOf('/' + defaultLocale + '/') === 0 ? '/' : '') const re = new RegExp(toReplace) return redirect(route.fullPath.replace(re, '/')) }}
4、在 store
下创立 index.js
import { getToken } from '@/lib/token.js'const state = () => ({ token: '', locales: ['en-US', 'zh-CN'], locale: 'en-US'})const mutations = { setToken(state, token) { state.token = token }, SET_LANG(state, locale) { if (state.locales.indexOf(locale) !== -1) { state.locale = locale } }}const actions = { async nuxtServerInit({ commit }, { app }) { let token = getToken(app) || '' commit('setToken', token) //还能够获取一些通用信息,比方个人信息,通用配置什么的 }}export default { state, actions, mutations}
5、在 language
下创立 en-US.json
、 zh-CN.json
更多语言库,请依照规定增加
配置对应的变量属性名称,在页面用
<span>{{ $t('变量名') }}</span>
对应antd-vue组件库国际化,官网举荐应用 config-provider
组件
// default.vue页面<template> <a-config-provider :locale="lang"> <div class="layout-container"> <a-layout> <a-layout-header>header</a-layout-header> <a-layout-content><Nuxt /></a-layout-content> <a-layout-footer>footer</a-layout-footer> <a-back-top /> </a-layout> </div> </a-config-provider></template><script>import { mapState } from 'vuex'import language from '../language/antd-lang/index'import moment from 'moment'import 'moment/locale/zh-cn'moment.locale('en')export default { data() { return {} }, computed: { ...mapState({ locale: state => state.locale }), lang: function() { let l = null switch (this.locale) { case 'zh-CN': l = language.zhCN moment.locale('zh-cn') break case 'en-US': l = language.enUS moment.locale('en') break } return l } }}</script>
在 language
下创立 antd-lang/index.js
, 蕴含所有的反对语言库
// 阿拉伯import arEG from '~/node_modules/ant-design-vue/es/locale/ar_EG'// 保加利亚语import bgBG from '~/node_modules/ant-design-vue/es/locale/bg_BG'// 加泰罗尼亚语import caES from '~/node_modules/ant-design-vue/es/locale/ca_ES'// 捷克语import csCZ from '~/node_modules/ant-design-vue/es/locale/cs_CZ'// 德语import deDE from '~/node_modules/ant-design-vue/es/locale/de_DE'// 希腊语import elGR from '~/node_modules/ant-design-vue/es/locale/el_GR'// 英语import enGB from '~/node_modules/ant-design-vue/es/locale/en_GB'// 英语(美式)import enUS from '~/node_modules/ant-design-vue/es/locale/en_US'// 西班牙语import esES from '~/node_modules/ant-design-vue/es/locale/es_ES'// 爱沙尼亚语import etEE from '~/node_modules/ant-design-vue/es/locale/et_EE'// 波斯语import faIR from '~/node_modules/ant-design-vue/es/locale/fa_IR'// 芬兰语import fiFI from '~/node_modules/ant-design-vue/es/locale/fi_FI'// 法语(比利时)import frBE from '~/node_modules/ant-design-vue/es/locale/fr_BE'// 法语import frFR from '~/node_modules/ant-design-vue/es/locale/fr_FR'// 冰岛语import isIS from '~/node_modules/ant-design-vue/es/locale/is_IS'// 意大利语import itIT from '~/node_modules/ant-design-vue/es/locale/it_IT'// 日语import jaJP from '~/node_modules/ant-design-vue/es/locale/ja_JP'// 韩语/朝鲜语import koKR from '~/node_modules/ant-design-vue/es/locale/ko_KR'// 挪威import nbNO from '~/node_modules/ant-design-vue/es/locale/nb_NO'// 荷兰语(比利时)import nlBE from '~/node_modules/ant-design-vue/es/locale/nl_BE'// 荷兰语import nlNL from '~/node_modules/ant-design-vue/es/locale/nl_NL'// 波兰语import plPL from '~/node_modules/ant-design-vue/es/locale/pl_PL'// 葡萄牙语(巴西)import ptBR from '~/node_modules/ant-design-vue/es/locale/pt_BR'// 葡萄牙语import ptPT from '~/node_modules/ant-design-vue/es/locale/pt_PT'// 斯洛伐克语import skSK from '~/node_modules/ant-design-vue/es/locale/sk_SK'// 塞尔维亚import srRS from '~/node_modules/ant-design-vue/es/locale/sr_RS'// 斯洛文尼亚import slSI from '~/node_modules/ant-design-vue/es/locale/sl_SI'// 瑞典语import svSE from '~/node_modules/ant-design-vue/es/locale/sv_SE'// 泰语import thTH from '~/node_modules/ant-design-vue/es/locale/th_TH'// 土耳其语import trTR from '~/node_modules/ant-design-vue/es/locale/tr_TR'// 俄罗斯语import ruRU from '~/node_modules/ant-design-vue/es/locale/ru_RU'// 乌克兰语import ukUA from '~/node_modules/ant-design-vue/es/locale/uk_UA'// 越南语import viVN from '~/node_modules/ant-design-vue/es/locale/vi_VN'// 简体中文import zhCN from '~/node_modules/ant-design-vue/es/locale/zh_CN'// 繁体中文import zhTW from '~/node_modules/ant-design-vue/es/locale/zh_TW'export default { arEG, bgBG, caES, csCZ, deDE, elGR, enGB, enUS, esES, etEE, faIR, fiFI, frBE, frFR, isIS, itIT, jaJP, koKR, nbNO, nlBE, nlNL, plPL, ptBR, ptPT, skSK, srRS, slSI, svSE, thTH, trTR, ruRU, ukUA, viVN, zhCN, zhTW}
六、scss、less款式全局援用
SASS: `yarn add sass-loader node-sass`LESS: `yarn add less-loader less`Stylus: `yarn add stylus-loader stylus`
yarn add @nuxtjs/style-resourcesnpm i @nuxtjs/style-resources --save-dev
// nuxt.config.jsexport default { buildModules: ['@nuxtjs/style-resources'], styleResources: { // your settings here sass: [], scss: [], less: [], stylus: [] },}