传统的服务端渲染
传统的服务端渲染是路由在服务端,请求的页面都是服务端拼接好数据后,写入响应体中返回给客户端,每次路由的改变都会重新请求页面,刷新数据。
vue的SSR
专业名词:同构渲染
工作原理:首屏渲染由服务端完成需要的数据拼接返回给客户端一个html文件,html是通过webpack打包生成的,包括其余的资源(不需要在首次渲染的时候立刻请求的,目的是尽量缩短首屏的渲染时间)
客户端渲染
服务器返回的html文件中不会有body的内容,是一个空的ID为app的节点,搜索引擎就是在第一次解析页面的时候分析文档的内容,这里面什么都没有,肯定不利于SEO.
使用nuxt进行同构渲染
nuxt有自带路由,但是这次它的路由满足不要我们的需求,所以我们自己写路由
插件也需要在这里注册哦!
// nuxt.config.js/*** Nuxt.js 配置文件*/module.exports = {router: {linkActiveClass: 'active',// 自定义路由表规则extendRoutes (routes, resolve) {// 清除 Nuxt.js 基于 pages 目录默认生成的路由表规则routes.splice(0)routes.push(...[{path: '/',component: resolve(__dirname, 'pages/layout/'),children: [{path: '', // 默认子路由name: 'home',component: resolve(__dirname, 'pages/home/')},{path: '/login',name: 'login',component: resolve(__dirname, 'pages/login/')}]}])}},server: {host: '0.0.0.0',port: 3000},// 注册插件plugins: ['~/plugins/request.js','~/plugins/dayjs.js']}
nuxtServerInt 在store的action中使用
export const actions = {// nuxtServerInit 是一个特殊的 action 方法// 这个 action 会在服务端渲染期间自动调用// 作用:初始化容器数据,传递数据给客户端使用nuxtServerInit ({ commit }, { req }) {let user = null// 如果请求头中有 Cookieif (req.headers.cookie) {// 使用 cookieparser 把 cookie 字符串转为 JavaScript 对象const parsed = cookieparser.parse(req.headers.cookie)try {user = JSON.parse(parsed.user)} catch (err) {// No valid cookie found}}// 提交 mutation 修改 state 状态commit('setUser', user)}}
middleware在在创建文件之后,直接在.vue中使用
在.vue 的 asyncData 中书写获取数据的代码
async asyncData ({ query }) {const page = Number.parseInt(query.page|| 1)const limit = 20const tab = query.tab || 'global_feed'const tag = query.tagconst loadArticles = tab === 'global_feed'? getArticles: getYourFeedArticlesconst [ articleRes, tagRes ] = await Promise.all([loadArticles({limit,offset: (page - 1) * limit,tag}),getTags()])const { articles, articlesCount } = articleRes.dataconst { tags } = tagRes.dataarticles.forEach(article => article.favoriteDisabled = false)return {articles, // 文章列表articlesCount, // 文章总数tags, // 标签列表limit, // 每页大小page, // 页码tab, // 选项卡tag // 数据标签}},
在.vue 的 watchQuery 中书写监听变量变化的代码
watchQuery: ['page', 'tag', 'tab'],
点赞功能要限制次数
article.favoriteDisabled = true
客户端持久化用户信息
// 仅在客户端加载 js-cookie 包const Cookie = process.client ? require('js-cookie') : undefinedmethods: {async onSubmit () {try {// 提交表单请求登录const { data } = this.isLogin? await login({user: this.user}): await register({user: this.user})// console.log(data)// TODO: 保存用户的登录状态this.$store.commit('setUser', data.user)// 为了防止刷新页面数据丢失,我们需要把数据持久化Cookie.set('user', data.user)// 跳转到首页this.$router.push('/')} catch (err) {// console.log('请求失败', err)this.errors = err.response.data.errors}}}
在store中做好服务端的持久化
const cookieparser = process.server ? require('cookieparser') : undefinedexport const actions = {// nuxtServerInit 是一个特殊的 action 方法// 这个 action 会在服务端渲染期间自动调用// 作用:初始化容器数据,传递数据给客户端使用nuxtServerInit ({ commit }, { req }) {let user = null// 如果请求头中有 Cookieif (req.headers.cookie) {// 使用 cookieparser 把 cookie 字符串转为 JavaScript 对象const parsed = cookieparser.parse(req.headers.cookie)try {user = JSON.parse(parsed.user)} catch (err) {// No valid cookie found}}// 提交 mutation 修改 state 状态commit('setUser', user)}}
相当于客户端和服务端都要持久化一份数据
