Здравствуйте, расскажите о своем понимании внешней маршрутизации.

внешний интерфейс
Здравствуйте, расскажите о своем понимании внешней маршрутизации.

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

предисловие

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

1. Почему происходит внешняя маршрутизация?

2. Какую проблему решает интерфейсная маршрутизация?

3. Каков принцип реализации фронтальной маршрутизации?

Мы берем эти три вопроса и продолжаем смотреть вниз.В процессе чтения, если у учащихся есть собственное мнение, они могут высказать свое мнение в области комментариев. Если вы считаете, что контент дал вам новые идеи, пожалуйста, поставьте свой драгоценный лайк 👍, это будет для меня мотивацией продолжать писать.

традиционная страница

Здесь нет запутанности в названии, весь проектDOMПрямые страницы, мы все называем их «традиционными страницами» (SSR относится к прямолинейным страницам, я не думаю, что это категория традиционных страниц здесь). Так что жеDOMПрямо? Проще говоря, он инициирует запрос после того, как браузер вводит URL-адрес и возвращаетHTMLСтраница является окончательным визуализируемым эффектом, т.е.DOMпрямо. И каждый раз, когда вы нажимаете на страницу, чтобы перейти, она будет повторно запрашиватьHTMLресурс. пока не увижу, не поверю. Давайте возьмем этот адрес в качестве примера, чтобы проверить следующее утверждение.

Блог Woohoo.cn на.com/han-1034683…

С первого взгляда вы можете понять, что изображено на картинке выше. Верно, блог-сад — это веб-сайт с традиционными страницами. Каждый раз, когда страница загружается, она возвращаетсяHTMLресурсы иCSSДождитесь статических ресурсов и объедините их в новую страницу.

«Слепых» одноклассников, я научу другому способу, то есть правой кнопкой мыши на странице браузера, нажать «Показать исходный код веб-страницы», и открыть его следующим образом:

Какие изображения или текст можно увидеть на веб-странице, вы можете найти соответствующие изображения на приведенных выше изображениях.HTMLструктура, то есть традиционная страница, то естьDOMпрямо.

Одна страница

Времена идут вперед, технологии развиваются.Сталкиваясь с растущим спросом на веб-страницы, веб-страницы начали двигаться в сторону модульности и компонентизации. Из этого следует, что код сложно поддерживать, он неуправляем и его сложно повторять. Столкнувшись с этой ситуацией, родилось много отличных современных интерфейсных фреймворков, и первый из них —React,Vue,Angularи другие известные фреймворки одностраничных приложений. И у этих фреймворков есть общая черта — «рендеринг страниц через JS».

Например, прежде чем мы пошли прямоDOM, а теперь и с этими одностраничными фреймворкамиHTMLТам в основном только одна страницаDOMВход примерно такой:

Все компоненты страницы запускаются путем запуска нижней части изображения выше.app.jsскрипт, смонтированный на<div id="root"></div>ниже этого узла. Покажите этот шаг на очень простом JS-дисплее:

<body>
  <div id="root"></div>
  <script>
    const root = document.getElementById('root') // 获取根节点
    const divNode = document.createElement('div') // 创建 div 节点
    divNode.innerText = '你妈贵姓?' // 插入内容
    root.appendChild(divNode) // 插入根节点
  </script>
</body>

image.png

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

image.png

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

Внешняя маршрутизацияПо адресной строке браузераpathnameизменяется, чтобы соответствовать соответствующим компонентам страницы. а затем создайте его с помощьюDOMФорма узла, запихнутого в корневой узел<div id="root"></div>. Этим достигается эффект переключения страниц без обновления, и это также можно объяснить со стороны, что это потому, что нет обновления, поэтомуReact,Vue,AngularКогда современные фреймворки создают компоненты страницы, каждый компонент имеет свой собственныйжизненный цикл.

принцип

Внешняя маршрутизацияДва фреймворка с самыми популярными плагинами соответствуютVue-Router иReact-Router, но их логика в конечном счете остается той же, и более уместно использовать одни и те же четыре слова для разных целей.

Анализируя принципы реализации хеш-режима и исторического режима, каждый получает более глубокое понимание принципа внешней маршрутизации.

хэш-режим

aВы должны быть знакомы с якорями тегов, а адрес браузера находится на#Следующие изменения можно отслеживать, и браузер предоставляет нам собственные события мониторинга.hashchange, он может отслеживать следующие изменения:

  • нажмитеaтег, изменил адрес браузера
  • Поведение браузера вперед и назад
  • пройти черезwindow.locationметод, изменить адрес браузера

Далее мы используем эти характеристики для достиженияhashПростая маршрутизация шаблонов:запустить онлайн

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hash 模式</title>
</head>
  <body>
    <div>
      <ul>
        <li><a href="#/page1">page1</a></li>
        <li><a href="#/page2">page2</a></li>
      </ul>
      <!--渲染对应组件的地方-->
      <div id="route-view"></div>
    </div>
  <script type="text/javascript">
    // 第一次加载的时候,不会执行 hashchange 监听事件,默认执行一次
    // DOMContentLoaded 为浏览器 DOM 加载完成时触发
    window.addEventListener('DOMContentLoaded', Load)
    window.addEventListener('hashchange', HashChange)
    // 展示页面组件的节点
    var routeView = null
    function Load() {
      routeView = document.getElementById('route-view')
      HashChange()
    }
    function HashChange() {
      // 每次触发 hashchange 事件,通过 location.hash 拿到当前浏览器地址的 hash 值
      // 根据不同的路径展示不同的内容
      switch(location.hash) {
      case '#/page1':
        routeView.innerHTML = 'page1'
        return
      case '#/page2':
        routeView.innerHTML = 'page2'
        return
      default:
        routeView.innerHTML = 'page1'
        return
      }
    }
  </script>
  </body>
</html>

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

Эффект отображения браузера выглядит следующим образом:

режим истории

historyрежим будетhashрежим немного более громоздкий, потому чтоhistoryШаблоны основаны на нативных событияхpopstate, вот объяснение от MDN:

image.png

Немного знаний: pushState и replaceState — это новые API HTML 5. Они очень мощные и могут изменить адрес браузера без обновления страницы. Это важный способ изменить адресную строку без обновления страницы.

включаютaСобытие клика метки не будетpopstateмонитор. Нам нужно найти способ решить эту проблему, чтобы достичьhistoryмодель.

image.png

**Решение.** Мы можем обойти все страницы на странице с помощьюaэтикетка, блокaВ то же время, как событие по умолчанию метки, плюс функция обратного вызова события клика, получить его в функции обратного вызоваaпомеченhrefзначение атрибута, затем передатьpushStateсменить браузерlocation.pathnameстоимость имущества. тогда делай это вручнуюpopstateФункция обратного вызова события для соответствия соответствующему маршруту. Логика может быть немного небрежной, давайте объясним это кодом:онлайн-адрес 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>History 模式</title>
</head>
<body>
  <div>
    <ul>
      <li><a href="/page1">page1</a></li>
      <li><a href="/page2">page2</a></li>
    </ul>
    <div id="route-view"></div>
  </div>
  <script type="text/javascript">
    window.addEventListener('DOMContentLoaded', Load)
    window.addEventListener('popstate', PopChange)
    var routeView = null
    function Load() {
      routeView = document.getElementById('route-view')
      // 默认执行一次 popstate 的回调函数,匹配一次页面组件
      PopChange()
      // 获取所有带 href 属性的 a 标签节点
      var aList = document.querySelectorAll('a[href]')
      // 遍历 a 标签节点数组,阻止默认事件,添加点击事件回调函数
      aList.forEach(aNode => aNode.addEventListener('click', function(e) {
        e.preventDefault() //阻止a标签的默认事件
        var href = aNode.getAttribute('href')
        //  手动修改浏览器的地址栏
        history.pushState(null, '', href)
        // 通过 history.pushState 手动修改地址栏,
        // popstate 是监听不到地址栏的变化,所以此处需要手动执行回调函数 PopChange
        PopChange()
      }))
    }
    function PopChange() {
      console.log('location', location)
      switch(location.pathname) {
      case '/page1':
        routeView.innerHTML = 'page1'
        return
      case '/page2':
        routeView.innerHTML = 'page2'
        return
      default:
        routeView.innerHTML = 'page1'
        return
      }
    }
  </script>
</body>
</html>

Обратите внимание, что вы не можете открывать статические файлы непосредственно в браузере, вам нужно использовать веб-сервис, чтобы запустить порт для просмотра веб-сайта.

Суммировать

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