共计 11486 个字符,预计需要花费 29 分钟才能阅读完成。
一、引入并创立 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-vue
npm 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 = false
import {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.js
const 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.js
export 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.js
export 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-resources
npm i @nuxtjs/style-resources --save-dev
// nuxt.config.js
export default {buildModules: ['@nuxtjs/style-resources'],
styleResources: {
// your settings here
sass: [],
scss: [],
less: [],
stylus: []},
}
正文完
发表至: javascript
2021-01-30