fix(plugin-layout): 打开相同path的链接会更新页签为新的 & 正确触发onActivated (#146)

* feat: script setup 支持 defineRouteMeta (#144)

* chore(release): publish

 - @fesjs/preset-built-in@2.1.4
 - @fesjs/fes@2.1.4

* fix: 打开相同path的链接会更新route & 第一次打开会触发onActivated (#145)

* fix: 打开相同path的链接会更新route & 第一次打开会触发onActivated

* fix: 优化

* chore(release): publish

 - @fesjs/plugin-layout@4.2.3

Co-authored-by: qlin <haizekuo@gmail.com>
This commit is contained in:
harrywan 2022-08-12 10:19:27 +08:00 committed by GitHub
parent fa7789653c
commit 86ff19b3d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 56 deletions

View File

@ -21,9 +21,9 @@
</FDropdown> </FDropdown>
</template> </template>
</FTabs> </FTabs>
<Page :nameList="keepAlivePages" :pageKey="getPageKey" isAllKeepAlive /> <Page ref="pageRef" :pageKey="getPageKey" isAllKeepAlive />
</template> </template>
<Page v-else :nameList="keepAlivePages" /> <Page v-else />
</template> </template>
<script> <script>
import { computed, unref, ref } from 'vue'; import { computed, unref, ref } from 'vue';
@ -48,6 +48,9 @@ export default {
multiTabs: Boolean, multiTabs: Boolean,
}, },
setup() { setup() {
const pageRef = ref();
const route = useRoute();
const router = useRouter();
const createPage = (_route) => { const createPage = (_route) => {
const title = _route.meta.title; const title = _route.meta.title;
return { return {
@ -58,10 +61,7 @@ export default {
key: getKey(), key: getKey(),
}; };
}; };
const keepAlivePages = ref([]);
const route = useRoute();
const router = useRouter();
const pageList = ref([createPage(route)]); const pageList = ref([createPage(route)]);
const actions = [ const actions = [
{ {
@ -77,11 +77,15 @@ export default {
const findPage = (path) => pageList.value.find((item) => unref(item.path) === unref(path)); const findPage = (path) => pageList.value.find((item) => unref(item.path) === unref(path));
router.beforeEach((to) => { router.beforeEach((to) => {
if (!findPage(to.path)) { const page = findPage(to.path);
if (!page) {
pageList.value = [...pageList.value, createPage(to)]; pageList.value = [...pageList.value, createPage(to)];
} else {
page.route = to;
} }
return true; return true;
}); });
// //
const switchPage = async (path) => { const switchPage = async (path) => {
const selectedPage = findPage(path); const selectedPage = findPage(path);
@ -108,12 +112,7 @@ export default {
} }
list.splice(index, 1); list.splice(index, 1);
pageList.value = list; pageList.value = list;
const _keepAlivePages = [...keepAlivePages.value]; pageRef.value.removeKeepAlive(selectedPage.name);
const keepIndex = _keepAlivePages.indexOf(selectedPage.name);
if (keepIndex !== -1) {
_keepAlivePages.splice(keepIndex, 1);
}
keepAlivePages.value = _keepAlivePages;
}; };
const reloadPage = (path) => { const reloadPage = (path) => {
const selectedPage = findPage(path || unref(route.path)); const selectedPage = findPage(path || unref(route.path));
@ -124,7 +123,7 @@ export default {
const closeOtherPage = (path) => { const closeOtherPage = (path) => {
const selectedPage = findPage(path || unref(route.path)); const selectedPage = findPage(path || unref(route.path));
pageList.value = [selectedPage]; pageList.value = [selectedPage];
keepAlivePages.value = [selectedPage.name]; pageRef.value.removeAllAndSaveKeepAlive(selectedPage.name);
}; };
const getPageKey = (_route) => { const getPageKey = (_route) => {
const selectedPage = findPage(_route.path); const selectedPage = findPage(_route.path);
@ -146,6 +145,7 @@ export default {
}; };
return { return {
pageRef,
route, route,
pageList, pageList,
getPageKey, getPageKey,
@ -154,7 +154,6 @@ export default {
handlerMore, handlerMore,
handleCloseTab, handleCloseTab,
actions, actions,
keepAlivePages,
}; };
}, },
}; };

View File

@ -1,21 +1,16 @@
<template> <template>
<router-view v-slot="{ Component, route }"> <router-view v-slot="{ Component, route }">
<keep-alive :include="currentNameList"> <keep-alive :include="keepAlivePages">
<component :is="getComponent(Component, route)" :key="pageKey(route)" /> <component :is="Component" :key="pageKey(route)" />
</keep-alive> </keep-alive>
</router-view> </router-view>
</template> </template>
<script> <script>
import { defineComponent, ref, watch } from 'vue'; import { useRouter, useRoute } from '@@/core/coreExports';
import { defineComponent, ref } from 'vue';
export default defineComponent({ export default defineComponent({
props: { props: {
nameList: {
type: Array,
default() {
return [];
},
},
pageKey: { pageKey: {
type: Function, type: Function,
default: () => {}, default: () => {},
@ -25,39 +20,57 @@ export default defineComponent({
default: false, default: false,
}, },
}, },
emits: ['update:nameList'], setup(props) {
setup(props, { emit }) { const route = useRoute();
const currentNameList = ref(props.nameList); const router = useRouter();
watch( function changePageComName(_route) {
() => props.nameList, if (_route.meta['keep-alive'] || props.isAllKeepAlive) {
() => { const matched = _route.matched;
if (currentNameList.value !== props.nameList) { const component = matched[matched.length - 1].components.default;
currentNameList.value = props.nameList; const name = _route.meta?.name ?? _route.name;
} if (name && component) {
},
);
const getComponent = (Component, route) => {
if (props.isAllKeepAlive || route.meta['keep-alive']) {
const name = route.meta?.name ?? route.name;
if (name) {
// name // name
Component.type.name = name;
// namekeep-aliveinclude // namekeep-aliveinclude
if (!currentNameList.value.includes(name)) { component.name = name;
currentNameList.value = [...currentNameList.value, name]; return name;
emit('update:nameList', currentNameList.value);
} }
} }
} }
return Component; function getInitAlivePage() {
const name = changePageComName(route);
return name ? [name] : [];
}
const keepAlivePages = ref(getInitAlivePage());
router.afterEach(() => {
// route
const name = changePageComName(route);
// namekeep-aliveinclude
if (!keepAlivePages.value.includes(name)) {
keepAlivePages.value = [...keepAlivePages.value, name];
}
});
const removeKeepAlive = (name) => {
const _keepAlivePages = [...keepAlivePages.value];
const keepIndex = _keepAlivePages.indexOf(name);
if (keepIndex !== -1) {
_keepAlivePages.splice(keepIndex, 1);
}
keepAlivePages.value = _keepAlivePages;
};
const removeAllAndSaveKeepAlive = (name) => {
keepAlivePages.value = [name];
}; };
return { return {
currentNameList, keepAlivePages,
getComponent, removeKeepAlive,
removeAllAndSaveKeepAlive,
}; };
}, },
}); });

View File

@ -1,7 +1,5 @@
<template> <template>
<div :class="$style.red"> <div :class="$style.red">字体颜色</div>
字体颜色
</div>
</template> </template>
<config> <config>
{ {
@ -13,7 +11,7 @@
export default { export default {
setup() { setup() {
return {}; return {};
} },
}; };
</script> </script>

View File

@ -5,8 +5,7 @@
<config> <config>
{ {
"name": "editor", "name": "editor",
"title": "$editor", "title": "$editor"
"keep-alive": true
} }
</config> </config>
<script> <script>

View File

@ -1,6 +1,7 @@
<template> <template>
<div class="page"> <div class="page">
<h4>Vuex</h4> <h4>Vuex</h4>
<input />
<div> <div>
<button @click="increment">click me{{ doubleCount }}</button> <button @click="increment">click me{{ doubleCount }}</button>
</div> </div>
@ -16,11 +17,12 @@
<config> <config>
{ {
"name": "store", "name": "store",
"title": "$store" "title": "$store",
"keep-alive": true
} }
</config> </config>
<script> <script>
import { computed, ref } from 'vue'; import { computed, ref, onMounted, onUnmounted, onActivated, onDeactivated } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import { MUTATION_TYPES, GETTER_TYPES, ACTION_TYPES } from '@fesjs/fes'; import { MUTATION_TYPES, GETTER_TYPES, ACTION_TYPES } from '@fesjs/fes';
@ -30,6 +32,23 @@ export default {
const store = useStore(); const store = useStore();
console.log('store==>', store); console.log('store==>', store);
const disabled = ref(false); const disabled = ref(false);
onMounted(() => {
console.log('onMounted');
});
onUnmounted(() => {
console.log('onUnmounted');
});
onActivated(() => {
console.log('onActivated');
});
onDeactivated(() => {
console.log('onDeactivated');
});
return { return {
address: computed(() => store.getters[GETTER_TYPES.user.address]), address: computed(() => store.getters[GETTER_TYPES.user.address]),
doubleCount: computed(() => store.getters[GETTER_TYPES.counter.doubleCount]), doubleCount: computed(() => store.getters[GETTER_TYPES.counter.doubleCount]),