Другой способ: одностраничный vue, мультимаршрутизация, обновление вперед, назад без обновления

Vue.js vue-router

Цель: одностраничное приложение 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 ниже, добро пожаловать в звезду.
Комментарии и предложения также приветствуются, спасибо

GitHub