Vue использует vue-router beforEach для определения фильтрации маршрута входа пользователя.

внешний интерфейс JavaScript Vue.js vue-router

Уважайте личную оригинальность, просьба указывать источник при перепечатке.

нужно

При разработке веб-приложения, с учетом пользовательского опыта, страницы, которым не нужно вызывать личные данные, часто настраиваются так, чтобы они были доступны туристам, и когда пользователь входит на некоторые страницы, требующие личных данных, таких как корзина, персональный центр, мой кошелек и т. д., при проверке входа в систему, если будет установлено, что он вошел в систему, будет отображаться страница.Если будет установлено, что он не вошел в систему, он сразу перейдет на страницу входа, чтобы предложить пользователю для входа в систему. Сегодня я расскажу, как использовать метод beforeEach vue-router для выполнения этого требования.

выполнить

В этой статье по умолчанию вы уже используетеwebpackилиvue-cliЧтобы построить среду и иметь определенный фундамент Vue, если вы сейчас новичок, то просто поищите в Интернете, есть много статей по теме, поэтому я не буду повторять их здесь. Нечего сказать, сразу к коду. Чтобы облегчить ремонтопригодность кода в будущем, я написал соответствующие методы во вновь созданном файле filter.js.

Далее вводим файл filter.js, сначала вводим vue-router:import router from "./router";Затем мы используемrouter.beforEachметод:

router.beforeEach((to, from, next) => {
    //根据字段判断是否路由过滤
    if (to.matched.some(record => record.meta.auth)) {
        if (getToken() !== null) {
            next()
        } else {
            //防止无限循环
            if (to.name === 'login') {
                next();
                return
            }
            next({
                path: '/login',
            });
        }
    } else {
        next()//若点击的是不需要验证的页面,则进行正常的路由跳转
    }
});

BeforeEeach на самом деле является функцией-ловушкой vue-router, которую можно понимать как метод, который будет вызываться перед прыжком каждого маршрутизатора.Так как есть before, конечно же, есть и afterEach, о котором мы поговорим позже.

Во-первых, давайте объясним три параметра beforeEach:

  1. to: Объект маршрута, в который собирается войти маршрутизатор.
  2. from: Маршрут, по которому уходит текущая навигация.
  3. next: функция, обязательно вызовите этот метод, чтобы разрешить этот хук. Эффект выполнения зависит от параметров вызова следующего метода.
  • next(): перейти к следующему хуку в конвейере. Если все хуки выполнены, то состояние навигации подтверждается (confirmed).
  • next(false): Прерывает текущую навигацию. Если URL-адрес браузера изменяется (вручную пользователем или кнопкой Browser Browser), то адрес URL будет сброшен на адрес, соответствующий маршруту.
  • next('/') or next({ path: '/' }): переход к другому адресу. Текущая навигация прерывается и создается новая.Вы можете передать любой объект местоположения в следующий и разрешить настройку таких параметров, как replace: true, имя: «дом» и любые параметры, используемые в router-link для поддержки или router.push.Обратите внимание, что next может передавать параметры запроса Pass.
  • next(error): (2.4.0+) Если параметр, переданный next, является экземпляром Error, навигация будет прекращена, а ошибка будет передана обратному вызову, зарегистрированному router.onError() .

иллюстрировать

Ну, могут быть некоторые люди, которые все еще не понимают этого, когда видят это, это не имеет значения, я приведу пример, чтобы понять.
Предположим, у нас сейчас есть три маршрута:/home,/mine,/login
Мы изначально вводим как/home, затем нажмите прыжок/mine, но поскольку мы не вошли в систему, он автоматически переходит к/login
В приведенном выше случае
to: представляет маршрутизацию/mine, маршрут, который мы хотим ввести.
from: представляет маршрут/home, маршрут, который мы собираемся оставить.
Обратите внимание, что использование beforeEach должно вызываться в концеnext(), иначе будет сообщено об ошибке.Если параметры не переданы, мы успешно войдем в/mine, если мы передадим такие параметры, какnext('/login'), то когда мы нажмем на любой маршрут, мы перейдем к/loginинтерфейс.
Однако наше требование состоит в том, чтобы перехватывать и переходить, только нажав на страницу, которая требует подтверждения входа, поэтому нам нужно добавить некоторые условия оценки для фильтрации маршрута.

 if (to.matched.some(record => record.meta.auth)) {
        if (getToken() !== null) {
            next()
        }
    }

to здесь - это параметр, упомянутый выше,to.matchedЭто массив объектов, который должен указывать на соответствующую информацию маршрута, такую ​​как: путь, имя, метаданные и так далее.
Мы вызываем метод some() с этим массивом в соответствии с возвращаемым значениемtrueилиfalseЧтобы судить, поэтому нам нужно добавить поле в файл конфигурации маршрутизации router.js для маршрута, который нам нужен, чтобы проверить прыжок при оценке входа в качестве условия оценки.

    {
      path: '/mine',
      name: 'mine',
      component: mine,
      meta:{auth:true}  //我们自己添加的字段
    }

С момента добавления на маршрутmeta:{auth:true}, так что нашto.matched.some(record => record.meta.auth)вернусьtrue, то мы можем принять решение о входе в систему. Мой проект состоит в том, чтобы сохранить токен вlocalstorageсудить, getToken() — это get, который я инкапсулировалlocalstorageметод.

 if (getToken() !== null) {
            next()//若token不为null,则进行路由跳转
        }

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

    else {
            next({
                path: '/login',
            });
        }

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

  • next()Указывает, что маршрут выполнен успешно, напрямую введите маршрут to и не будет вызывать router.beforeEach() снова.
  • next({ path: '/login', });Указывает, что маршрут успешно перехвачен, перенаправлен на вход в систему, и router.beforeEach() будет вызываться снова.

Другими словами, функция beforeEach() должна вызывать next(), иначе будет бесконечный цикл.
next() и next('xxx') разные, разница в том, что первый не будет снова вызывать router.beforeEach(), а второй будет. И так как у нас нет токена, после повторного вызова router.beforeEach() мы введем

 else {
            next({
                path: '/login',
            });
        }

Так создается бесконечный цикл, и решение этой задачи тоже очень простое, мы вnext({ path: '/login', });Добавьте условие суждения перед

 if (to.name === 'login') {
                next();
                return
        }

Если у нас есть направленный маршрут кname == 'login', затем выполнитеnext();и return, чтобы завершить выполнение кода.

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

tips

2018.7.2
Так как многие интерфейсы в реальном проекте требуют проверки и перехвата токена, после рассмотрения принято решение установить метод фильтрации в перехватчике axios.http response 拦截器В соответствии с кодом ошибки, возвращаемым серверной частью, делается вывод, что срок действия токена истек или он недействителен для перехода на страницу входа.