Следующая запись ямы входа

Nuxt.js

Мысли о внедрении nuxt в проект

Почему передняя часть должна вводить изоморфную SSR

А. Для лучшего SEO и скорости загрузки в верхней части страницы.

б) Внедрить слой BFF, чтобы расширить возможности внешнего интерфейса и улучшить его способность решать проблемы.

Преимущества nuxt

1. Более четкая и строгая структура: Nuxt, как и egg и другие фреймворки, предоставляет набор механизмов структуры и ограничений, поэтому создание проекта на основе Nuxt будет иметь более четкую структуру.

2. Простой и удобный в использовании, готовый к использованию, интегрированный с инфраструктурой пользовательского интерфейса, средой тестирования и т. д.npx create-nuxt-app appNameМожет быть запущен непосредственно после одного набора, и стоимость миграции низкая

Об изоморфной ССР

  1. Хотя используется рендеринг на стороне сервера, его можно назвать только изоморфным SSR, который отличается от традиционного рендеринга на стороне сервера. В настоящее время суть изоморфной SSR заключается в интеграции компонентов страницы, маршрутизации и внешнего интерфейса, запуске сервера для создания моментальных снимков и передаче сгенерированного HTML-снимка клиенту. Следует отметить, что поскольку объем вычислений, необходимых для изоморфных снимков, намного больше, чем при традиционном рендеринге на стороне сервера, производительность на одной машине может быть ниже, чем при традиционном рендеринге на стороне сервера.
  2. Реализация изоморфного SSR гордится появлением виртуального DOM. Самым большим преимуществом виртуального DOM является не алгоритм Diff, а расширение возможностей внешнего интерфейса. Он абстрагирует DOM от HTML и может работать на сервере, IOS, Android и даже смарт-техника.
  3. Суть изоморфного SSR заключается в том, что когда пользователь запрашивает в первый раз, для внешнего интерфейса через узел создается снимок HTML, а затем операция пользователя на текущей странице фактически является взаимодействием операции SPA, а внешний интерфейс взаимодействие конечной маршрутизации по-прежнему зависит от истории маршрутизации для обработки. , а не от традиционной маршрутизации, поэтому это все ещеSPAТакая обработка может снизить нагрузку на сервер, улучшить взаимодействие с пользователем и компенсировать проблемы с производительностью изоморфного рендеринга, обеспечивая при этом скорость первого экрана.

Начало работы с Nuxt

Построить

npm

npx create-nuxt-app <项目名>

yarn

yarn create nuxt-app <项目名>

Структура каталогов

стенография

src

~ or @

root folder

~~ or @@

Корень по умолчанию и src одинаковы

Nuxt.config.js

Ступайте на яму:

1.Nuxt.config.jsфайл не используетсяbabel处理

nuxt.config.jsэто основной файл конфигурации, предоставляемый nuxt

При разработке,nuxt.config.jsИзменения в не будут напрямую обновляться в горячем режиме, и их необходимо вводить вручную в командной строке.rsповторно выполнить

asyncData

Метод asyncData вызывается перед каждой загрузкой компонента (ограничено компонентами страницы). Его можно вызвать перед обновлением сервера или маршрута. При вызове этого метода первый параметр устанавливается в объект контекста текущей страницы. Вы можете использовать метод asyncData для получения данных. Nuxt.js объединит данные, возвращаемые asyncData, с данными компонента. Данные, возвращаемые методом, также возвращаются текущему компоненту.

Понимание асинхронных данных

Представьте себе сценарий изоморфного рендеринга: при первом доступе сервер возвращает снимок HTML, когда пользователь оперирует измененной страницей, пользователь напрямую отправляет запрос из браузера на сервер. Затем нам нужно оперировать данными.Чтобы избежать написания двух наборов кода, работающего на стороне узла и на стороне браузера, нам нужна такая функция, которая может судить, на стороне браузера или на стороне сервера, и автоматически обрабатывать данные Запросы.

Итак, nuxt предоставилasyncDataТакой способ обработки запросов данных одновременно проводится сервером и браузером,asyncDataПервый параметр метода определяется как объект контекста nuxtjs.Через объект контекста nuxtjs вы можете получить параметры маршрутизации, использовать пользовательские плагины nuxtjs, обработать параметры ошибок и т. д.

То есть: функция интерфейса, выполняемая изоморфной логикой

Параметры в объекте контекста

app
params
res,req
$ аксиос и т. д.

Получить асинхронные данные

Аксиомы по умолчанию, данные должны возвращать разрешение

Как использовать асинхронные данные

использовать асинхронный режим или ждать
export default {
  async asyncData ({ params }) {
    let { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { title: data.title }
  }
}
Использование промисов
export default {
  asyncData ({ params }) {
    return axios.get(`https://my-api/posts/${params.id}`)
    .then((res) => {
      return { title: res.data.title }
    })
  }
}

не могу использовать это

Логика ССР

Когда страница запрашивается в первый раз, срабатывает SSR, при переходе на текущую страницу интерфейс запрашивается AJAX, а CSR генерирует новую страницу.

предварительная обработка

Nuxt наследует конфигурацию предварительной обработки vue cli 3. Если вы хотите использовать мопс, scss, стилус и т. д., вам нужно только выполнить npm intall или yarn add при его использовании.

npm install --save-dev pug@2.0.3 pug-plain-loader coffeescript coffee-loader node-sass sass-loader

междоменный запрос

npm i @nuxtjs/proxy -D
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  axios: {
    proxy: true
  },
  proxy: {
    '/api': {
      target: 'http://example.com',
      pathRewrite: {
        '^/api' : '/'
      }
    }
  }

noSSR

CSR можно реализовать, оборачивая noSSR, сценарии, а когда страница очень длинная, нагрузку на сервер можно уменьшить, используя отрисовку CSR внизу.

Поддержка текстовой формы и формы слота

<no-ssr placeholder="Loading...">
      <!-- 此组件仅在客户端呈现 -->
      <comments />
    </no-ssr>
  <no-ssr>
    <!-- 此组件仅在客户端呈现 -->
    <comments />

    <!-- loading indicator -->
    <comments-placeholder slot="placeholder" />
  </no-ssr>

прыжок по маршруту

NuxtLink

    <NuxtLink :to="'/users/'+user.id">
      {{ user.name }}
    </NuxtLink>

router.push

 this.$router.push(`/detail/${topicItem.postid}`);

Глобальный CSS

nuxt.config.js

  css: [
    'element-ui/lib/theme-chalk/index.css',
    '~/assets/main.scss'
  ],

загрузка между переходами страниц

loading: '~/components/loading.vue',

layout

Соответствует имени пользовательского файла vue в каталоге макета.

 layout: 'dark',

Динамический макет адаптируется к мобильным устройствам

layout: (context) => context.isMobile ? 'mobile' : 'desktop'

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

nuxt.config.js

  router: {
    middleware: ['visits', 'user-agent']
  }
export default function (context) {
  const userAgent = process.server ? context.req.headers['user-agent'] : navigator.userAgent
  context.isMobile = /Android|webOS|iPhone|iPad|BlackBerry/i.test(userAgent)
}

Промежуточное ПО основано на маршрутизации и будет выполняться при изменении маршрутизации.Последовательность процесса выполнения следующая:

  1. nuxt.config.js
  2. соответствие макету
  3. соответствующая страница

Концепция промежуточного программного обеспечения в nuxt основана на методе уровня маршрутизации, который можноnuxt.config.js,layouts,pagesпромежуточное ПО, которое соответствует промежуточному ПО всех страниц, всему промежуточному ПО, использующему один и тот же макет, и промежуточному ПО одной страницы. Если промежуточное ПО настроено одновременно в трех местах, оно будет выполняться три раза для одной страницы.

Пример использованияnuxt.config.jsсередина

  //nuxt.config.js中router的配置
  router: {
    middleware: 'auth',
  },

layoutsа такжеpagesсередина

middleware:'auth'

Уведомление

Сценарий: очистите файл cookie на странице (состояние vuex не будет очищено в это время), затем щелкните ссылку, чтобы выполнить операцию спа, когда выполняется промежуточное программное обеспечение, состояние в vuex остается исходным.

Механизм плагина

Сторонние библиотеки, такие как axios

import axios from "axios";
...
  async asyncData() {
    let { data } = await axios.get(
      `https://api.isoyu.com/api/News/new_list?type=1&page=20/new_list?type=1&page=20}`
    );
    return { topicList: data.data };
  }

nuxt.config.js

 plugins: [
     { src:  '@/plugins/element-ui' },
    { src: '@/plugins/vue-notifications.js', mode: 'client' }
  ],

режим можно выбрать клиент и сервер.

внедрить экземпляр vue

plugins/vue-inject.js

import Vue from 'vue'

Vue.prototype.$myInjectedFunction = (string) => console.log("This is an example", string)

nuxt.config.js

export default {
  plugins: ['~/plugins/vue-inject.js']
}

внедрить контекст

plugins/ctx-inject.js

export default ({ app }, inject) => {
  // Set the function directly on the context.app object
  app.myInjectedFunction = (string) => console.log('Okay, another function', string)
}

nuxt.config.js

export default {
  plugins: ['~/plugins/ctx-inject.js']
}

использовать

export default {
  asyncData(context){
    context.app.myInjectedFunction('ctx!')
  }
}

Одновременный впрыск

plugins/combined-inject.js

export default ({ app }, inject) => {
  inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}

nuxt.config.js

export default {
  plugins: ['~/plugins/combined-inject.js']
}

использовать

export default {
  mounted(){
    this.$myInjectedFunction('works in mounted')
  },
  asyncData(context){
    context.app.$myInjectedFunction('works with context')
  }
}

store/index.js

export const state = () => ({
  someValue: ''
})

export const mutations = {
  changeSomeValue(state, newValue) {
    this.$myInjectedFunction('accessible in mutations')
    state.someValue = newValue
  }
}

export const actions = {
  setSomeValueToWhatever ({ commit }) {
    this.$myInjectedFunction('accessible in actions')
    const newValue = "whatever"
    commit('changeSomeValue', newValue)
  }
}

Примечание: 1. Плагин должен соответствоватьnuxt.config.jsв последовательности, выполняемой последовательно

Сообщение об ошибке

async asyncData({ $axios, params, error, app }) {
error({ statusCode: 404, message: "Topic not found" });
}

Nuxt глубокое понимание

Жизненный цикл

image

Прежде всего, нам нужно понять жизненный цикл этого фреймворка.В процессе разработки могут возникнуть некоторые проблемы, которые трудно локализовать, и требования не могут быть реализованы.Возможно, жизненный цикл nuxt может помочь вам лучше найти и решить проблемы.

Во-первых, когда возникает запрос, первый выбор будет выполненnuxtServerInitПроцесс состояния в Vuex, то есть первым обрабатывать состояние всего приложения, а затем обрабатывать цикл в рамках одного конкретного маршрута. будет обработан первыйmiddleware, будут последовательно обработаныnuxt.config.jsконфиг, соответствиеlayout(Макет шаблона предоставлен nuxt), соответствующая страница. После этой ссылки будет обработана функция проверки (используемая для проверки параметров маршрутизации), установленная на одной странице. Наконец, это будет предоставлено nuxtasyncDataтак же какfetchфункция для получения одногоpageДанные. Следует отметить, что после жизненного цикла этих столбцов он войдет в процесс рендеринга vue.

Последовательный процесс в жизненном цикле запроса nuxt

Сервер

1. Сначала запустите плагин (все вnuxt.config.jsНаписано, может запускать плагин на стороне сервера, вне зависимости от того, находится ли он на текущей странице)

2. ВыполнитьnuxtServerInit

3. Выполнитьmiddleware:

a. middlewareбудет выполняться последовательноnuxt.config.jsнастроен вmiddleware;

b. layoutsнастроен вmiddleware;

c. pagesсерединаmiddleware.

4. Выполните метод проверки, чтобы проверить правильность параметров страницы.

5. Выполните методы asyncData и fetch на странице.

6. Действительно войдите в жизненный цикл Vue, чтобы,beforecreated,created

сторона браузера

7. Запустите плагин (все вnuxt.config.jsнаписать плагин, который можно запустить на стороне браузера)

8. Введите жизненный цикл vue, а затем запустите его на стороне браузераbeforecreatedа такжеcreatedопять таки.

Прикрепил:

1.plugin и nuxtServerInit будут выполняться только при первом обновлении страницы, а методы в plugin и nuxtServerInit не будут выполняться после нажатия на страницу для перехода. Если открывается новая страница, плагин и методы nuxtServerInit запускаются снова.

понимать:

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

2. Дополнительные жизненные циклы и методы, предоставляемые фреймворком изоморфного рендеринга, предшествуют реальному жизненному циклу vue. Причина в том, что жизненный цикл vue не может быть асинхронным. Поэтому для удовлетворения потребностей разработки все жизненные циклы и методы Это должно быть выполнено до жизненного цикла vue.Понимание этого облегчит начало разработки nuxt.

3.beforeCreatedа такжеcreatedЖизненный цикл фактически выполняется на стороне сервера и на стороне браузера одновременно, что является одним из источников «изоморфного» рендеринга.

4. Плагины,nuxtServerInit,middleware,validate,asyncData, в соответствии с порядком выполнения и конкретными требованиями необходимо выбрать соответствующий жизненный цикл и метод для удовлетворения требований разработки

Решить проблему междоменной разработки (проникновения куки)

Описание сценария проблемы:

Местное развитие, если даlocalhost, имя домена API сервераtest.com. Затем, когда будет сделан первый запрос, будет задействован процесс «предварительной выборки» файла cookie (токена).Хотя сторона узла введена для изоморфного рендеринга, файл cookie и токен по-прежнему хранятся в браузере как учетные данные пользователя, поэтому этот процесс требует файл cookie из браузера на узел, а затем с узла на серверный API.

решение:

Поэтому, когда страница запрашивается в первый раз, проверка разрешений и соответствующие данные страницы должны быть запрошены со стороны узла на стороне сервера, и нам нужен файл cookie (токен) на стороне браузера. Существует множество различных схем предварительной выборки (проникновения) файлов cookie в первые дни, некоторые из них хранятся в диспетчере состояний, а некоторые изменяются в методе asyncData.Мое предложение — инкапсулировать запрос данных в плагин отдельно и использовать asyncData для одновременного просмотра.В asyncData инкапсулированный подключаемый модуль axios используется для решения соответствующих проблем.

В то же время, когда мы делаем первый запрос, мы сталкиваемся с проблемой разработки: при первом обращении к локальному хосту браузер не будет нестиtest.comфайлов cookie. Есть проблемы с локальной разработкой, поэтому вот два решения: 1. Напрямую изменить локальный ip, чтобы он указывал наtest.com, пользователи Mac рекомендуют руль, простой и удобный в использовании переключатель среды. 2. Вы можете посетить пустую страницу по первому запросу, а затем заставить nuxt получить файл cookie через междоменный запрос ajax, а затем вернуться с пустой страницы на посещенную страницу, чтобы получить желаемый файл cookie.

Ниже приведен код для инкапсуляции плагина axios.

export default function ({ $axios, redirect, req, route, error }, inject) {
  // Create a custom axios instance
  let cookie = ''

  if (process.server) {
    if (req.headers.cookie) {
      cookie = req.headers.cookie
    }
  } else {
    cookie = document.cookie
  }
    const instance = $axios.create({
    headers: {
      common: {
        Accept: 'text/plain, */*'
      },
    },
    withCredentials: true, // default
  })
//...
  instance.setBaseURL(process.env.API_HOST)
  process.server ? instance.setHeader(cookie) : ''

Вы должны знать, что браузер не может установить параметр cookie в заголовке, а сервер может, поэтому мы можем вручную установить cookie на сервере.process.serverчтобы определить, является ли он сервером. Здесь, поскольку файл cookie обрабатывается в проекте таким образом, если токен на самом деле тот же, требуется только еще один процесс, чтобы извлечь токен из файла cookie и поместить его в токен.

Таким образом реализуется процесс предварительной выборки куки (токена), который прост, удобен и эффективен. В то же время мы также можем обработать некоторую обработку ошибок и запросить настройку здесь. . Например, унифицированная обработка статуса ошибки http

  instance.onResponse(response => {

    if (response.status === 404) {
        //404处理
    }

    return response.data 
  })

Здесь есть проблема, на которую стоит обратить внимание: в плагине можно напрямую использовать метод error для обработки страницы с ошибкой перехода, но еслиasyncDataСуществует несколько запросов данных, и когда успех и неудача различаются, это вызовет ошибку выполнения ошибки, которую можно использовать в плагине здесь.redirectметод для выполнения илиasyncDataсерединаPromise.all()Для обработки состояния ошибки после завершения.

следующая аутентификация

1. Если страниц немного и каждая страница имеет интерфейсный запрос, то можно напрямую опустить механизм внедрения vuex, а напрямую в инкапсулированный плагин http запроса по согласованному с бэкендом статус-коду, когда статус-код неправильно, считается, что вы не вошли в систему, и соответствующая логика может быть обработана.

2. Если страниц много и права пользователей несовместимы, то некоторые страницы не имеют запроса к интерфейсу, например, на статической странице есть страница с заголовком, содержащим имя пользователя. В этом случае вам нужно использовать vuex и сделать его постоянством, чтобы облегчить разработку. Примеры использования на официальном сайтеexpress-sessionМеханизм, который кажется ненужным. Также можно использовать сессию для хранения данных, но если объем данных невелик, более лаконично поместить его в файл cookie.

Использование vuex в nuxt

1.nuxtServerInit

Может выполнять некоторые запросы в nuxtServerInit

пример

store/userinfo

export const state = () => ({
  userName: '',
  roleName: '',
  roleType: '',
})

export const mutations = {
  UPDATE_USERINFO(state, { userName, roleName, roleType, netEaseUserEmail }) {
    state.userName = userName
    state.roleName = roleName
    state.roleType = roleType
  }
}

store/index

export const actions = {
  async nuxtServerInit(store, { res, req, app }) {
    //处理userinfo信息初始化
    if (!(store.state.userinfo && store.state.userinfo.netEaseUserEmail)) {
      const userinfoRes = await app.$http.get(path.getUserInfo);
      store.commit('userinfo/UPDATE_USERINFO', userinfoRes.data)
    }
  }
}

Базовое местоположение

import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState('userinfo', ['userName', 'roleName'])
  }
}

2. Пройтиvuex-persistedstate,js-cookie,cookie-parser,cookieРеализовать постоянство с помощью файлов cookieVuexПример

import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'

export default ({ store, req, res, app }) => {
  createPersistedState({
    key: 'vuexnuxt',
    storage: {
      getItem: key =>
        process.client
          ? Cookies.getJSON(key)
          : cookie.parse(req.headers.cookie || '')[key],
      setItem: (key, value) => process.client ?
        Cookies.set(key, value, { expires: 365 }) : res.cookie(key, value, { expires: new Date(Date.now() + 60 * 60 * 1000 * 24 * 365) }),
      removeItem: key => process.client ? Cookies.remove(key) : res.clearCookie(key) 
    }
  })(store)
}

Таким образом, может быть реализована постоянная поддержка vuex, будь то на стороне узла или на стороне браузера, к ней можно получить доступ черезcookieпостоянный vuex

Вложение: работа куки браузера с использованиемjs-cookieиспользование сервераcookie-parserиметь дело с. пыталсяcookie-universal-nuxtЭтот плагин, сдавайся. (Страница зависает на белом экране после использования, возможно, в этом сценарии плагина есть бесконечный цикл)

Существует множество вариантов сохранения vuex, locoostorage, sessiontorage, session и т. д., но с точки зрения простоты использования файлы cookie — лучший выбор.