1. keep-alive
-
вопрос:После использования тега keep-alive расположение страницы кеша, возвращаемой на некоторые устройства Android, является неточным.
-
решение:
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
const router = new Router({
scrollBehavior(to, from, savedPosition) {
if (savedPosition && to.meta.keepAlive) {
return savedPosition;
}
return { x: 0, y:0 };
},
});
2. Проблема с пустым экраном при возврате страницы
- вопрос
【前提】:iOS设备
【步骤】: 页面A是个列表很长-->滑到页脚的时候点击跳转之后到页面B--->再返回A页面
--->屏幕会出现空白遮罩层--->手指轻触屏幕滑动--->遮罩层消失
Решение первое
Эта операция выполняется после операции обратного вызова после успешного запроса интерфейса, например
// fetchCourseList是一个封装好的Promise请求
fetchCourseList().then(({ data: courses }) => {
this.courses = courses;
}).then(() => {
setTimeout(() => {
window.scrollTo(0, 1);
window.scrollTo(0, 0);
});
});
Недостатки этой схемы: Каждая страница должна выполнять такую обработку, что не рекомендуется.
Решение второе (рекомендуется)
Использование асинхронных операций прокрутки в scrollBehavior
const router = new Router({
scrollBehavior(to, from, savedPosition) {
// keep-alive 返回缓存页面后记录浏览位置
if (savedPosition && to.meta.keepAlive) {
return savedPosition;
}
// 异步滚动操作
return new Promise((resolve) => {
setTimeout(() => {
resolve({ x: 0, y: 1 });
}, 0);
});
},
});
Это решение обрабатывается непосредственно в маршрутизации, совместимо с каждой страницей и не создает позицию прокрутки в 1 пиксель после загрузки страницы.
Почему нельзя вернуться напрямую и нужно использовать асинхронную операцию прокрутки? Ниже приведены некоторые личные мнения, и я приглашаю всех обсудить и исправить.
-
Прежде всего, нам нужно понять, какой жизненный цикл компонента функция Scrollbehavior начинает выполнять. Здесь я предупреждаю каждого жизненного цикла компонента и функции Scrollbehavior, и результатом расследования: функция Scrollbehavior выполняется до того, как загружена непрерывная упадинат после установки жизненного цикла компонента.
-
В функции scrollBehavior верните { x:0, y:100} напрямую, и страница входа по-прежнему будет вверху. Почему не прокручивается до 100px? Угадайте: данные, возвращаемые асинхронным запросом в смонтированном состоянии, назначаются переменной a в данных.Переменная a вызывает сбой прокрутки, потому что двусторонняя привязка vue обновляет слой представления?
-
Чтобы проверить вышеприведенные догадки, установите данные статической страницы, которые были жестко запрограммированы на html. В функции scrollBehavior верните { x:0, y: 100} напрямую, и результат: при входе на страницу она будет прокручиваться до 100 пикселей. Доказательство: это как-то связано с операцией после возврата асинхронного запроса.
-
Затем поймите, что vue смонтировал и сделал перед периодами обновления. смонтированный период: data данные висели на странице. BeforeUpdate и период обновления: когда vue обнаруживает, что данные в данных изменились, он инициирует повторную визуализацию соответствующего компонента.
-
Согласно шагу 4. Асинхронный запрос, инициированный в течение смонтированного периода, не будет мешать последующей работе основного потока, поэтому функция scrollBehavior продолжит выполнение, если не сработает событие обратного вызова запроса (операция присваивания переменной a в данные не выполняются). Если вы сразу вернете { x:0, y:100} в это время. Это эквивалентно прокрутке перед выполнением события обратного вызова асинхронного запроса. После прокрутки начинает выполняться событие обратного вызова асинхронного запроса, и присваивается переменная a в данных, что приводит к повторному рендерингу компонента и возврату наверх. Весь процесс прокрутки прокручивается для исходной страницы данных данных, поэтому слой маски все равно будет отображаться.
-
Подводя итог вышесказанному: вы должны использовать асинхронную прокрутку, использовать setTimeout, чтобы выйти из основного потока и поместить событие обратного вызова в очередь. Поскольку moused выполняется раньше, чем функция scrollBehavior, событие обратного вызова асинхронного запроса входит в очередь первым, а затем событие обратного вызова setTimeout. По принципу «первым пришел – первым вышел». Сначала выполняется событие обратного вызова асинхронного запроса для присвоения переменной a в данных. На данный момент это эквивалентно статической странице, а затем мне просто нужно выполнить return { x: 0, y: 100 }. Это вызвало эффект прокрутки страницы до 100 пикселей. Но поскольку данные данных изменились, страница повторно отображается вверху. В настоящее время весь эффект касания и прокрутки был выполнен тайно, и слой маски больше не будет отображаться.