Одна статья, невозможно сделать все, все аудитории. Я надеюсь, что вы прочитаете статью с дивергентным мышлением и усвоите знания, содержащиеся в статье, для собственного использования. Прочитав статью, вы можете что-то получить.
предисловие
Ну, давайте не будем притворяться, сегодня я буду сексуальным интервьюером и задам вам вопрос онлайн,«Расскажите о своем понимании внешней маршрутизации». Увидев этот вопрос, есть много ответов. Но подумайте об этом так, когда вы задаете кандидату этот вопрос, какой ответ вы хотите получить? По моему скромному мнению, я надеюсь, что кандидаты смогут интерпретировать этот вопрос с глобальной точки зрения, примерно в следующих трех пунктах.
1. Почему происходит внешняя маршрутизация?
2. Какую проблему решает интерфейсная маршрутизация?
3. Каков принцип реализации фронтальной маршрутизации?
Мы берем эти три вопроса и продолжаем смотреть вниз.В процессе чтения, если у учащихся есть собственное мнение, они могут высказать свое мнение в области комментариев. Если вы считаете, что контент дал вам новые идеи, пожалуйста, поставьте свой драгоценный лайк 👍, это будет для меня мотивацией продолжать писать.
традиционная страница
Здесь нет запутанности в названии, весь проектDOM
Прямые страницы, мы все называем их «традиционными страницами» (SSR относится к прямолинейным страницам, я не думаю, что это категория традиционных страниц здесь). Так что жеDOM
Прямо? Проще говоря, он инициирует запрос после того, как браузер вводит URL-адрес и возвращаетHTML
Страница является окончательным визуализируемым эффектом, т.е.DOM
прямо. И каждый раз, когда вы нажимаете на страницу, чтобы перейти, она будет повторно запрашиватьHTML
ресурс. пока не увижу, не поверю. Давайте возьмем этот адрес в качестве примера, чтобы проверить следующее утверждение.
С первого взгляда вы можете понять, что изображено на картинке выше. Верно, блог-сад — это веб-сайт с традиционными страницами. Каждый раз, когда страница загружается, она возвращается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>
Отбросьте весь обыденный мир, самая аутентичная форма запуска одностраничного проекта выглядит так.Внимание, я должен указать вопрос! ! !
Поскольку одна страница отображается таким образом, если у меня есть более дюжины страниц, на которые можно переходить и переключаться друг с друга, что произойдет! ! ? ? В этот моментВнешняя маршрутизацияОн появился, чтобы решить одностраничный веб-сайт, переключив адресный путь браузера, чтобы он соответствовал соответствующим компонентам страницы. Мы понимаем этот процесс через некрасивую картинку:
Внешняя маршрутизацияПо адресной строке браузера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:
Немного знаний: pushState и replaceState — это новые API HTML 5. Они очень мощные и могут изменить адрес браузера без обновления страницы. Это важный способ изменить адресную строку без обновления страницы.
включаютa
Событие клика метки не будетpopstate
монитор. Нам нужно найти способ решить эту проблему, чтобы достичьhistory
модель.
**Решение.** Мы можем обойти все страницы на странице с помощью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>
Обратите внимание, что вы не можете открывать статические файлы непосредственно в браузере, вам нужно использовать веб-сервис, чтобы запустить порт для просмотра веб-сайта.
Суммировать
Основные моменты этой статьи сосредоточены на интерфейсной маршрутизации.Если вы можете прочитать ее полностью и пройтись по принципам реализации, я думаю, у вас должно быть новое понимание современных интерфейсных фреймворков. Студенты, у которых нет нового понимания, приезжают в Ханчжоу, чтобы побить меня, и я не буду сопротивляться.