Практика рендеринга Nuxt.js на стороне сервера, от разработки до развертывания

Node.js MongoDB Vue.js Vuex

понимание

После нескольких попыток по субботам и воскресеньям мы, наконец, решили распространенные проблемы с серверным рендерингом.Когда SEO не является проблемой, для нас может быть настоящей весной заняться интерфейсом, и мы также столкнулись с некоторыми небольшими ямами, Nuxt. Официальный js по-прежнему очень мощный. После поднятия вопроса он очень активно помогает. Еще раз спасибо команде разработчиков Nuxt.js.

аутентификация маршрута

Первый камень блок - это время посадки проблем аутентификации, как сохранить токен локально. Официальное использование Express-Session для решения этой проблемы, но также нужно использовать задневские нодеи, и наша компания использует PHP. Тогда я думал, возможно, Cookie может попробовать, поэтому я делаю это:

app.post('/api/login', function (req, res) {
  // 后台验证用户信息,并返回token
  async function login () {
    const { data } = await axiosServer.post('/login', req.body)
    return data
  }

  login().then(function (data) {
    // 把token存储到cookie中
    const { token } = data
    if (token) {
      res.cookie('token', token, {
        maxAge: 60000 * 60 * 24
      })
    }
    // 原封不动返回
    return res.json(data)
  })
})

Я перенаправил запрос на вход с помощью nodejs, передал данные, отправленные пользователем, на серверную часть, токен, возвращенный серверной частью, был установлен в файле cookie, а затем данные были возвращены на веб-интерфейс, а веб-интерфейс использовал vuex для сохранения токена. состояние, так что токен также существует в файлах cookie и памяти, и обновление страницы является нормальным Токен внешнего хранилища:

  async nuxtServerInit ({ dispatch, commit }, { req, res }) {
    if (req.cookies && req.cookies.token) {
      // 存储token
      commit('SET_USER', req.cookies.token)
    }
  },
  // SET_USER
  SET_USER (state, token) {
    state.token = token
  },

Таким образом, эта проблема решается так, все данные, которые необходимо хранить локально, могут быть решены с помощью этого

Визуализация данных внутри компонента

Еще одна небольшая проблема заключается в том, как отображаются данные в компонентах. В Nuxt.js только компоненты на странице имеютfetchа такжеasyncDataметод, поэтому, когда мы используем страницу макета макета, если компоненту необходимо запросить данные, он не может быть отображен.Решение состоит в том, чтобыnuxtServerInitДанные в компоненте инициализируются в методе следующим образом:

  async nuxtServerInit ({ dispatch, commit }, { req, res }) {
    // 初始化组件内的数据
    await dispatch('ADMIN_INFO')
    await dispatch('TAGS')
    await dispatch('ARCHIVES')
  }

Таким образом, данные в компоненте также могут быть успешно отображены.

Использование фильтров

Личное ощущение дизайна плагина Nuxt.js по-прежнему очень удобно для пользователя, и его не может быть проще в использовании. Создайте новый filter.js в плагинах, фильтр можно воспроизвести так:

import Vue from 'vue'
// 时间格式化
export function formatDate (date, fmt) {
  let newDate = new Date(date)
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (newDate.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  let o = {
    'M+': newDate.getMonth() + 1,
    'd+': newDate.getDate(),
    'h+': newDate.getHours(),
    'm+': newDate.getMinutes(),
    's+': newDate.getSeconds()
  }
  for (let k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      let str = o[k] + ''
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
    }
  }
  return fmt
}
let filters = {
  formatDate
}

Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})
export default filters

Затем зарегистрируйте его в nuxt.config.js:

  plugins: [
    '~plugins/filters.js'
  ]

Его можно счастливо использовать в компоненте следующим образом:

<!-- 时间格式化 -->
<div>
 <span>{{date | formatDate('yyyy-MM-dd')}}</span>
</div>

промежуточное ПО

Например, когда пользователь не вошел в систему, он заходит на страницу, требующую аутентификации через маршрутизацию, и мы можем настроить некоторые ошибки:

// auth.js
export default function ({ store, error }) {
// 可通过组件的props接收error信息
  if (!store.state.token) {
    error({
      message: 'cookie失效或未登录,请登录后操作',
      statusCode: 403
    })
  }
}

Используйте это промежуточное ПО в компоненте:

export default {
  middleware: 'auth',
  // 还可以把用户重定位到登录页
  fetch ({redirect, store}) {
    if (!store.state.token) {
      redirect('/login')
    }
  },
}

Многоуровневая вложенность маршрутизации

Официальный сказал, что эта ситуация используется меньше, но я обнаружил, что она используется много.Например, разные категории имеют разный пейджинг, поэтому и категории, и пейджинг должны быть динамической маршрутизацией, как показано на рисунке:

Скомпилированный результат:

Развертывание проекта

Примерно в августе я написал несколько статей о том, какРазвернуть проект NodejsОглядываясь назад на статью, она действительно была неплохая, со временем некоторые ошибки были исправлены, некоторые ошибки были найдены, в целом текст был слишком сумбурным. Поэтому я потратил день на запись, тренируясь на новом сервере, и использовал приведенные выше статьи в качествеgitbookРезюме, не расширено здесь, слишком долго, добавлено соответствующее содержание автоматического развертывания

Проектная практика

Этот небольшой проект был написан мной несколько месяцев назад, я провел рефакторинг с помощью Nuxt.js в январе, фронтенд использовал Nuxt.js + vuex, бэкэнд использовал Nodejs + MongoDB, и я написал редактор уценки с vue. , Поддержка загрузки изображений и рендеринга на стороне сервера, рендеринг:

титульная страница

редактор

GitHub
gitbook