nuxt构建项目
2021/1/31 5:07:31
本文主要是介绍nuxt构建项目,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、引入并创建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 }] ],
store配置请参考本文下面的i18n部分, store/index.js
四、引入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
配置请参考:@nuxtjs/style-resources
// nuxt.config.js export default { // 下面这两个配置用一个就行了 modules: ['@nuxtjs/style-resources'], buildModules: ['@nuxtjs/style-resources'], // 配置我们需要用到的less、scss全局变量,然后在.vue文件内直接引入 styleResources: { // your settings here sass: [], scss: ['./assets/vars/*.scss', './assets/abstracts/_mixins.scss'], less: ['./assets/vars/*.less'], stylus: [] }, }
这篇关于nuxt构建项目的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-30毕设私活神器
- 2024-05-30html
- 2024-05-09一定要避坑:关于微信H5分享,温馨提示你不要再踩坑了!!!
- 2024-05-09本地项目放到公网访问!炒鸡煎蛋!
- 2024-04-07金融企业区域集中库的设计构想和测试验证
- 2024-03-11前端CSS的工程化——掌握Sass这四大特性就够了
- 2024-02-21h5关联css样式(html怎么和css关联)-icode9专业技术文章分享
- 2024-02-07Firefox禁止远程字体加速网页加载及图标字体补充安装
- 2024-02-07一个菜鸡前端的3年总结-「2023」
- 2024-01-18最火前端Web组态软件(可视化)