представлять
При использовании vue + vue-router для разработки SPA вы когда-нибудь сталкивались с такой ситуацией: когда мы переключаемся между страницей списка и страницей сведений, если страница списка не кэшируется, это будет вызывать каждый раз возврат со страницы сведений , страница со списком перезагрузится. Как показано ниже:
Внимательные друзья обнаружили, что при возврате на страницу списка со страницы сведений страница списка перегружается, и это явно нехорошо.В это время мы можем кэшировать страницу списка.
keep-alive реализует кэширование страниц
Не все страницы в нашем проекте нужно кэшировать, поэтому вот два метода кэширования по требованию:
метод первый:
Во-первых, настройте метаполе при определении маршрута и настройте поле KeepAlive в качестве маркера того, кэшируется ли страница:
routes:[{
path: '/search',
name: 'search',
component: search,
meta: {
title: '搜索列表页',
keepAlive: true // 标记列表页需要被缓存
}
},
{
path: '/detail',
name: 'detail',
component: detail,
meta: {
title: '详情页',
// 详情页不需要做缓存,所以不加keepAlive标记
}
}]
из-за<keep-alive>Компоненты не поддерживают директивы v-if, поэтому мы используем две в App.vue.<router-view>Способ записи через поле keepAlive текущего маршрута, чтобы определить, кэшировать ли страницу:
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
Метод два
использовать<keep-alive>который предоставилexcludeилиincludeвариант, здесь мы используемexclude, в App.vue:
<div id="app">
<keep-alive exclude="detail">
<router-view />
</keep-alive>
</div>
Следует отметить, что вы должны добавить к компоненту страницы соответствующее имя, например, в detail.vue:
<script>
export default {
name: 'detail', // 这个name要和keep-alive中的exclude选项值一致
...
}
</script>
Это означает, что все страницы в проекте будут кэшироваться, кроме компонента страницы, имя которого — detail.
Оптимизация особого случая:
Если страница сведений также сделалаkeep-alive, то при переключении страницы списка и страницы сведений положение прокрутки может влиять друг на друга.Routerпредоставить экземплярscrollBehaviorметод:
export default new Router({
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
},
routes: [...],
})
Показать результаты
Тем не менее, я надеюсь, что всякий раз, когда я захожу на страницу поиска с главной страницы, данные страницы должны быть сброшены обратно в исходное состояние.Есть ли какой-либо способ гибко контролировать, нужно ли сбрасывать данные страницы? В этот раз мне на ум пришла библиотека управления состоянием в экосистеме vue.vuex.
Сделайте страницы более гибкими с помощью vuex
анализ спроса:Нам нужен глобальный флаг, чтобы контролировать, нужно ли сбрасывать данные каждый раз, когда вводится страница кеша, простоvuexможет сделать это.
vex вверх
Установить
npm install vuex --save
настроить vuex
Чтобы облегчить дальнейшее обслуживание, можно создать каталог хранилища для хранения кода модуля vuex Структура каталога относится к следующему рисунку:
state.js:
const state = {
refreshSearch: true // 标记是否刷新搜索页
}
export default state
mutation.js
const matutaions = {
setRefreshSearch(state, flag) {
state.refreshSearch = flag
}
}
export default matutaions
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
Vue.use(Vuex)
export default new Vuex.Store({
state,
mutations
})
В файле ввода main.js:
import store from './store' //这里是指向store目录中的index.js
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Таким образом, мы эквивалентны созданию тега с vuex, чтобы определить, нужно ли сбрасывать страницу.
Произвольно сбросить данные на вашей кешированной странице
где сбросить
keep-aliveКомпонент имеет уникальный хук жизненного циклаactivated().activated()Будет вkeep-aliveвызывается каждый раз при активации компонента, аcreated()Он будет вызываться только один раз при создании и не будет вызываться при повторной активации. Так что здесь нам нужноactivated()Hook для сброса данных нашей страницы.
Сброс, если вы хотите сбросить в активированном ()
здесь, чтобы использоватьvuexсерединаrefreshSearchфлаг, чтобы определить, требуется ли сброс
search.vue: (это страница, которую необходимо кэшировать)
<script>
import {mapState, mapMutations} from 'vuex' //vuex提供的映射函数,用来简化代码的
export default {
activated() {
if (this.refreshSearch) {
// 若为true,则执行重置页面等相关操作
this.fetchData();
} else {
this.reset(true);
}
},
methods:{
fetchData() {
// 获取页面数据
},
...mapMutations({
reset: 'setRefreshSearch' // 将 `this.reset()` 映射为 `this.$store.commit('setRefreshSearch')`
})
},
computed: {
...mapState([
'refreshSearch' // 映射 this.refreshSearch 为 this.$store.state.refreshSearch
]),
}
}
</script>
Когда мы переходим со страницы поиска на страницу сведений, мы хотим, чтобы страница поиска кэшировалась, просто установите флаг в значение false:
methods: {
goDetail() {
this.reset(false) // 这样返回搜索页的时候,搜索页就不会重置数据了
this.$router.push({path: '/detail'})
},
...mapMutations({
reset: 'setRefreshSearch'
})
}
Когда мы переходим на страницу поиска с домашней страницы, мы хотим, чтобы данные страницы поиска сбрасывались, просто установите флаг в значение true:
methods: {
goSearch() {
this.reset(true) // 这样去搜索页时数据就会被重置了
this.$router.push({path: '/search'})
},
...mapMutations({
reset: 'setRefreshSearch'
})
}
Предварительный просмотр эффекта
Суммировать
В этой статье описывается использование по запросуkeep-alive, а с помощьюvuexконтролироватьkeep-aliveНужно ли сбрасывать и обновлять данные страницы компонента, надеюсь, это вам поможет.
Прикрепленный связанный портал знаний:
поддержка встроенного компонента vue
поведение прокрутки vue-router