предисловие
Когда дело доходит до функций хуков Vue, многие люди могут остановиться только на некоторых очень простых и часто используемых хуках (created
,mounted
), а насчет разницы, когда какой хук использовать, я внимательно не изучал, а жизненный цикл Vue тоже относительно высокочастотная тестовая площадка в интервью, так что как отвечать на такие вопросы, у людей есть какая яркая чувство...
Защита навигации Vue-Router:
Иногда нам нужно выполнить некоторые операции через маршрутизацию, например, наиболее распространенную проверку разрешения на вход.Когда пользователь соответствует условиям, разрешить ему войти в навигацию, в противном случае отменить прыжок и перейти на страницу входа, чтобы позволить ему войти в систему.
Для этого у нас есть несколько способов внедрить процесс навигации по маршруту:Глобальный, только для каждого маршрута или уровень компонента, рекомендуется сначала прочитатьдокументация по маршрутизации
глобальная гвардия
vue-router имеет три охранника по всему миру:
- router.beforeEach global front guard перед входом в маршрут
- router.beforeResolve глобальная защита разрешения (2.5.0+), вызываемая после вызова beforeRouteEnter
- router.afterEach глобальный почтовый хук после ввода маршрута
инструкции:
// main.js 入口文件
import router from './router'; // 引入路由
router.beforeEach((to, from, next) => {
next();
});
router.beforeResolve((to, from, next) => {
next();
});
router.afterEach((to, from) => {
console.log('afterEach 全局后置钩子');
});
to, from, next эти три параметра:
туда и обратноМаршрутизируйте объекты, которые будут входить и выходить, объект маршрутизации ссылается на объект маршрутизации, обычно получаемый через this.$route.
next:FunctionЭтот параметр является функцией, иДолжен быть вызван, иначе он не может войти в маршрут(страница пуста).
-
next() входит в маршрут.
-
следующий (false): отменить входящий маршрут, и URL-адрес сбрасывается на исходный адрес маршрута (то есть адрес маршрута, который нужно оставить).
-
next переходит к новому маршруту, текущая навигация прерывается и начинается новая навигация.
我们可以这样跳转:next('path地址')或者next({path:''})或者next({name:''}) 且允许设置诸如 replace: true、name: 'home' 之类的选项 以及你用在router-link或router.push的对象选项。
Эксклюзивная защита маршрутизации
Если вы не хотите настраивать защиту глобально, вы можете настроить защиту индивидуально для определенных маршрутов:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// 参数用法什么的都一样,调用顺序在全局前置守卫后面,所以不会被全局守卫覆盖
// ...
}
}
]
})
Охранники в компонентах маршрутизации:
- beforeRouteEnter перед вводом маршрута
- beforeRouteUpdate (2.2) Когда маршрутизация повторно использует один и тот же компонент
- beforeRouteLeave при выходе с текущего маршрута
Представлено в документации:
beforeRouteEnter (to, from, next) {
// 在路由独享守卫后调用 不!能!获取组件实例 `this`,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this`
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用,可以访问组件实例 `this`
}
beforeRouteEnter получить доступ к этому
Поскольку хук вызывается, когда экземпляр компонента еще не создан, экземпляр компонента не может быть получен.this
, вы можете передать обратный вызовnext
для доступа к экземпляру компонента
.
ноВремя выполнения обратного вызова после монтирования, так что на мой взгляд, доступ к этому здесь не очень осмысленный и может быть помещен вcreated
илиmounted
в.
beforeRouteEnter (to, from, next) {
console.log('在路由独享守卫后调用');
next(vm => {
// 通过 `vm` 访问组件实例`this` 执行回调的时机在mounted后面,
})
}
доRouteLeave:
Вызывается, когда навигация уходит с соответствующего маршрута компонента, мы используем его, чтобы запретить пользователю уйти, например, если черновик не был сохранен, или перед тем, как пользователь покинет,setInterval
После уничтожения, чтобы предотвратить уход, таймер все еще вызывается.
beforeRouteLeave (to, from , next) {
if (文章保存) {
next(); // 允许离开或者可以跳到别的路由 上面讲过了
} else {
next(false); // 取消离开
}
}
Некоторые знания о хуках:
Перехват ошибок для функций перехвата маршрута
Если у нас есть ошибка в функции ловушки глобальной защиты/маршрутизации эксклюзивной защиты/компонентной защиты маршрутизации, мы можем перехватить ее следующим образом:
router.onError(callback => {
// 2.4.0新增 并不常用,了解一下就可以了
console.log(callback, 'callback');
});
В документации по маршрутизации есть ещеметод экземпляра: Динамически добавлять маршрутизацию и т.п., можете узнать об этом, если интересно.
Перейти в бесконечный цикл, страница всегда пуста
Я понимаю, что многие люди столкнутся с этой проблемой, давайте посмотрим на этот псевдокод:
router.beforeEach((to, from, next) => {
if(登录){
next()
}else{
next({ name: 'login' });
}
});
Логика кажется правильной, но когда мы переходим кlogin
После этого, поскольку он все еще не вошел в систему в это время, он всегда будет переходить кlogin
Дальше идет бесконечный цикл, страница всегда пуста, так что нам нужно немного изменить условие суждения.
if(登录 || to.name === 'login'){ next() } // 登录,或者将要前往login页面的时候,就允许进入路由
После установки глобального джамп-хука:
Обратитесь к документации, поскольку Router.Aftereach не принимаетсяnext
Функция не изменяет саму навигацию, а это значит, что ее можно использовать только как хук, но когда я попробовал ее сам, то обнаружил, что мы можем использовать эту форму для прыжка:
// main.js 入口文件
import router from './router'; // 引入路由
router.afterEach((to, from) => {
if (未登录 && to.name !== 'login') {
router.push({ name: 'login' }); // 跳转login
}
});
Ну, router.beforeEach тоже вполне достижимо и лучше, так что покажу.
Полный процесс маршрутизации и навигации (за исключением других жизненных циклов):
- Триггер для ввода других маршрутов.
- Вызвать охрану компонента, чтобы уйти с маршрута
beforeRouteLeave
- Вызовите охрану бюро:
beforeEach
- Вызывается в повторно используемом компоненте
beforeRouteUpdate
- Вызвать эксклюзивную защиту маршрута
beforeEnter
. - Разобрать компоненты асинхронной маршрутизации.
- Вызывается в компоненте маршрутизации, который будет введен
beforeRouteEnter
- Вызвать глобальную защиту синтаксического анализа
beforeResolve
- Навигация подтверждена.
- вызвать глобальный почтовый хук
afterEach
крюк. - запустить обновление DOM (
mounted
). - воплощать в жизнь
beforeRouteEnter
Функция обратного вызова передается следующему в страже
Keep-alive вы не знаете [я думаю, вы не знаете]
При разработке проекта Vue большинство компонентов не нужно рендерить несколько раз, поэтому Vue предоставляет встроенный компонент.keep-alive
ПриходитьКэшировать внутреннее состояние компонента, чтобы избежать повторного рендеринга,Документация здесь.
Документация: и
<transition>
сходство,<keep-alive>
является абстрактным компонентом: он не отображает элемент DOM сам по себе и не появляется в цепочке родительских компонентов.
Применение:
Кэшировать динамические компоненты:
<keep-alive>
При обертывании динамических компонентов неактивные экземпляры компонентов кэшируются, а не уничтожаются, что не имеет большого практического смысла.
<!-- 基本 -->
<keep-alive>
<component :is="view"></component>
</keep-alive>
<!-- 多个条件判断的子组件 -->
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>
Компоненты маршрутизации кэша:
использоватьkeep-alive
Все компоненты маршрутизации, соответствующие путям, могут кэшироваться, включая компоненты в компонентах маршрутизации,keep-alive
Это относится к большинству вариантов использования.
<keep-alive>
<router-view></router-view>
</keep-alive>
Крючки жизненного цикла:
Поскольку это специальный сеанс функций ловушек Vue, его необходимо вычесть~
существованиеkeep-alive
Во включенных компонентах/маршрутах будет еще два хука жизненного цикла:activated
а такжеdeactivated
.
Документация: В 2.2.0 и более поздних версиях активированные и деактивированные будут в деревевсе вложенные компонентытриггер в.
активированный вызывается при первом рендеринге компонента, а затем каждый раз, когда кешированный компонент активируется.
активированное время вызова:
При первом вводе кэшированного маршрута/компонента вmounted
Позади,beforeRouteEnter
Вызывается до того, как функция обратного вызова передается следующей охранником:
beforeMount=> 如果你是从别的路由/组件进来(组件销毁destroyed/或离开缓存deactivated)=>
mounted=> activated 进入缓存组件 => 执行 beforeRouteEnter回调
Поскольку компонент кэшируется,Эти хуки не срабатывают при повторном входе в кешированный маршрут/компонент.:
// beforeCreate created beforeMount mounted 都不会触发。
Итак, время следующего звонка:
组件销毁destroyed/或离开缓存deactivated => activated 进入当前缓存组件
=> 执行 beforeRouteEnter回调
// 组件缓存或销毁,嵌套组件的销毁和缓存也在这里触发
deactivated: вызывается при деактивации компонента (уходе с маршрута)
использовалkeep-alive
не позвонитbeforeDestroy
(хук уничтожения перед компонентом) иdestroyed
(Уничтожение компонента), поскольку компонент не уничтожается, он кэшируется.
Этот крючок можно рассматривать какbeforeDestroy
Вместо этого, если вы кешируете компонент и хотите что-то сделать, когда компонент уничтожен, вы можете поместить его в этот хук.
Если вы покинете маршрут, он будет запущен в следующей последовательности:
组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach =>
全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由)
// 如果离开的组件没有缓存的话 beforeDestroy会替换deactivated
// 如果进入的路由也没有缓存的话 全局后置钩子afterEach=>销毁 destroyed=> beforeCreate等
Так что, если я просто хочу кэшировать несколько из этих маршрутов/компонентов?
Кэшируйте маршруты, которые вы хотите кэшировать:
До Vue2.1.0:
Чтобы добиться чего-то подобного, вы можете:
-
Настройка метаданных маршрутизации
-
создать два
keep-alive
Этикетка -
использовать
v-if
Определите, какие маршруты кэшируются, с помощью метаинформации маршрутизации.<keep-alive> <router-view v-if="$route.meta.keepAlive"> <!--这里是会被缓存的路由--> </router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"> <!--因为用的是v-if 所以下面还要创建一个未缓存的路由视图出口--> </router-view> //router配置 new Router({ routes: [ { path: '/', name: 'home', component: Home, meta: { keepAlive: true // 需要被缓存 } }, { path: '/:id', name: 'edit', component: Edit, meta: { keepAlive: false // 不需要被缓存 } } ] });
После версии Vue2.1.0:
Чтобы использовать метаданные о маршрутизации, создайте еще одинrouter-view
Метки и каждый маршрут должны быть настроены с помощью метаинформации, что позволяет достичь желаемого эффекта, но это слишком громоздко.
К счастью, после Vue2.1.0 Vue добавил два новых свойства для совместной работы.keep-alive
для условного кэширования маршрутов/компонентов.
Добавлены свойства:
-
include
: соответствующие маршруты/компоненты будут кэшироваться -
exclude
: совпадающие маршруты/компоненты не будут кэшироваться
include
а такжеexclude
Поддерживает три способа условного кэширования маршрутов: строковая форма с разделителями-запятыми, обычная форма и форма массива.
Обычная форма и форма массива, необходимо использоватьv-bind
форму для использования.
Как использовать компонент кеша:
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
Но в других сценариях мы будем использоватьkeep-alive
кэшировать маршруты:
<keep-alive include='a'>
<router-view></router-view>
</keep-alive>
Правила соответствия:
-
Сначала сопоставьте параметр имени компонента,если
name
Варианты недоступны. - затем соответствует егоместное зарегистрированное имя. (родительский компонент
components
ключ опции) - Анонимный компонент, несопоставимый.
Например, компонент маршрутизации неname
вариант, и нет зарегистрированного имени компонента.
- может соответствовать только текущему обернутому компоненту,Не удается сопоставить подкомпоненты, вложенные ниже.
Например, при использовании в маршрутизации он может соответствовать только компонентам маршрута.name
Параметр, не может соответствовать вложенному компоненту внутри компонента маршрутизации.name
опции.
- Документация:
<keep-alive>
не будет работать должным образом в функциональных компонентах, так как у них нет кэшированных экземпляров. exclude
приоритет больше, чемinclude
То есть: когдаinclude
а такжеexclude
Когда оба существуют,exclude
Эффективно,include
не удалось.
<keep-alive include="a,b" exclude="a">
<!--只有a不被缓存-->
<router-view></router-view>
</keep-alive>
когда компонентexclude
match, компонент не будет закэширован и не будет вызыватьсяactivated
а такжеdeactivated
.
Хуки жизненного цикла компонентов:
О жизненном цикле компонентов, пришло время освободить эту картину:
Эта картина сделала это очень ясно, и многие люди также сделали эту часть очень четко. Большинство жизненных циклов не будут использоваться. Вот несколько очков:
-
Запросы Ajax лучше всего размещать в
created
в, потому что он уже доступен в этот моментthis
Теперь запрошенные данные можно разместить непосредственно наdata
в.Я тоже несколько раз сталкивался здесь, и интервьюер спрашивал: в какой жизненный цикл следует помещать ajax-запрос.
-
Операция dom должна быть помещена в
mounted
в,существуетmounted
Предыдущий доступ к дому будетundefined
. -
Делайте что-то каждый раз, когда вы входите/выходите из компонента, какой хук использовать:
-
Не кэшировать:
доступно при входе
created
а такжеmounted
крючок, использовать при уходеbeforeDestory
а такжеdestroyed
крюк,beforeDestory
может получить доступthis
,destroyed
не доступныйthis
. -
Кэшированный компонент:
После кэширования компонента повторный вход в компонент не сработает.
beforeCreate
,created
,beforeMount
,mounted
,Если вы хотите что-то делать каждый раз при входе в компонент, вы можете поставитьactivated
В крючок компонента кеша.Аналогично: при выходе из кеша компонента,
beforeDestroy
а такжеdestroyed
не срабатывает, вы можете использоватьdeactivated
Вместо этого оставьте крючок для компонента кеша.
Полная последовательность срабатывания хуков:
навигация по маршруту,keep-alive
, в сочетании с хуком жизненного цикла компонента, триггерной последовательностью, предполагая, что он покидает компонент a и входит в компонент b в первый раз:
-
beforeRouteLeave
: Компонент компонента маршрутизации покидает хук перед маршрутизацией, что может отменить выход из маршрутизации. -
beforeEach
: глобальная передняя защита маршрутизации, которую можно использовать для проверки входа в систему, загрузки глобальной маршрутизации и т. д. -
beforeEnter
: Эксклюзивная защита маршрутизации -
beforeRouteEnter
: компонент компонента маршрутизации входит в крючок предварительной маршрутизации. -
beforeResolve
:Защита глобального синтаксического анализа маршрута -
afterEach
: маршрутизировать глобальный почтовый хук -
beforeCreate
: жизненный цикл компонента, недоступноthis
. -
created
: Жизненный цикл компонента, доступенthis
, не могу получить доступ к dom. -
beforeMount
: жизненный цикл компонента -
deactivated
: выйти из кеша компонента a или активировать abeforeDestroy
а такжеdestroyed
Хук уничтожения компонента. -
mounted
: доступ/управление dom. -
activated
: в компонент кеша, во вложенный дочерний компонент a (если есть). - Затем выполните функцию обратного вызова beforeRouteEnter.
Эпилог
Vue предоставляет много хуков, но мы почти не используем их. Только зная последовательность срабатывания этих функций-хуков и некоторые ограничения, стоящие за ними, мы можем правильно использовать эти хуки.Эти хуки более понятны и более удобны в использовании.
Я надеюсь, что друзья, которые прочитали это, могут нажать «Нравится» / «Подписаться», ваша поддержка — самая большая поддержка для меня.
Передовое расширенное накопление,Нет публики,GitHub, wx:OBkoro1, Электронная почта: obkoro1@foxmail.com
Выше 2018.7.21
Использованная литература:
Vue-документация