Цель: одностраничное приложение vue, созданное vue-cli, некоторые определенные страницы реализуют обновление вперед, назад без обновления, пользовательский интерфейс, подобный приложению. Примечание. Обновление здесь конкретно относится к запуску запроса ajax для получения данных с сервера при входе на эту страницу. Не обновлять конкретно означает, что при входе на эту страницу запрос ajax не запускается, а используются ранее кэшированные данные, чтобы уменьшить количество запросов к серверу и сделать работу пользователя более плавной.
Требования к проекту:
Исследуйте любую технологию, как из потребностей проекта. Микропрограмма, ранее обрабатывающая хранилище коммуникационных терминалов, используя обычную модель mvc, использует jq + js, поэтому для более знакомых требований проекта Mall. В текущем исследовании vue, практикуемый в ручном торговом центре, часто упоминаемые потребности не могут быть решены ранее. Некоторые страницы необходимо обновлять вперед, а не назад. Например, из ТРЦ [Главная] - [страница] Оформить заказ>, каждый раз при открытии новой страницы нужно будет получать новые данные, а после нажатия клавиши возврата не нужно получать новые данные -> [] страница сведений , а полоса прокрутки остается в прежнем положении. Наиболее распространенная операция выполняется со страницы [Главная] -> [Подробности], а затем в деталях со страницы [Страница] -> [Главная] и так далее.
Пример показан на рисунке:
Прошлый опыт:
Предки сажали деревья, а последующие поколения наслаждались тенью. Совместное использование в мире технологий всегда было на подъеме. Когда мы сталкиваемся с проблемами, мы можем сколько угодно искать следы больших парней. Для вышеуказанных потребностей см. акциюподдержка vue-router, который больше соответствует моим потребностям, но когда я использую его в своем проекте, я обнаружил, что он немного неуместен. Это разделение технических моментов больше подходит для прыжков и возврата до двух страниц. А моя страница — это прыжок между несколькими маршрутами (2+), назад. В отчаянии я могу исследовать и открывать только самостоятельно. Однако этот технический момент дал мне хорошее вдохновение, и я хотел бы поблагодарить автора. @ RoamIn
Идеи реализации:
Примечание. В демо-версии главная страница содержит три ссылки. страница1-->страница2-->страница 3. Идти вперед по порядку, каждый раз при переходе на новую страницу нужно получить данные, а после нажатия клавиши назад вернуться со страницы 3 на страницу 2, страница 2 больше не получает новые данные, но использует предыдущий кеш Data. При возврате со страницы2 на страницу1 страница1 больше не получает новые данные, а использует предыдущие данные. Следовательно, страницы page1 и page2 необходимо кэшировать, а page3 не нужно кэшировать. Вы можете представить страницу 1 как домашнюю страницу, страницу 2 как страницу сведений и страницу 3 как страницу отправки заказа. Это легко понять.
-
Используйте keep-alive для кэширования страниц, которые необходимо кэшировать
-
Переписать router-view в app.vue
<keep-alive> <router-view v-if="$route.meta.keepAlive"> <!-- 这里是会被缓存的视图组件,比如 page1,page2 --> </router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"> <!-- 这里是不被缓存的视图组件,比如 page3 --> </router-view>
-
Добавить в router/index.jsМетаинформация маршрутизации, установите страницу для кэширования
routes: [{ path: '/', name: 'index', component: index, meta: { keepAlive: false, //此组件不需要被缓存 } }, { path: '/page1', name: 'page1', component: page1, meta: { keepAlive: true, //此组件需要被缓存 } }, { path: '/page2', name: 'page2', component: page2, meta: { keepAlive: true, // 此组件需要被缓存 } }, { path: '/page3', name: 'page3', component: page3, meta: { keepAlive: false, // 此组件不需要被缓存 } } ]
-
Порядок выполнения хуков
-
Не использовать keep-alive передRouteEnter --> создано --> смонтировано --> уничтожено
-
Используйте поддержку активности
beforeRouteEnter --> created --> mounted --> activated --> deactivated
Повторный вход на кэшированную страницу вызовет только вызов beforeRouteEnter -->activated --> deactivated . созданный и смонтированный, больше не будет выполняться. Мы можем использовать разные функции ловушек для разных целей.Убедитесь, что понимаете время выполнения и порядок выполнения вышеперечисленных функций-ловушек.Ядро этого руководства зависит от этой функции-ловушки.
Активация и деактивация — это две важные функции ловушек в Vue после использования keep-alive, о которых рекомендуется узнать подробнее..
-
-
-
Как написать страницы для кэширования
Примечание: страница1 и страница2 в демо, эти две страницы нужно кэшировать, идея та же, далее в качестве примера взята страница1, а страница2 повторяться не будет.
Пример файла:components/page1.vue-
Инициализировать строку str в данных для хранения данных, полученных из фона.
data() { return { msg: "我是第一个页面", str: "" // 加载页面后执行获取数据的方法,插入到此 }; }
-
Создайте метод в методах для имитации получения данных из фона
methods: { getData() { // getData方法,模拟从后台请求数据 this.str = "我是通过调用方法加载的数据。。。"; } }
-
Измените конфигурацию в router/index.js.
-
Каждый раз, когда мы заходим на страницу, нам нужно знать, с какой страницы мы пришли, чтобы определить, нужно ли нам получать данные. Взяв эту страницу page1 в качестве примера, когда мы знаем, что она пришла со страницы 2, мы можем думать, что пользователь использовал ключ возврата.В это время странице page1 не нужно получать новые данные, и она может использовать ранее кэшированные данные. Если это приходит с другой страницы, нам нужно получить данные.
-
мы можем пройтиbeforeRouteEnterПараметр from в этой функции хука определяет, с какой страницы он пришел.Когда этот параметр выполняется, экземпляр компонента не был создан, поэтому переменные не могут быть определены в данных. Мы можем определить переменную в маршруте, чтобы судить.
-
Добавьте переменную isBack в метамаршрутизатор/index.js, значение по умолчанию false
{ path: '/page1', name: 'page1', component: page1, meta: { keepAlive: true, //此组件需要被缓存 isBack:false, //用于判断上一个页面是哪个 } }, { path: '/page2', name: 'page2', component: page2, meta: { keepAlive: true, // 此组件需要被缓存 isBack:false, //用于判断上一个页面是哪个 } },
-
-
В beforeRouteEnter оценивается, откуда пришла страница
-
Определите, с какого маршрута он пришел.Если он пришел со страницы2, это означает, что текущую страницу не нужно обновлять для получения новых данных, а ранее кэшированные данные можно использовать напрямую.
beforeRouteEnter(to, from, next) { // 路由导航钩子,此时还不能获取组件实例 `this`,所以无法在data中定义变量(利用vm除外) // 参考 https://router.vuejs.org/zh-cn/advanced/navigation-guards.html // 所以,利用路由元信息中的meta字段设置变量,方便在各个位置获取。这就是为什么在meta中定义isBack // 参考 https://router.vuejs.org/zh-cn/advanced/meta.html if(from.name=='page2'){ to.meta.isBack=true; //判断是从哪个路由过来的, //如果是page2过来的,表明当前页面不需要刷新获取新数据,直接用之前缓存的数据即可 } next(); },
-
-
Выполните метод getData для получения данных в активированном
-
Потому что эту страницу нужно кэшировать. Созданные и смонтированные методы будут выполняться только при первом входе и не будут выполняться при повторном входе. И активировано выполняется каждый раз, когда он входит, поэтому получите данные в этой функции ловушки.
activated() { if(!this.$route.meta.isBack){ // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据 this.getData(); } // 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据 this.$route.meta.isBack=false },
-
-
Это оно?
-
Когда это настроено, вы можете выполнить его, и, похоже, все в порядке. При первом входе на страницу 1 вы можете получить новые данные, а при возврате со страницы 2 вы больше не получаете новые данные, а используете ранее кэшированные данные. Но есть еще проблема: когда пользователь заходит на страницу2 со страницы1, по какой-то причине страница страницы2 обновляется вручную. В это время я вернулся на страницу1 и обнаружил, что ранее закешированные данные были утеряны и больше не восстанавливались. Поэтому нам нужно добавить еще одно условие оценки: когда пользователь вручную обновляет страницу, а затем возвращается, ему нужно повторно получить данные.
-
Как добавить это условие, чтобы определить, обновил ли пользователь страницу? Мы знаем, что при использовании keep-alive созданная функция ловушки сработает только после первого входа, и после повторного входа она не будет выполняться снова. Когда пользователь обновляет страницу, эта функция ловушки будет выполняться снова, поэтому мы можем использовать этот небольшой трюк для создания некоторых статей.
-
Переменная isFirstEnter, определенная в данных, используется для определения того, является ли это первым входом или обновлением страницы. По умолчанию установлено значение false.
data() { return { msg: "我是第一个页面", str: "", // 加载页面后执行获取数据的方法,插入到此 isFirstEnter:false // 是否第一次进入,默认false }; },
-
Измените isFirstEnter на true в created, указав, что это первый раз, когда вы входите или обновляете страницу.
created() { this.isFirstEnter=true; // 只有第一次进入或者刷新页面后才会执行此钩子函数 // 使用keep-alive后(2+次)进入不会再执行此钩子函数 },
-
Добавить условия оценки в активированном
activated() { if(!this.$route.meta.isBack || this.isFirstEnter){ // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据 // 如果isFirstEnter是true,表明是第一次进入此页面或用户刷新了页面,需获取新数据 this.str=''// 把数据清空,可以稍微避免让用户看到之前缓存的数据 this.getData(); } // 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据 this.$route.meta.isBack=false // 恢复成默认的false,避免isBack一直是true,导致每次都获取新数据 this.isFirstEnter=false; },
-
Это должно сделать это
-
-
-
Метод записи, не требующий кэширования страниц
Примечание: Для страницы 3 в демо эта страница не нуждается в кешировании, вы можете написать ее как хотите, и никаких специальных настроек не требуется.
Другие настройки:
После использования keep-alive может возникнуть небольшая проблема: вторая страница может наследовать высоту полосы прокрутки первой страницы. (Встречается в моем проекте) Например: после того, как страница 1 прокручивается вниз, а затем переходит на страницу 2, полоса прокрутки страницы 2 может быть предыдущей высоты и может не быть вверху.
-
Решение состоит в том, чтобы записывать высоту полосы прокрутки каждый раз при выходе, а при повторном входе восстанавливать предыдущую высоту в соответствии с потребностями проекта или устанавливать ее наверх.
-
Решение 2 (рекомендуется)
Добавьте следующий код в router/index.js (если вы не понимаете, см. справочную ссылку)
Ссылаться на:Режим истории HTML5поведение при прокруткеmode: 'history', scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } }
Пункт вопроса:
В этом демонстрационном упражнении я напечатал порядок выполнения функции ловушки и нашел вопрос (у меня очень простое понимание функции ловушки):
При входе на страницу 2 со страницы 1 сначала выполняются методы beforeRouteEnter и created страницы 2, а затем выполняется деактивированный метод страницы 1.
Поэтому я активировал эти два параметра инициализации, а не деактивировал их.
this.$route.meta.isBack=false;
this.isFirstEnter=false;
Заключительные замечания:
Чтобы решить эту проблему, обновление вперед не обновляет назад, я волновался всю неделю, как и многие способы, которые не удалось решить. Последний комплексный опыт у разных начальников, проверенный много раз, объяснял это относительно «низким» подходом.
В настоящее время я также являюсь Vue Xiaobai, и я также исследую и двигаюсь вперед.Если этот метод может решить проблемы, с которыми вы сталкиваетесь, я очень рад. Если вы думаете, что это действительно низко, пожалуйста, слегка распылите.
Демо находится на GitHub ниже, добро пожаловать в звезду.
Комментарии и предложения также приветствуются, спасибо