Что такое маршрутизация?
С момента рождения веб-сайтов, веб-сайтов и т. д. маршруты всегда существовали; до разделения передней и задней части обычно упоминаемые маршруты были внутренними; маршруты проходят через запрос, а затем распределяются по указанному пути для соответствия соответствующий обработчик; его функция заключается в распределении запросов и распределении соответствующих запросов в соответствующие места.
Внешняя маршрутизация и внутренняя маршрутизация
Внутренняя маршрутизация
Внутренняя маршрутизация может быть понята как сервер, отображающий URL-адрес, запрошенный браузером, в соответствующую функцию после синтаксического анализа.Эта функция будет выполнять различные операции в зависимости от типа ресурса.Если это статический ресурс, он будет читать файл. Если это динамические данные, то некоторые добавления, удаления и изменения будут выполняться через базу данных.
Преимущество back-end маршрутизации в том, что она хороша для SEO и обладает высокой безопасностью; недостатком — высокая связанность кода, что увеличивает нагрузку на сервер, а http-запрос ограничен сетевым окружением, что влияет пользовательский опыт.
Внешняя маршрутизация
С появлением интерфейсных одностраничных приложений (SPA) интерфейсные страницы полностью стали составными, разные страницы — это разные компоненты, а переключение страниц — это переключение компонентов; JS анализирует URL-адрес, а затем находит соответствующий компонент для рендеринг
Самое большое отличие front-end роутинга от back-end роутинга в том, что нет необходимости проходить через сервер, а соответствующую страницу можно получить сразу после парсинга страницы через JS в браузере
Преимущество внешней маршрутизации заключается в том, что нет необходимости отправлять http-запросы на переключение компонентов, переключение происходит быстро, а пользовательский опыт удобен; недостатком является отсутствие разумного использования кеша, и это не способствует SEO
Внешний режим маршрутизации
хэш-режим
Режим хешированияvue-routerШаблон маршрутизации по умолчанию, отмеченный#
http://localhost:8888/#/home
пройти черезwindow.location.hashПолучить хэш текущего URL; передать в хеш-режимеhashchangeМетод может отслеживать изменение хэша в url
window.addEventListener("hashchange", function(){}, false)
Особенностью режима хеширования является лучшая совместимость, а изменение хэша добавит запись в историю браузера, которая может реализовать прямые и обратные функции браузера;
Недостаток из-за еще одного#, поэтому URL в целом недостаточно красив
режим истории
Режим истории — это еще один внешний режим маршрутизации, основанный на объекте истории HTML5.
пройти черезlocation.pathnameПолучить адрес маршрутизации текущего URL-адреса; в режиме истории передатьpushStateа такжеreplaceStateМетод может изменить URL-адрес в сочетании сpopstateМетод прослушивает изменения маршрута в URL-адресе.
Особенности режима истории заключаются в том, что он более удобен в реализации и более читабелен.#, URL-адрес также более красивый;
Его недостатки также очевидны, когда пользователь обновляет или напрямую вводит адрес, будет отправлен запрос на сервер, поэтому режим истории нуждается в поддержке одноклассников сервера и перенаправляет все маршруты на корневой маршрут.
рабочий процесс vue-маршрутизатора
- изменение URL
- запускать прослушиватель событий
- Изменить текущую переменную в vue-router
- наблюдатель, отслеживающий текущую переменную
- получить новые компоненты
- render
Основы плагина Vue
Vue.use()
Vue.use()Метод используется для установки плагинов, с помощью которых можно взломать некоторые функции или API во Vue;
Он получает параметр, если этот параметр имеет метод установки, тоVue.use()Будет выполнен метод установки.Если полученный параметр является функцией, функция будет выполнена как метод установки.
Метод установки также получит параметр при выполнении, который является текущим экземпляром Vue.
Через полученный экземпляр Vue вы можете определить некоторые глобальные методы или свойства, либо вы можете расширить метод экземпляра Vue через прототип
class vueRouter {
constructor(){
}
}
vueRouter.install = function(Vue) {
}
Vue.mixin()
Vue.mixin()Метод используется для регистрации глобального миксина, в качестве параметра он получает объект, который мы называем миксин-объект, миксин-объект может содержать любые опции компонента, к свойствам и методам, определенным миксином-объектом, можно обращаться в каждом компонент
<!-- router.js -->
class vueRouter {
constructor(){
}
}
vueRouter.install = function(Vue) {
Vue.mixin({
data(){
return {
name: '阿白smile'
}
}
})
}
<!-- home.vue -->
// 省略代码
<script>
export default {
created(){
console.log(name) // '阿白smile'
}
}
</script>
Реализовать routerJs
Благодаря предыдущим знаниям у меня есть некоторое понимание маршрутизации, а затем я начинаю реализовывать routerJs.
Давайте сначала рассмотрим использование vue-router, а затем проведем пошаговый разбор разборки на основе этого
<!-- index.js -->
import vueRouter from './router'
import App from 'app.vue'
Vue.use(vueRouter)
const router = new vueRouter({
routes: []
})
new Vue({
router,
render: h => h(App)
})
Как видно из приведенного выше примера использования,Vue.use()Метод устанавливает vueRouter как подключаемый модуль, благодаря установке подключаемого модуля метод vueRouter и связанные с ним компоненты можно использовать глобально;
метод установки
Во-первых, вам нужно сначала реализовать метод установки и внедрить vueRouter в глобальную через установку
<!-- router.js -->
class vueRouter {
constructor(){}
}
vueRouter.install = function(Vue) {
Vue.mixin({
beforeCreate(){
// $options.router存在则表示是根组件
if (this.$options && this.$options.router) {
this._root = this
this._router = this.$options.router
Vue.util.defineReactive(this, 'current', this._router.history)
} else {
// 不是根组件则从父组件中获取
this._root = this.$parent._root
}
// 使用$router代理对this._root._router的访问
Object.defineProperty(this, '$router', {
get() {
return this._root._router
}
})
}
})
}
Метод установки принимает экземпляр Vue в качестве параметра черезVue.mixin()глобальный миксинbeforeCreatedКрючки жизненного цикла; служебные методы, доступные через экземпляр VuedefineReactiveБудуcurrentсвойство становится наблюдателем
Во избежание использования_routerмодификация, поэтомуObject.definePropertyУстановить свойство только для чтения$router, и используйте его для проксированияthis._root._routerДоступ
инициализация маршрутизатора
vue-router должен передать новый оператор при инициализации, поэтому вам нужно предоставить класс vueRouter и открыть его для внешнего использования; вам также нужен класс истории для сохранения текущего пути маршрутизации
class HistoryRoute {
constructor() {
this.current = null
}
}
class vueRouter {
// options 为初始化时的参数
constructor(options) {
this.mode = options.mode || 'hash'
this.routes = options.routes || []
this.history = new HistoryRoute
this.init()
}
init() {
if (this.mode === 'hash') {
// 初始化一个#
location.hash ? '' : location.hash = '/'
// 页面加载完成获取当前路由
window.addEventListener('load', () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener('hashchange', () => {
this.history.current = location.hash.slice(1)
})
} else {
window.addEventListener('load', () => {
this.history.current = location.pathname
})
window.addEventListener('popstate', () => {
this.history.current = location.pathname
})
}
}
}
export default vueRouter
В приведенном выше коде создайтеHistoryRouteДобрый,HistoryRouteДобрыйcurrentСвойство хранит текущий маршрут.В методе установки это значение может быть реализовано для ответа и отслеживания его изменений, а также для отображения различных компонентов в соответствии с его изменениями.
vueRouter получает объект опций в качестве параметра инициализации при создании экземпляра, а режим маршрутизации указывается в опциях (mode) и таблицу маршрутизации (routes); если не указано в опцияхmodeа такжеroutes,ноmodeПо умолчанию используется хэш-режим,routesПо умолчанию []
Метод инициализации будет установлен после загрузки страницы в соответствии с различными режимами маршрутизации.current, а также добавить прослушиватели событий для маршрутизации изменений, чтобы обеспечить своевременные обновленияcurrentсвойство, а затем визуализировать компонент
компонент router-view и рендеринг маршрута
router-viewРеализация компонента зависит отVue.component()метод, с помощью которого компонент регистрируется глобально.Следует отметить, что глобальная регистрация компонента Vue должна быть выполнена до создания экземпляра Vue;
Vue.componentМетод получает два параметра, первый — это имя компонента, а другой — объект параметра компонента;
router-viewФункция компонента заключается в отображении компонента, соответствующего маршруту, в соответствии с изменением маршрута, поэтому он в основном используется в объекте опции во время регистрации.renderфункция
Vue.component('router-view', {
render(h) {
}
})
Следующее, что нужно реализоватьrouter-viewСамая важная функция компонента, как найти компонент, который нужно отрендерить?
Известно, что при изменении маршрута можно получить самый последний адрес маршрутизации, и в то же времяroutes(таблица маршрутизации) данные
Таким образом, вам нужно только получить соответствующий компонент из таблицы маршрутизации по адресу маршрутизации и передать егоrenderфункция выполняется
Есть два способа получить компоненты из таблицы маршрутизации по маршруту:
Во-первых, каждый раз при изменении маршрута метод find используется для однократного запроса таблицы маршрутизации и получения объекта маршрутизации.Хотя этот метод выполним, запрашивать каждый раз при изменении маршрута слишком дорого;
Другой способ — хранить маршрут и соответствующие ему компоненты в виде пар «ключ-значение».При изменении маршрута вам нужно запрашивать только по адресу маршрута, этот метод нужно пройти только один раз, и он используется непосредственно при маршрут меняется Получение компонентов в виде пар ключ-значение может быть очень эффективным для повышения скорости рендеринга
class vueRouter {
constructor(options) {
// 省略其他代码
this.routes = options.routes || []
this.routeMap = this.createMap(this.routes)
}
// 省略其他代码
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, {})
}
}
До сих пор все маршруты хранились в парах ключ-значение.routeMap, то вы можете использоватьrenderФункция отображает компонент
vueRouter.install = function(_Vue) {
// 省略其他代码
Vue.component('router-view', {
render(h) {
let current = this._self._root._router.history.current // 当前路由
let routerMap = this._self._root._router.routeMap
return h(routerMap[current])
}
})
}
сюда,router-viewКомпонент инкапсулирован, его можно использовать в любом компоненте, а различные компоненты отображаются в соответствии с изменениями в маршрутизации.
метод push и метод замены
существуетvue-router, будь то декларативный переход маршрутизации или программный переход маршрутизации, он должен быть выполнен за счет участия этих двух методов;
В режиме истории маршрут переключается черезwindow.history.pushStateМетод завершен, в режиме хеширования переключение маршрута осуществляется непосредственно изменением значения хеш-функции.
pushState
pushStateэто новый метод, представленный H5, в основном используемый для добавления записей в историю;
Он получает три параметра, которыегосударственный объект,заглавиеа такжеURL;Поскольку второй параметр (заголовок) будет игнорироваться в некоторых браузерах, вот основное понимание объекта состояния и URL
stateObjобъект состояния, который будет связан с записью истории;popstateПри срабатывании события объект состояния будет передан функции обратного вызова; браузер сериализует объект состояния и сохранит его локально, а также сможет получить объект при перезагрузке страницы.
URLURL-адрес новой истории, который должен находиться в том же домене, что и текущая страница; этот адрес будет отображаться в адресной строке браузера.
class vueRouter {
constructor(options) {}
push(url) {
if (this.mode === 'hash') {
location.hash = url
} else {
pushState(url)
}
}
replace(url) {
if (this.mode === 'hash') {
location.hash = url
} else {
pushState(url, true)
}
}
}
function pushState(url, replace) {
const history = window.history
if (replace) {
history.replaceState({key: history.state.key}, '', url)
} else {
history.pushState({key: Date.now()}, '', url)
}
}
В приведенном выше коде значение хеш-функции напрямую изменяется в зависимости от местоположения в режиме хеширования, компонент представления изменяется путем изменения значения хэш-функции, аpushStateЭтот метод одинаково отвечает за переходы на страницы в режиме истории и использует параметр замены, чтобы определить, какой метод использовать для перехода;
Реализация router-link
router-linkтакже черезVue.component()способ регистрации глобального компонента
Vue.component('router-link', {
render(h) {
}
})
router-linkПолучите некоторые параметры реквизита, вот несколько часто используемых, все параметры можно просмотретьофициальная документация
to: 目标路由地址
tag: 渲染的标签
replace: 使用replace方式进行路由跳转,不留下history记录
Далее приступайте к реализации простогоrouter-linkкомпоненты
Vue.component('router-link', {
props: {
to: {
type: [Object, String],
required: true
},
tag: {
type: String,
default: 'a'
},
replace: Boolean
},
render(h) {
let data = {}
if (this.tag === 'a') {
data.attrs = {href: this.to}
} else {
data.on = {click: () => {
if (this.replace) {
this._self._root._router.replace(this.to)
} else {
this._self._root._router.push(this.to)
}
}}
}
return h(this.tag, data, this.$slots.default)
}
})
router-linkКомпонент задает целевой маршрут через параметр to. Параметр tag отвечает за метку, отображаемую компонентом на странице. По умолчанию используется метка. Параметр replace отвечает за управление использованием метода замены при переходе маршрута .
существуетrenderВ функции выполняется разная склейка данных по разным тегам.При смене маршрута по умолчанию тег может напрямую устанавливать атрибут href, а другим тегам нужно прослушивать события, а потом использоватьrouterМетод перехода по маршруту для переключения маршрута
До сих пор это было достигнутоvue-routerМониторинг основной маршрутизации, прыжки, переключение, рендеринг компонентов и другие функции, сначала перейдите в браузер, чтобы увидеть эффект
напиши в конце
Эта статья начинается с происхождения маршрутизации, переходит к различиям, преимуществам и недостаткам внешней и внутренней маршрутизации, а затем представляетvue-routerрабочий процесс и реализованоvue-routerНекоторые из основных методов и их принципы в
Исходный код, задействованный в статье, был отправлен на мойGithub
End