Одна статья, невозможно сделать все, все аудитории. Я надеюсь, что вы прочитаете статью с дивергентным мышлением и усвоите знания, содержащиеся в статье, для собственного использования. Прочитав статью, вы можете что-то получить.
предисловие
Ну, давайте не будем притворяться, сегодня я буду сексуальным интервьюером и задам вам вопрос онлайн,«Расскажите о своем понимании внешней маршрутизации». Увидев этот вопрос, есть много ответов. Но подумайте об этом так, когда вы задаете кандидату этот вопрос, какой ответ вы хотите получить? По моему скромному мнению, я надеюсь, что кандидаты смогут интерпретировать этот вопрос с глобальной точки зрения, примерно в следующих трех пунктах.
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>
Обратите внимание, что вы не можете открывать статические файлы непосредственно в браузере, вам нужно использовать веб-сервис, чтобы запустить порт для просмотра веб-сайта.
Суммировать
Основные моменты этой статьи сосредоточены на интерфейсной маршрутизации.Если вы можете прочитать ее полностью и пройтись по принципам реализации, я думаю, у вас должно быть новое понимание современных интерфейсных фреймворков. Студенты, у которых нет нового понимания, приезжают в Ханчжоу, чтобы побить меня, и я не буду сопротивляться.