静态资源和打包
直接引入图片:
<div><img src="~static/logo.png" /></div>
css中引入图片:
<style>
.diss{
width: 300px;
height: 100px;
background-image: url('~static/logo.png')
}
</style>
打包:npm run generate
然后在dist文件夹下输入live-server。
nuxt的跨域+拦截器
axios和@nuxtjs/axios
使用asyncData时需要请求全链接或者服务器有配代理的接口,客户端否则会出现跨域,服务器端不会出跨域问题。
在nuxt.config.js中配置代理。
nuxtjs/axios是对axios的包装,使用this.$aixos.get(url).then(),并且package.json中dependencies 有没有存在 @nuxtjs/axios,没有就安装npm install --save @nuxtjs/axios @nuxtjs/proxy
nuxt.config.js进行配置
export default {
head: { ... },
css: [],
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
axios: {
// 开启代理 (如果需要判断线上线下环境,可以通过 process.env.NODE_ENV !== 'production' 来判断)
proxy: true,
// 给请求 url 加个前缀 /api,如果这项不配置,则需要手动添加到请求链接前面
// 如果是多个代理的时候,则不需要配置,走手动添加代理前缀
prefix: '/api',
// 跨域请求时是否需要使用凭证
credentials: true
},
proxy: {
//当代理多个时,只需添加如下格式的数组对象即可
'/api': { // key(路由前缀):value(target)(代理地址)
// 目标接口域
target: 'http://test.luoqiuqin.com',
// 全局配置是否跨域
changeOrigin: true,
pathRewrite: {
// 单个配置是否跨域
// changeOrigin: true
// 把 '/api' 替换成 '/',具体需要替换为 '' 还是 '/' 看自己习惯
'^/api': '/'
}
}
},
build: {
// 防止重复打包
vendor: ['axios']
}
}
在组件中使用,这样就可以在服务器渲染到页面之后,通过请求进行更换数据,因为到页面之后需要走代理的方式才能获取到数据,否则会报错跨域。、
mounted() {
this.$axios.get("/about").then(res=>{
console.log(res)
})
// axios 需要手动加上 '/api' 代理协议
// @nuxtjs/axios 因为配置了 prefix: '/api' 会自动添加,否则也得手动添加
// 访问的 url 地址为 http://x.x.x.x:3000/api/index
// 然后根据上面代理转为 http://test.luoqiuqin.com/index
// /api 会自动加到访问链接中
}
使用axios:默认nuxtjs自带axios,是不需要手动安装的,在 package.json 文件中 dependencies 中可能并不体现出来,可以通过 node_modules 文件夹找到 axios。
如果没有就安装:
npm install @nuxtjs/axios --save-dev
axios 与 @nuxtjs/axios 可以共用 nuxt.config.js 中代理配置。
在组件中使用:
<script>
import axios from 'axios'
export default {
mounted() {
axios.get("/api/index").then(res=>{
console.log(res)
})
}
}
</script>
//可以封装 ,axios.js
import axios from 'axios'
const service = axios.create({
// 请求地址,为空则请求的时候带上
baseURL: '',
// 请求超时时间
timeout: 90000
})
export {
service as axios
}
//request.js
import { axios } from './axios'
// 请求地址
const BASE_URL = process.env.NODE_ENV === 'production' ? 'http://luoqiuqin.com' : 'http://test.luoqiuqin.com'
// 这种带全链接用于放在 asyncData() 中进行 SEO 请求
export function getxxx (parameter) {
return axios({
url: BASE_URL + `/list`,
method: 'get',
params: parameter
})
}
// 这种带全链接用于放在 asyncData() 中进行 SEO 请求
export function postxxx (parameter) {
return axios({
url: BASE_URL + `/load`,
method: 'post',
data: parameter
})
}
// 这种带全链接用于放在页面加载到浏览器之后,加载更多或者其他请求操作使用,不会出现跨域问题
export function getxxx (parameter) {
return axios({
url: '/api' + `/list`,
method: 'get',
params: parameter
})
}
// 这种带全链接用于放在页面加载到浏览器之后,加载更多或者其他请求操作使用,不会出现跨域问题
export function postxxx (parameter) {
return axios({
url: '/api' + `/load`,
method: 'post',
data: parameter
})
}
——拦截器
先要确认安装 了axios或者@nuxt.js/aixos
module.expores{
plugins: [
{
src: "~/plugins/axios",
ssr: false
},
],
modules: [
'@nuxtjs/axios',
],
}
//plugins/aixos.js
export default ({ $axios, redirect }) => {
$axios.onRequest(config => {
console.log('Making request to ' + config.url)
})
$axios.onError(error => {
const code = parseInt(error.response && error.response.status)
if (code === 400) {
redirect('/400')
}
})
}
export default function (app) {
let axios = app.$axios;
// 基本配置
axios.defaults.timeout = 10000
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 请求回调
axios.onRequest(config => {})
// 返回回调
axios.onResponse(res => {})
// 错误回调
axios.onError(error => {})
}
@nuxt.js/toast
类似于element的message,如果你的项目没有UI框架,alert太丑,不妨试试这个模块。
npm install @nuxtjs/toast
//nuxt.config.js中
module.exports = {
modules: [
'@nuxtjs/toast',
['@nuxtjs/dotenv', { filename: '.env.prod' }] // 指定打包时使用的dotenv
],
toast: {
// toast模块的配置
position: 'top-center',
duration: 2000
}
}
//使用
...
this.$toast.error('服务器开小差啦~~')
this.$toast.error('请求成功~~')
...
生命周期
nuxt扩展了vue的生命周期,
export default {
middleware () {}, //服务端
validate () {}, // 服务端
asyncData () {}, //服务端
fetch () {}, // store数据加载
beforeCreate () { // 服务端和客户端都会执行},
created () { // 服务端和客户端都会执行 },
beforeMount () {},
mounted () {} // 客户端
}
——asyncData
是nuxt最大的一个卖点,服务端渲染的能力就在这里,首次渲染时务必使用该方法。
asyncData会传进一个context参数,通过该参数可以获得一些信息,如:
export default {
asyncData (ctx) {
ctx.app // 根实例
ctx.route // 路由实例
ctx.params //路由参数
ctx.query // 路由问号后面的参数
ctx.error // 错误处理方法
}
}
——渲染出错和ajax请求出错的处理
使用asyncData钩子时可能会由于服务器错误或api错误导致无法渲染,此时页面还未渲染出来,需要针对这种情况做一些处理,当遇到asyncData错误时,跳转到错误页面,nuxt提供了context.error方法用于错误处理,在asyncData中调用该方法即可跳转到错误页面。
export default {
async asyncData (ctx) {
// 尽量使用try catch的写法,将所有异常都捕捉到
try {
throw new Error()
} catch {
ctx.error({statusCode: 500, message: '服务器开小差了~' })
}
}
}
错误页面可以通过/layout/error.vue自定义。
这里会遇到一个问题,context.error的参数必须是类似{ statusCode: 500, message: ‘服务器开小差了~’ },statusCode必须是http状态码,
而我们服务端返回的错误往往有一些其他的自定义代码,如{resultCode: 10005, resultInfo: ‘服务器内部错误’ },此时需要对返回的api错误进行转换一下。
为了方便,引入/plugins/ctx-inject.js为context注册一个全局的错误处理方法: context.$errorHandler(err)。
// 为context注册全局的错误处理事件
export default (ctx, inject) => {
ctx.$errorHandler = err => {
try {
const res = err.data
if (res) {
// 由于nuxt的错误页面只能识别http的状态码,因此statusCode统一传500,表示服务器异常。
ctx.error({ statusCode: 500, message: res.resultInfo })
} else {
ctx.error({ statusCode: 500, message: '服务器开小差了~' })
}
} catch {
ctx.error({ statusCode: 500, message: '服务器开小差了~' })
}
}
}
//nuct.config.js
export default {
plugins: [
'~/plugins/ctx-inject.js'
]
}
ajax请求出错,这时页面已经渲染出来,可以this.$toast.error(res.message)。
——loading方法
nuxt内置了页面顶部loading进度条的样式,提供页面跳转体验。
打开: this.
n
u
x
t
.
nuxt.
nuxt.loading.start()
完成: this.
n
u
x
t
.
nuxt.
nuxt.loading.finish()