|
@@ -0,0 +1,271 @@
|
|
|
+import {defineStore} from "pinia";
|
|
|
+import router from "@/router.js";
|
|
|
+import useEventEmitter from "@hooks/useEventEmitter.js";
|
|
|
+import commonUtil from "@utility/commonUtil.js";
|
|
|
+import tabBarOption from "@/tabBar.js";
|
|
|
+
|
|
|
+export const routerEventEmitter = useEventEmitter();
|
|
|
+const tabBar = tabBarOption.map(el => el.pathName) //tabbar页面;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @method defaultCurrentPagesFun 默认当前路由
|
|
|
+ * */
|
|
|
+const defaultCurrentPagesFun = () => {
|
|
|
+ let defaultCurrentPages = [];
|
|
|
+ if (tabBar.length) {
|
|
|
+ defaultCurrentPages = [{
|
|
|
+ pathName: tabBar[0],
|
|
|
+ params: [],
|
|
|
+ cache: true
|
|
|
+ }]
|
|
|
+ }
|
|
|
+ return defaultCurrentPages;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @method isNavigate 判断导航
|
|
|
+ * @param navigateInfo { String | JSON } 导航信息
|
|
|
+ * */
|
|
|
+const isNavigate = (navigateInfo) => {
|
|
|
+ let isTabBar = false;
|
|
|
+ let isNavStr = false;
|
|
|
+ if (commonUtil.isStr(navigateInfo)) {
|
|
|
+ isNavStr = true;
|
|
|
+ if (tabBar.includes(navigateInfo)) {
|
|
|
+ isTabBar = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ isNavStr = false;
|
|
|
+ if (tabBar.includes(navigateInfo.pathName)) {
|
|
|
+ isTabBar = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return [isTabBar, isNavStr];
|
|
|
+};
|
|
|
+
|
|
|
+const useRouterStore = defineStore('routerStore', {
|
|
|
+ state: () => ({
|
|
|
+ currentPages: defaultCurrentPagesFun(),//当前已跳转页面列表
|
|
|
+ historyPages: [] //当前已回退页面列表
|
|
|
+ }),
|
|
|
+ actions: {//actions是store的方法methods
|
|
|
+ /***
|
|
|
+ * @method navigateTo 保留当前页面,跳转某个页面,不能跳转跳转到tabBar页面
|
|
|
+ * @param navigateInfo { String | JSON } 导航信息
|
|
|
+ navigateInfo = pathName
|
|
|
+ navigateInfo = {
|
|
|
+ pathName:'', 路由名称
|
|
|
+ success: ()=>{} 路由跳转成功函数
|
|
|
+ }
|
|
|
+ * */
|
|
|
+ async navigateTo(navigateInfo) {
|
|
|
+ const [isTabBar, isNavStr] = isNavigate(navigateInfo);
|
|
|
+ if (!isTabBar) {
|
|
|
+ let pathName = isNavStr ? navigateInfo : navigateInfo.pathName;
|
|
|
+ await router.push(pathName);
|
|
|
+ this.update(pathName);
|
|
|
+ if (commonUtil.isFun(navigateInfo.success)) navigateInfo.success();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method navigateBack 关闭当前页面,返回上一页面或多级页面
|
|
|
+ * @param backInfo { Number | JSON } 导航信息 返回的页面数,默认1
|
|
|
+ backInfo={
|
|
|
+ delta: 1,
|
|
|
+ success: ()=>{} 路由跳转成功函数
|
|
|
+ }
|
|
|
+ * */
|
|
|
+ navigateBack(backInfo = 1) {
|
|
|
+ let delta = backInfo;
|
|
|
+ const backPageRouter = this.currentPages[this.currentPages.length - 2];
|
|
|
+ this.updateCacheStatus(backPageRouter.pathName);
|
|
|
+ //返回一个页面由路由监听处理,主要为了兼容浏览器自带的返回
|
|
|
+ if (commonUtil.isJson(backInfo)) {
|
|
|
+ delta = backInfo.delta || 1;
|
|
|
+ }
|
|
|
+ if (delta > 1) {
|
|
|
+ router.go(-delta);
|
|
|
+ this.delete(delta);
|
|
|
+ } else {
|
|
|
+ router.back();
|
|
|
+ }
|
|
|
+ // 返回页面,真实内容的渲染会慢一拍;这里用定时处理
|
|
|
+ if (commonUtil.isFun(backInfo.success)) {
|
|
|
+ const navigateBackTimeout = setTimeout(() => {
|
|
|
+ backInfo.success();
|
|
|
+ clearTimeout(navigateBackTimeout);
|
|
|
+ }, 30)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /***
|
|
|
+ * @method switchTabBar 跳转到tabBar页面,并关闭其他所有非tabBar页面
|
|
|
+ * @param navigateInfo { String | JSON } 导航信息
|
|
|
+ navigateInfo = pathName
|
|
|
+ navigateInfo = {
|
|
|
+ pathName:'', 路由名称
|
|
|
+ success: ()=>{} 路由跳转成功函数
|
|
|
+ }
|
|
|
+ * */
|
|
|
+ async switchTabBar(navigateInfo) {
|
|
|
+ const [isTabBar, isNavStr] = isNavigate(navigateInfo);
|
|
|
+ if (isTabBar) {
|
|
|
+ let pathName = isNavStr ? navigateInfo : navigateInfo.pathName;
|
|
|
+ await router.replace(pathName);
|
|
|
+ if (commonUtil.isFun(navigateInfo.success)) navigateInfo.success();
|
|
|
+ this.currentPages = [{
|
|
|
+ pathName: pathName,
|
|
|
+ params: [], //emit传递的参数集合
|
|
|
+ cache: true //页面是否缓存
|
|
|
+ }];
|
|
|
+ //跳转tabBar页,相当于重新开始路由跳转,需清空已回退页面列表
|
|
|
+ this.historyPages = [];
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /***
|
|
|
+ * @method redirectTo 关闭当前页面,跳转某个页面。但是不允许跳转到tabBar页面
|
|
|
+ * @param navigateInfo { String | JSON } 导航信息
|
|
|
+ navigateInfo = pathName
|
|
|
+ navigateInfo = {
|
|
|
+ pathName:'', 路由名称
|
|
|
+ success: ()=>{} 路由跳转成功函数
|
|
|
+ }
|
|
|
+ * */
|
|
|
+ async redirectTo(navigateInfo) {
|
|
|
+ const [isTabBar, isNavStr] = isNavigate(navigateInfo);
|
|
|
+ if (!isTabBar) {
|
|
|
+ let pathName = isNavStr ? navigateInfo : navigateInfo.pathName;
|
|
|
+ await router.replace(pathName);
|
|
|
+ if (commonUtil.isFun(navigateInfo.success)) navigateInfo.success();
|
|
|
+ this.deleteHistory(pathName);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method emit 触发特定事件,并依次调用与该事件关联的所有监听器函数
|
|
|
+ * @param eventName {String} 事件名
|
|
|
+ * @param par {Any} 传给监听事件的参数
|
|
|
+ * */
|
|
|
+ emit(eventName, par) {
|
|
|
+ const currentPage = this.currentPages[this.currentPages.length - 1];
|
|
|
+ const paramIndex = currentPage.params?.findIndex(el => Reflect.ownKeys(el)[0] == eventName)
|
|
|
+ if (paramIndex > -1) {
|
|
|
+ currentPage.params[paramIndex][eventName] = par;
|
|
|
+ } else {
|
|
|
+ currentPage.params.push({
|
|
|
+ [eventName]: par
|
|
|
+ })
|
|
|
+ }
|
|
|
+ routerEventEmitter.emit(`${location.pathname}.${eventName}`, par);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method on 事件监听器
|
|
|
+ * @param eventName {String} 事件名称
|
|
|
+ * @param callback {Function} 监听函数
|
|
|
+ * */
|
|
|
+ on(eventName, callback) {
|
|
|
+ if (eventName) {
|
|
|
+ routerEventEmitter.addOnceListener(`${location.pathname}.${eventName}`, callback);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method eventOn events事件绑定,主要用于页面返回传参
|
|
|
+ * @param eventName {String} 事件名称
|
|
|
+ * @param callback {Function} 监听函数
|
|
|
+ * */
|
|
|
+ eventOn(eventName, callback) {
|
|
|
+ this.on(`events.${eventName}`, callback);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method eventEmit events事件发射器,主要用于页面返回传参
|
|
|
+ * @param eventName {String} 事件名
|
|
|
+ * @param par {Any} 传给监听事件的参数
|
|
|
+ * */
|
|
|
+ eventEmit(eventName, par) {
|
|
|
+ routerEventEmitter.emit(`${location.pathname}.events.${eventName}`, par);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method update 更新路由
|
|
|
+ * @param pathName {String} 路由name
|
|
|
+ * */
|
|
|
+ update(pathName) {
|
|
|
+ const pageIndex = this.currentPages.findIndex((element) => element.pathName == pathName);
|
|
|
+ let routerInfo = {
|
|
|
+ pathName: pathName,
|
|
|
+ params: [], //emit传递的参数集合
|
|
|
+ cache: true //页面是否缓存
|
|
|
+ };
|
|
|
+ if (pageIndex > -1) {
|
|
|
+ //如果已存在路由直接替换原有信息
|
|
|
+ this.currentPages[pageIndex] = routerInfo;
|
|
|
+ } else {
|
|
|
+ //如果不存在路由添加路由信息
|
|
|
+ this.currentPages.push(routerInfo);
|
|
|
+ }
|
|
|
+ this.deleteHistory(pathName);
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method delete 移除页面路由
|
|
|
+ * @param delta {Number} 返回的页面数
|
|
|
+ * */
|
|
|
+ delete(delta) {
|
|
|
+ const historyPages = this.currentPages.splice(this.currentPages.length - delta, delta);
|
|
|
+ this.currentPages[this.currentPages.length - 1].cache = true;
|
|
|
+ if (this.currentPages.length > 1) {
|
|
|
+ this.historyPages.unshift(...historyPages);
|
|
|
+ } else {
|
|
|
+ //当前列表只有一个时,说明此时是在tabBar页,相当于重新开始路由跳转,需清空已回退页面列表
|
|
|
+ this.historyPages = [...historyPages];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method deleteHistory 移除页面历史路由
|
|
|
+ * @param pathName {String} 路由名字
|
|
|
+ * @param addCurrentPages {Boolean} 是否添加到当前路由
|
|
|
+ * */
|
|
|
+ deleteHistory(pathName,addCurrentPages) {
|
|
|
+ if (this.historyPages.length) {
|
|
|
+ const spliceCount = this.historyPages.findIndex((element) => element.pathName == pathName);
|
|
|
+ const historyPages = this.historyPages.splice(0, spliceCount + 1);
|
|
|
+ if(addCurrentPages) {
|
|
|
+ historyPages.forEach((element)=>{
|
|
|
+ element.cache = true
|
|
|
+ });
|
|
|
+ this.currentPages.push(...historyPages)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method updateCacheStatus 更新某个页面缓存状态
|
|
|
+ * @param pathName 路由名
|
|
|
+ * */
|
|
|
+ updateCacheStatus(pathName) {
|
|
|
+ this.currentPages.forEach((element)=>{
|
|
|
+ if(element.pathName == pathName){
|
|
|
+ element.cache = true;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * @method resetCacheStatus 重置页面缓存状态
|
|
|
+ * @description 用于页面刷新时
|
|
|
+ * */
|
|
|
+ resetCacheStatus() {
|
|
|
+ const pathName = location.pathname.substring(1);
|
|
|
+ if (this.currentPages.length) {
|
|
|
+ this.currentPages.forEach((element) => {
|
|
|
+ element.cache = pathName == element.pathName ? true : false;
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (this.historyPages.length) {
|
|
|
+ this.historyPages.forEach((element) => {
|
|
|
+ element.cache = pathName == element.pathName ? true : false;
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ persist: {//pinia持久化配置,默认sessionStorage
|
|
|
+ enabled: true
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export default useRouterStore
|