VUE中,跳转页面之前判断并显示弹框组件。
涉及到路由守卫、数据交互。有空我在完善,先直接给出代码
代码使用了 element plus、vuex
路由文件
import { createRouter, createWebHistory } from 'vue-router';
import CommonEntry from '@/views/CommonEntry.vue';
import Home from '@/views/mobile/HomeView.vue';
import MainLayout from '@/views/mobile/MainLayout.vue';
import User from '@/views/mobile/UserView.vue';
import {useStore} from "vuex";
const routes = [
{
path: '/',
name: 'commonEntry',
component: CommonEntry,
},
{
path: '/m/',
name: 'homeMobile',
component: MainLayout,
children: [
{
path: '',
name: 'home',
component: Home,
},
{
path: 'user',
name: 'user',
component: User,
meta: { requiresAuth: true }
}
]
}
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
// 这里是关键
router.beforeEach((to, from, next) => {
const store = useStore();
if (to.matched.some(record => record.meta.requiresAuth && !store.getters['user/isAuthenticated'])) {
if( from.name === undefined ) { // 用户通过连接直接访问跳转到首页
next('/');
} else {
// 保存需要跳转的路由信息
localStorage.setItem('wantedRoute', JSON.stringify({path: to.path, query: to.query, hash: to.hash}));
// 显示登陆组件
store.dispatch('authDialog/toggleLoginDialog', true);
// 不进行下一步路由的跳转,由登陆组件中再次进行路由跳转
next(false);
}
} else {
next();
}
});
export default router;
父组件MainLayout.vue
登陆组件LoginDialog.vue
{{ $t('login') }}
{{ $t('freeTrial') }}
{{ $t('registerAccount') }}
利用uex来保存登陆状态 store.js
import {createStore} from "vuex";
import authDialog from './authDialog';
export default createStore({
modules: {
authDialog
}
});
authDialog.js
const state = {
isLoginDialogVisible: false, // 登录对话框显示状态
isRegisterDialogVisible: false, // 注册对话框显示状态
};
const mutations = {
setLoginDialogVisibility(state, visibility) {
state.isLoginDialogVisible = visibility;
},
setRegisterDialogVisibility(state, visibility) { // 控制注册对话框的显示状态
state.isRegisterDialogVisible = visibility;
},
};
const actions = {
toggleLoginDialog({ commit }, visibility) {
commit('setLoginDialogVisibility', visibility);
},
toggleRegisterDialog({ commit }, visibility) { // 切换注册对话框的显隐
commit('setRegisterDialogVisibility', visibility);
},
};
const getters = {
isLoginDialogVisible: (state) => state.isLoginDialogVisible,
isRegisterDialogVisible: (state) => state.isRegisterDialogVisible, // 获取注册对话框的显示状态
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};
全局方法:globalMixin.js
export default {
data() {
return {
isSubmitting: false
};
},
methods: {
// 防止重复点击
async preventMultipleSubmissions(action) {
if (this.isSubmitting) {
this.$message({
showClose: true,
message: this.$t('pleaseWait'),
type: 'warning'
});
return;
}
this.isSubmitting = true;
try {
await action();
} catch (error) {
this.$message({
showClose: true,
message: this.$t('operatorError'),
type: 'warning'
});
} finally {
this.isSubmitting = false;
}
},
// 登陆状态检查
isAuthenticated() {
return this.$store.state.user.userInfo !== null;
}
}
};
让我来逐一解释你的问题:
useStore
的作用和 store.dispatch
的使用useStore
: 在 Vue 3 和 Vuex 4 中,useStore
是一个 Composition API 的方法,用于在组件内部访问 Vuex store。这是一种新的模式,用于取代在 Vue 2 中使用 this.$store
的方式。useStore
主要用于 setup 函数或其他 Composition API 函数中。
为什么不能直接通过方法名调用: Vuex 的 actions
和 mutations
需要通过 store 的 dispatch
和 commit
方法来调用,以保持状态管理的一致性和可追踪性。这是 Vuex 的设计哲学之一,旨在通过集中式存储管理应用的所有状态,并遵循特定的规则来更改状态。
store.dispatch
: 用于触发 Vuex store 中的 actions
。actions
是可以包含任意异步操作的方法。在这个例子中,store.dispatch('authDialog/toggleLoginDialog', true)
会触发 authDialog
模块中的 toggleLoginDialog
action,并传入 true
作为参数。
commit
的作用和 mapActions
、mapGetters
的使用commit
: 在 Vuex 中,commit
用于触发 mutations
。mutations
是同步函数,用于更改 Vuex store 中的状态。在这个例子中,commit('setLoginDialogVisibility', visibility)
会触发 setLoginDialogVisibility
mutation,并传入 visibility
作为参数。
...mapActions
和 ...mapGetters
: 这两个函数是 Vuex 提供的辅助函数,用于将 Vuex 的 actions
和 getters
映射到组件的 methods
和 computed
属性中。...
是 JavaScript 的展开运算符,用于将数组或对象展开到另一个数组或对象中。在这个例子中,...mapActions('authDialog', ['toggleLoginDialog', 'toggleRegisterDialog'])
将 authDialog
模块的 toggleLoginDialog
和 toggleRegisterDialog
actions 映射到组件的方法中,而 ...mapGetters
类似地将 getters
映射到计算属性中。
@update:
的作用和 $emit
的使用@update:
: 是 Vue 中的一个事件监听修饰符,用于监听子组件触发的更新事件。在这个例子中,@update:dialogVisible="handleLoginDialogVisibilityChange"
监听 LoginDialog
组件触发的 update:dialogVisible
事件,并调用 handleLoginDialogVisibilityChange
方法来响应该事件。
this.$emit
: 在 Vue 组件中,this.$emit
用于子组件向父组件发送事件。this.$emit('update:dialogVisible', value)
就是 LoginDialog
或 RegisterDialog
组件向父组件发送 update:dialogVisible
事件,并传递 value
作为参数。
父子数据交互: 是的,@update:
修饰符和 this.$emit
一起工作,实现了父子组件之间的数据交互。子组件通过 $emit
发出事件,父组件通过监听这些事件来响应变化。
这种模式是 Vue 组件间通信的常用方法之一,有助于保持数据的单向流动,从而使得状态管理更加清晰和可维护。