NuxtJS 让你构建你的下一个 Vue.js 应用程序变得更有信心。这是一个 开源 的框架,让 web 开发变得简单而强大。
理解SSR
传统服务端渲染CSR
单页面应用SPA 首屏性能不好 seo不好
服务端渲染SSR(server side render)
npm install vue-server-renderer@2.6.11 express
在vue的脚手架项目中的vue-template-compiler 也是@2.6.11,上面的安装的版本号要和这里相同
已经存在spa
需要seo页面是否只是少数几个营销页面预渲染是否可以考虑
确实需要做ssr改造,利用服务器端爬虫技术puppeteer
最后选择重构 全新项目建议nuxt.js
npx create-nuxt-app <项目名>
运行项目: npm run dev
layouts/default.vue
nuxt-link像router-link
nuxt 像router-view
<template>
<div>
<nuxt-link no-prefetch to="/detail/123">详情</nuxt-link>
//no-prefetch禁用预加载行为
<nuxt-link to="/cat">购物猫</nuxt-link>
<nuxt-link to="/">首页</nuxt-link>
<nuxt />
</div>
</template>
pages页面下自定义 选用哪个layouts
export default {
layout:'blank'
}
layouts/blank.vue
<template>
<nuxt></nuxt>
</template>
pages文件夹下新建.vue文件,自动创建路由,
nuxt的主页,也就是路由的路径为 / 的 就是pages/index.vue
<template>
<Tutorial/> //Tutorial组件 在components文件夹下的Tutorial.vue文件 无需导入直接使用Tutorial
</template>
middleware的使用
pages下某个文件使用 就是局部使用
export default {
middleware: ['auth']
}
nuxt.config.js中使用就是 全局配置 对每个
export default {
router: {
middleware: ['auth']
}
}
动态路由
访问localhost:3000/detail/123
pages/detail/_id.vue
<template>
<div>
{{$route.params.id}}//这里渲染123
</div>
</template>
async asyncData({ $axios, params, error }) {// params就是上面的params
// asyncData出现的比较早 所以 不能访问this
if (params.id) {
// asyncData中不能使用this获取组件实例
// 但是可以通过上下文获取相关数据
const { data: goodInfo } = await $axios.$get("/api/detail", { params });
if (goodInfo) {
return { goodInfo };
}
error({ statusCode: 400, message: "商品详情查询失败" });
} else {
return { goodInfo: null };
}
}
asyncData
asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData方法来获取数据,Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。
注意:由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。
Nuxt.js 提供了几种不同的方法来使用 asyncData 方法,你可以选择自己熟悉的一种来用:
export default {
async asyncData({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
asyncData 方法返回的数据在融合 data 方法返回的数据后,一并返回给模板进行展示,如:
<template>
<h1>{{ title }}</h1>
</template>
nuxt命令
路由拦截 路由扩展
extendRoutes(routes, resolve) {
routes.push({
name: 'custom',
path: '*',
component: resolve(__dirname, 'pages/404.vue')
})
},
插件
plugins/api-inject.js
export default ({ $axios }, inject) => {
inject('login', user => {
return $axios.$post('/api/login', user)
})
}
nuxt-config.js
plugins: [
'@/plugins/element-ui',
'@/plugins/api-inject',//注册下
]
this.$login(u) 就可以访问到api/login接口了
拦截器
plugins/interceptor.js
export default function ({ $axios, store }) {
$axios.onRequest(config => {
// 每次请求都会修改令牌的操作
if (store.state.user.token) {
config.headers.Authorization = "Bearer " + store.state.user.token;
}
return config;
});
}
nuxt.config.js
plugins: [
"@/plugins/interceptor"
],
跨域
nuxt.config.js
axios: {
proxy: true
},
proxy: {
"/api": "http://localhost:8080"
},
store
store/user.js
export const state = () => ({
token: ''
});
export const mutations = {
init(state, token) {
state.token = token;
}
};
export const getters = {
isLogin(state) {
return !!state.token;
}
};
export const actions = {
login({ commit, getters }, u) {
return this.$axios.$post("/api/login", u).then(({ token }) => {
if (token) {
commit("init", token)
}
return getters.isLogin;
});
}
};
在middleware和plugins下的js文件可以访问到user
export default function ({ store }) {
store.state.user.token
}
koa一半使用
var Koa = require('koa');
var app = new Koa();
const bodyparser = require('koa-bodyparser')
const router = require('koa-router')({prefix:'/api'}) //通过/api/goods访问接口
app.keys = ["some secret", "another secret"]
const goods =[
{id:1,text:'web全栈架构师',price:1000},
{id:2,text:'java全栈架构师',price:1000},
]
router.get('/goods', ctx => {
ctx.body = {
ok: 1,
goods
}
})
router.get('/detail',ctx =>{
ctx.body = {
ok:1,
data:goods.find(good => good.id == ctx.query.id)
}
})
router.post('/login',ctx=>{
const user = ctx.request.body
if(user.username === 'jerry' && user.password == '123'){
const token = 'a mock token'
ctx.cookies.set('token',token)
ctx.body = {ok:1,token}
}else{
ctx.body = {ok:0}
}
})
app.use(bodyparser())
app.use(router.routes())
//使用路由中间件
// app.use(router.routes()).use(router.allowedMethods());
app.listen(8080)