mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-13 04:18:55 +08:00
refactor: 四端完成 Options API → script setup + vuex → pinia 迁移
- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup> - 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录) - util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入 - 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md) - 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API - 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
@@ -12,17 +12,11 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import config from "@/config/index";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
year: new Date().getFullYear(),
|
||||
};
|
||||
},
|
||||
};
|
||||
const year = ref(new Date().getFullYear());
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -6,50 +6,46 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { getBaseSite } from "@/api/common.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
domainLogo: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
applyFavicon(href) {
|
||||
if (!href) return;
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = href;
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
},
|
||||
getSite() {
|
||||
getBaseSite().then((res) => {
|
||||
if (res.success && res.result && res.result.settingValue) {
|
||||
const { domainLogo, domainIcon, siteName } = JSON.parse(
|
||||
res.result.settingValue
|
||||
);
|
||||
this.domainLogo = domainLogo || "";
|
||||
const expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||
localStorage.setItem("icontitle_expiration_time", expirationTime);
|
||||
localStorage.setItem("icon", domainLogo || "");
|
||||
localStorage.setItem("domainIcon", domainIcon || "");
|
||||
localStorage.setItem("title", siteName || "");
|
||||
this.applyFavicon(domainIcon || domainLogo);
|
||||
if (siteName) {
|
||||
window.document.title = siteName + " - 运营后台";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getSite();
|
||||
},
|
||||
};
|
||||
const domainLogo = ref("");
|
||||
|
||||
function applyFavicon(href) {
|
||||
if (!href) return;
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = href;
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
}
|
||||
|
||||
function getSite() {
|
||||
getBaseSite().then((res) => {
|
||||
if (res.success && res.result && res.result.settingValue) {
|
||||
const { domainLogo: logo, domainIcon, siteName } = JSON.parse(
|
||||
res.result.settingValue
|
||||
);
|
||||
domainLogo.value = logo || "";
|
||||
const expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||
localStorage.setItem("icontitle_expiration_time", expirationTime);
|
||||
localStorage.setItem("icon", logo || "");
|
||||
localStorage.setItem("domainIcon", domainIcon || "");
|
||||
localStorage.setItem("title", siteName || "");
|
||||
applyFavicon(domainIcon || logo);
|
||||
if (siteName) {
|
||||
window.document.title = siteName + " - 运营后台";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getSite();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -12,19 +12,19 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { Platform } from "@element-plus/icons-vue";
|
||||
import i18n from "@/locale";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
|
||||
export default {
|
||||
name: "langSwitch",
|
||||
components: { Platform },
|
||||
methods: {
|
||||
langChange(v) {
|
||||
this.$i18n.locale = v;
|
||||
this.$store.commit("switchLang", v);
|
||||
},
|
||||
},
|
||||
};
|
||||
defineOptions({ name: "langSwitch" });
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
function langChange(v) {
|
||||
i18n.global.locale = v;
|
||||
appStore.switchLang(v);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -40,42 +40,42 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ArrowDown } from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
name: "messageTip",
|
||||
components: { ArrowDown },
|
||||
props: {
|
||||
res: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
defineOptions({ name: "messageTip" });
|
||||
|
||||
const props = defineProps({
|
||||
res: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
computed: {
|
||||
value() {
|
||||
let count = 0;
|
||||
const r = this.res || {};
|
||||
Object.keys(r).forEach((k) => {
|
||||
if (r[k]) count += r[k];
|
||||
});
|
||||
return count;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
navigateTo(name) {
|
||||
if (name === "manager-appointment-work-orders") {
|
||||
this.$router.push({ name, query: { serviceStatus: "OPEN" } });
|
||||
return;
|
||||
}
|
||||
if (name === "manager-procurement-order-list") {
|
||||
this.$router.push({ name, query: { status: "SUBMITTED" } });
|
||||
return;
|
||||
}
|
||||
this.$router.push({ name });
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const value = computed(() => {
|
||||
let count = 0;
|
||||
const r = props.res || {};
|
||||
Object.keys(r).forEach((k) => {
|
||||
if (r[k]) count += r[k];
|
||||
});
|
||||
return count;
|
||||
});
|
||||
|
||||
function navigateTo(name) {
|
||||
if (name === "manager-appointment-work-orders") {
|
||||
router.push({ name, query: { serviceStatus: "OPEN" } });
|
||||
return;
|
||||
}
|
||||
if (name === "manager-procurement-order-list") {
|
||||
router.push({ name, query: { status: "SUBMITTED" } });
|
||||
return;
|
||||
}
|
||||
router.push({ name });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -109,4 +109,3 @@ export default {
|
||||
transform: translateY(-50%) translateX(50%);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -18,8 +18,17 @@
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { otherRouter } from "@/router/router";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
|
||||
defineOptions({ name: "pageBreadcrumb" });
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const stripLayout = (name) => (name || "").replace(/__layout$/, "");
|
||||
|
||||
@@ -61,105 +70,101 @@ const findFirstLeaf = (group) => {
|
||||
return stripLayout(first?.name) || null;
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "pageBreadcrumb",
|
||||
computed: {
|
||||
items() {
|
||||
const route = this.$route;
|
||||
if (!route || !route.name || route.name === "home_index") {
|
||||
return [{ title: "首页" }];
|
||||
}
|
||||
return this.buildChain(stripLayout(route.name));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
go(target) {
|
||||
if (!target || !target.name) return;
|
||||
if (this.$route.name === target.name) return;
|
||||
this.$router.push(target);
|
||||
},
|
||||
findInMenu(name) {
|
||||
const menuList = this.$store.state.app.menuList || [];
|
||||
for (const grp of menuList) {
|
||||
for (const child of grp.children || []) {
|
||||
if (stripLayout(child.name) === name) {
|
||||
return { group: grp, child };
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
routerEntry(name) {
|
||||
if (Array.isArray(otherRouter.children)) {
|
||||
return otherRouter.children.find((c) => c.name === name);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
topItem() {
|
||||
const navList = this.$store.state.app.navList || [];
|
||||
const menuList = this.$store.state.app.menuList || [];
|
||||
const currNavTitle = this.$store.state.app.currNavTitle;
|
||||
const firstName =
|
||||
this.$route.meta && this.$route.meta.firstRouterName;
|
||||
const items = computed(() => {
|
||||
if (!route || !route.name || route.name === "home_index") {
|
||||
return [{ title: "首页" }];
|
||||
}
|
||||
return buildChain(stripLayout(route.name));
|
||||
});
|
||||
|
||||
let topTitle = currNavTitle;
|
||||
if (firstName) {
|
||||
const top = navList.find((n) => n.name === firstName);
|
||||
if (top) topTitle = top.title;
|
||||
function go(target) {
|
||||
if (!target || !target.name) return;
|
||||
if (route.name === target.name) return;
|
||||
router.push(target);
|
||||
}
|
||||
|
||||
function findInMenu(name) {
|
||||
const menuList = appStore.menuList || [];
|
||||
for (const grp of menuList) {
|
||||
for (const child of grp.children || []) {
|
||||
if (stripLayout(child.name) === name) {
|
||||
return { group: grp, child };
|
||||
}
|
||||
if (!topTitle) return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
let target = null;
|
||||
if (menuList && menuList.length) {
|
||||
const leafName = findFirstLeaf(menuList[0]);
|
||||
if (leafName) target = { name: leafName };
|
||||
}
|
||||
return { title: topTitle, target };
|
||||
},
|
||||
buildChain(name, depth = 0) {
|
||||
if (depth > 6) return [];
|
||||
function routerEntry(name) {
|
||||
if (Array.isArray(otherRouter.children)) {
|
||||
return otherRouter.children.find((c) => c.name === name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const inMenu = this.findInMenu(name);
|
||||
if (inMenu) {
|
||||
const list = [];
|
||||
const top = this.topItem();
|
||||
if (top) list.push(top);
|
||||
const groupLeaf = findFirstLeaf(inMenu.group);
|
||||
list.push({
|
||||
title: inMenu.group.title,
|
||||
target: groupLeaf ? { name: groupLeaf } : null,
|
||||
});
|
||||
list.push({ title: inMenu.child.title });
|
||||
return list;
|
||||
}
|
||||
function topItem() {
|
||||
const navList = appStore.navList || [];
|
||||
const menuList = appStore.menuList || [];
|
||||
const currNavTitle = appStore.currNavTitle;
|
||||
const firstName = route.meta && route.meta.firstRouterName;
|
||||
|
||||
const parentName = PARENT_MAP[name];
|
||||
const entry = this.routerEntry(name);
|
||||
const selfTitle = entry?.title
|
||||
? entry.title
|
||||
: (this.$route.meta && this.$route.meta.title
|
||||
? String(this.$route.meta.title).replace(/\s*-\s*.+$/, "")
|
||||
: "");
|
||||
let topTitle = currNavTitle;
|
||||
if (firstName) {
|
||||
const top = navList.find((n) => n.name === firstName);
|
||||
if (top) topTitle = top.title;
|
||||
}
|
||||
if (!topTitle) return null;
|
||||
|
||||
if (parentName) {
|
||||
const parentChain = this.buildChain(parentName, depth + 1).map(
|
||||
(it, idx, arr) =>
|
||||
idx === arr.length - 1
|
||||
? { title: it.title, target: { name: parentName } }
|
||||
: it
|
||||
);
|
||||
if (selfTitle) parentChain.push({ title: selfTitle });
|
||||
return parentChain;
|
||||
}
|
||||
let target = null;
|
||||
if (menuList && menuList.length) {
|
||||
const leafName = findFirstLeaf(menuList[0]);
|
||||
if (leafName) target = { name: leafName };
|
||||
}
|
||||
return { title: topTitle, target };
|
||||
}
|
||||
|
||||
const list = [];
|
||||
const top = this.topItem();
|
||||
if (top) list.push(top);
|
||||
if (selfTitle) list.push({ title: selfTitle });
|
||||
return list;
|
||||
},
|
||||
},
|
||||
};
|
||||
function buildChain(name, depth = 0) {
|
||||
if (depth > 6) return [];
|
||||
|
||||
const inMenu = findInMenu(name);
|
||||
if (inMenu) {
|
||||
const list = [];
|
||||
const top = topItem();
|
||||
if (top) list.push(top);
|
||||
const groupLeaf = findFirstLeaf(inMenu.group);
|
||||
list.push({
|
||||
title: inMenu.group.title,
|
||||
target: groupLeaf ? { name: groupLeaf } : null,
|
||||
});
|
||||
list.push({ title: inMenu.child.title });
|
||||
return list;
|
||||
}
|
||||
|
||||
const parentName = PARENT_MAP[name];
|
||||
const entry = routerEntry(name);
|
||||
const selfTitle = entry?.title
|
||||
? entry.title
|
||||
: (route.meta && route.meta.title
|
||||
? String(route.meta.title).replace(/\s*-\s*.+$/, "")
|
||||
: "");
|
||||
|
||||
if (parentName) {
|
||||
const parentChain = buildChain(parentName, depth + 1).map(
|
||||
(it, idx, arr) =>
|
||||
idx === arr.length - 1
|
||||
? { title: it.title, target: { name: parentName } }
|
||||
: it
|
||||
);
|
||||
if (selfTitle) parentChain.push({ title: selfTitle });
|
||||
return parentChain;
|
||||
}
|
||||
|
||||
const list = [];
|
||||
const top = topItem();
|
||||
if (top) list.push(top);
|
||||
if (selfTitle) list.push({ title: selfTitle });
|
||||
return list;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -31,88 +31,90 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed, nextTick, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { setStore } from "@/libs/storage";
|
||||
import { Message } from "@/utils/message";
|
||||
import util from "@/libs/util.js";
|
||||
|
||||
export default {
|
||||
name: "shrinkableMenu",
|
||||
computed: {
|
||||
menuList() {
|
||||
return this.$store.state.app.menuList;
|
||||
},
|
||||
navList() {
|
||||
return this.$store.state.app.navList;
|
||||
},
|
||||
currNav() {
|
||||
return this.$store.state.app.currNav;
|
||||
},
|
||||
activeMenuName() {
|
||||
const route = this.$route;
|
||||
const routePath = util.normalizeRoutePath(route.path);
|
||||
for (const item of this.menuList) {
|
||||
for (const menu of item.children || []) {
|
||||
const menuPath = util.normalizeRoutePath(menu.path);
|
||||
if (menu.name === route.name || (menuPath && menuPath === routePath)) {
|
||||
return menu.name;
|
||||
}
|
||||
}
|
||||
defineOptions({ name: "shrinkableMenu" });
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const menuList = computed(() => appStore.menuList);
|
||||
const navList = computed(() => appStore.navList);
|
||||
const currNav = computed(() => appStore.currNav);
|
||||
const activeMenuName = computed(() => {
|
||||
const routePath = util.normalizeRoutePath(route.path);
|
||||
for (const item of menuList.value) {
|
||||
for (const menu of item.children || []) {
|
||||
const menuPath = util.normalizeRoutePath(menu.path);
|
||||
if (menu.name === route.name || (menuPath && menuPath === routePath)) {
|
||||
return menu.name;
|
||||
}
|
||||
return route.name;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route(val) {
|
||||
if (
|
||||
val.meta.firstRouterName &&
|
||||
val.meta.firstRouterName !== this.currNav
|
||||
) {
|
||||
this.selectNav(val.meta.firstRouterName);
|
||||
}
|
||||
}
|
||||
return route.name;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.fullPath,
|
||||
() => {
|
||||
if (
|
||||
route.meta.firstRouterName &&
|
||||
route.meta.firstRouterName !== currNav.value
|
||||
) {
|
||||
selectNav(route.meta.firstRouterName);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const changeMenu = (name) => {
|
||||
if (!name) return;
|
||||
if (router.hasRoute(name)) {
|
||||
router.push({ name });
|
||||
return;
|
||||
}
|
||||
const menu = findMenuByName(name);
|
||||
if (menu?.path) {
|
||||
const path = menu.path.startsWith("/") ? menu.path : `/${menu.path}`;
|
||||
router.push({ path });
|
||||
return;
|
||||
}
|
||||
util.initRouter();
|
||||
nextTick(() => {
|
||||
if (router.hasRoute(name)) {
|
||||
router.push({ name });
|
||||
} else {
|
||||
Message.warning("菜单路由未就绪,请刷新页面后重试");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const findMenuByName = (name) => {
|
||||
for (const item of menuList.value) {
|
||||
for (const menu of item.children || []) {
|
||||
if (menu.name === name) {
|
||||
return menu;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
changeMenu(name) {
|
||||
if (!name) return;
|
||||
if (this.$router.hasRoute(name)) {
|
||||
this.$router.push({ name });
|
||||
return;
|
||||
}
|
||||
const menu = this.findMenuByName(name);
|
||||
if (menu?.path) {
|
||||
const path = menu.path.startsWith("/") ? menu.path : `/${menu.path}`;
|
||||
this.$router.push({ path });
|
||||
return;
|
||||
}
|
||||
util.initRouter(this);
|
||||
this.$nextTick(() => {
|
||||
if (this.$router.hasRoute(name)) {
|
||||
this.$router.push({ name });
|
||||
} else {
|
||||
this.$Message.warning("菜单路由未就绪,请刷新页面后重试");
|
||||
}
|
||||
});
|
||||
},
|
||||
findMenuByName(name) {
|
||||
for (const item of this.menuList) {
|
||||
for (const menu of item.children || []) {
|
||||
if (menu.name === name) {
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
selectNav(name) {
|
||||
this.$store.commit("setCurrNav", name);
|
||||
this.setStore("currNav", name);
|
||||
if (name === 'home_index') {
|
||||
this.$store.commit("updateMenulist", []);
|
||||
this.$router.push({ name: 'home_index' });
|
||||
return;
|
||||
}
|
||||
util.initRouter(this);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const selectNav = (name) => {
|
||||
appStore.setCurrNav(name);
|
||||
setStore("currNav", name);
|
||||
if (name === 'home_index') {
|
||||
appStore.updateMenulist([]);
|
||||
router.push({ name: 'home_index' });
|
||||
return;
|
||||
}
|
||||
util.initRouter();
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -41,160 +41,179 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, watch, onBeforeUnmount } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import util from "@/libs/util.js";
|
||||
|
||||
export default {
|
||||
name: "tagsPageOpened",
|
||||
props: {
|
||||
pageTagsList: Array,
|
||||
beforePush: {
|
||||
type: Function,
|
||||
default: () => true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentPageName: this.$route.name,
|
||||
tagBodyLeft: 0,
|
||||
visible: false,
|
||||
contextMenuLeft: 0,
|
||||
contextMenuTop: 0,
|
||||
actionList: {
|
||||
others: "关闭其他",
|
||||
clearAll: "关闭所有",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isActive(item) {
|
||||
const target = item.children ? item.children[0] : item;
|
||||
return util.isSameRoutePage(target, {
|
||||
name: this.currentPageName,
|
||||
path: this.$route.path,
|
||||
});
|
||||
},
|
||||
tagType(item) {
|
||||
return this.isActive(item) ? "primary" : "info";
|
||||
},
|
||||
itemTitle(item) {
|
||||
if (typeof item.title === "object") {
|
||||
return this.$t(item.title.i18n);
|
||||
}
|
||||
return item.title;
|
||||
},
|
||||
closePage(event, name) {
|
||||
let pageOpenedList = this.$store.state.app.pageOpenedList;
|
||||
let lastPageObj = pageOpenedList[0];
|
||||
if (this.currentPageName === name) {
|
||||
const len = pageOpenedList.length;
|
||||
for (let i = 1; i < len; i++) {
|
||||
if (pageOpenedList[i].name === name) {
|
||||
lastPageObj =
|
||||
i < len - 1 ? pageOpenedList[i + 1] : pageOpenedList[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (event && event.target) {
|
||||
const tagWidth = event.target.parentNode?.offsetWidth || 0;
|
||||
this.tagBodyLeft = Math.min(this.tagBodyLeft + tagWidth, 0);
|
||||
}
|
||||
this.$store.commit("removeTag", name);
|
||||
this.$store.commit("closePage", name);
|
||||
pageOpenedList = this.$store.state.app.pageOpenedList;
|
||||
localStorage.pageOpenedList = JSON.stringify(pageOpenedList);
|
||||
if (this.currentPageName === name) {
|
||||
this.linkTo(lastPageObj);
|
||||
}
|
||||
},
|
||||
linkTo(item) {
|
||||
const target = item.children ? item.children[0] : item;
|
||||
if (util.isSameRoutePage(target, this.$route)) return;
|
||||
if (!this.beforePush(item)) return;
|
||||
defineOptions({ name: "tagsPageOpened" });
|
||||
|
||||
const routerObj = { name: item.name };
|
||||
if (item.argu) routerObj.params = item.argu;
|
||||
if (item.query) routerObj.query = item.query;
|
||||
const props = defineProps({
|
||||
pageTagsList: Array,
|
||||
beforePush: {
|
||||
type: Function,
|
||||
default: () => true,
|
||||
},
|
||||
});
|
||||
|
||||
if (item.name && this.$router.hasRoute(item.name)) {
|
||||
this.$router.push(routerObj);
|
||||
return;
|
||||
}
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const path = target.path || item.path;
|
||||
if (path) {
|
||||
this.$router.push({
|
||||
path: path.startsWith("/") ? path : `/${path}`,
|
||||
query: item.query,
|
||||
});
|
||||
}
|
||||
},
|
||||
handlescroll(e) {
|
||||
const type = e.type;
|
||||
let delta = 0;
|
||||
if (type === "DOMMouseScroll" || type === "mousewheel") {
|
||||
delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0) * 40;
|
||||
}
|
||||
let left = 0;
|
||||
if (delta > 0) {
|
||||
left = Math.min(0, this.tagBodyLeft + delta);
|
||||
} else if (
|
||||
this.$refs.scrollCon.offsetWidth - 100 <
|
||||
this.$refs.scrollBody.offsetWidth
|
||||
) {
|
||||
if (
|
||||
this.tagBodyLeft <
|
||||
-(this.$refs.scrollBody.offsetWidth - this.$refs.scrollCon.offsetWidth + 100)
|
||||
) {
|
||||
left = this.tagBodyLeft;
|
||||
} else {
|
||||
left = Math.max(
|
||||
this.tagBodyLeft + delta,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
this.$refs.scrollBody.offsetWidth -
|
||||
100
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.tagBodyLeft = 0;
|
||||
}
|
||||
this.tagBodyLeft = left;
|
||||
},
|
||||
handleTagsOption(type) {
|
||||
if (type === "clearAll") {
|
||||
this.$store.commit("clearAllTags");
|
||||
this.$router.push({ name: "home_index" });
|
||||
} else {
|
||||
this.$store.commit("clearOtherTags", this);
|
||||
}
|
||||
this.tagBodyLeft = 0;
|
||||
},
|
||||
contextMenu(item, e) {
|
||||
this.visible = true;
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left;
|
||||
this.contextMenuLeft = e.clientX - offsetLeft + 10;
|
||||
this.contextMenuTop = e.clientY - 64;
|
||||
},
|
||||
closeMenu() {
|
||||
this.visible = false;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route(to) {
|
||||
this.currentPageName = to.name;
|
||||
},
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener("click", this.closeMenu);
|
||||
} else {
|
||||
document.body.removeEventListener("click", this.closeMenu);
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.body.removeEventListener("click", this.closeMenu);
|
||||
},
|
||||
const currentPageName = ref(route.name);
|
||||
const tagBodyLeft = ref(0);
|
||||
const visible = ref(false);
|
||||
const contextMenuLeft = ref(0);
|
||||
const contextMenuTop = ref(0);
|
||||
const actionList = {
|
||||
others: "关闭其他",
|
||||
clearAll: "关闭所有",
|
||||
};
|
||||
|
||||
const scrollCon = ref(null);
|
||||
const scrollBody = ref(null);
|
||||
|
||||
const isActive = (item) => {
|
||||
const target = item.children ? item.children[0] : item;
|
||||
return util.isSameRoutePage(target, {
|
||||
name: currentPageName.value,
|
||||
path: route.path,
|
||||
});
|
||||
};
|
||||
|
||||
const tagType = (item) => {
|
||||
return isActive(item) ? "primary" : "info";
|
||||
};
|
||||
|
||||
const itemTitle = (item) => {
|
||||
if (typeof item.title === "object") {
|
||||
return t(item.title.i18n);
|
||||
}
|
||||
return item.title;
|
||||
};
|
||||
|
||||
const closePage = (event, name) => {
|
||||
let pageOpenedList = appStore.pageOpenedList;
|
||||
let lastPageObj = pageOpenedList[0];
|
||||
if (currentPageName.value === name) {
|
||||
const len = pageOpenedList.length;
|
||||
for (let i = 1; i < len; i++) {
|
||||
if (pageOpenedList[i].name === name) {
|
||||
lastPageObj =
|
||||
i < len - 1 ? pageOpenedList[i + 1] : pageOpenedList[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (event && event.target) {
|
||||
const tagWidth = event.target.parentNode?.offsetWidth || 0;
|
||||
tagBodyLeft.value = Math.min(tagBodyLeft.value + tagWidth, 0);
|
||||
}
|
||||
appStore.removeTag(name);
|
||||
appStore.closePage(name);
|
||||
pageOpenedList = appStore.pageOpenedList;
|
||||
localStorage.pageOpenedList = JSON.stringify(pageOpenedList);
|
||||
if (currentPageName.value === name) {
|
||||
linkTo(lastPageObj);
|
||||
}
|
||||
};
|
||||
|
||||
const linkTo = (item) => {
|
||||
const target = item.children ? item.children[0] : item;
|
||||
if (util.isSameRoutePage(target, route)) return;
|
||||
if (!props.beforePush(item)) return;
|
||||
|
||||
const routerObj = { name: item.name };
|
||||
if (item.argu) routerObj.params = item.argu;
|
||||
if (item.query) routerObj.query = item.query;
|
||||
|
||||
if (item.name && router.hasRoute(item.name)) {
|
||||
router.push(routerObj);
|
||||
return;
|
||||
}
|
||||
|
||||
const path = target.path || item.path;
|
||||
if (path) {
|
||||
router.push({
|
||||
path: path.startsWith("/") ? path : `/${path}`,
|
||||
query: item.query,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handlescroll = (e) => {
|
||||
const type = e.type;
|
||||
let delta = 0;
|
||||
if (type === "DOMMouseScroll" || type === "mousewheel") {
|
||||
delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0) * 40;
|
||||
}
|
||||
let left = 0;
|
||||
if (delta > 0) {
|
||||
left = Math.min(0, tagBodyLeft.value + delta);
|
||||
} else if (
|
||||
scrollCon.value.offsetWidth - 100 <
|
||||
scrollBody.value.offsetWidth
|
||||
) {
|
||||
if (
|
||||
tagBodyLeft.value <
|
||||
-(scrollBody.value.offsetWidth - scrollCon.value.offsetWidth + 100)
|
||||
) {
|
||||
left = tagBodyLeft.value;
|
||||
} else {
|
||||
left = Math.max(
|
||||
tagBodyLeft.value + delta,
|
||||
scrollCon.value.offsetWidth -
|
||||
scrollBody.value.offsetWidth -
|
||||
100
|
||||
);
|
||||
}
|
||||
} else {
|
||||
tagBodyLeft.value = 0;
|
||||
}
|
||||
tagBodyLeft.value = left;
|
||||
};
|
||||
|
||||
const handleTagsOption = (type) => {
|
||||
if (type === "clearAll") {
|
||||
appStore.clearAllTags();
|
||||
router.push({ name: "home_index" });
|
||||
} else {
|
||||
appStore.clearOtherTags(route.name);
|
||||
}
|
||||
tagBodyLeft.value = 0;
|
||||
};
|
||||
|
||||
const contextMenu = (item, e) => {
|
||||
visible.value = true;
|
||||
const offsetLeft = scrollCon.value.getBoundingClientRect().left;
|
||||
contextMenuLeft.value = e.clientX - offsetLeft + 10;
|
||||
contextMenuTop.value = e.clientY - 64;
|
||||
};
|
||||
|
||||
const closeMenu = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
(name) => {
|
||||
currentPageName.value = name;
|
||||
}
|
||||
);
|
||||
|
||||
watch(visible, (value) => {
|
||||
if (value) {
|
||||
document.body.addEventListener("click", closeMenu);
|
||||
} else {
|
||||
document.body.removeEventListener("click", closeMenu);
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.body.removeEventListener("click", closeMenu);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user