面试题答案
一键面试整体设计思路
- 路由守卫:
- 全局前置守卫:用于全局的权限控制,例如在进入任何页面之前检查用户是否登录。可以在
router.js
中定义:
const router = new VueRouter({... }) router.beforeEach((to, from, next) => { const isLoggedIn = localStorage.getItem('token') if (to.meta.requiresAuth &&!isLoggedIn) { next('/login') } else { next() } })
- 路由独享守卫:在特定路由上定义守卫,用于该路由特有的权限或数据加载逻辑。例如:
const router = new VueRouter({ routes: [ { path: '/admin', component: AdminComponent, beforeEnter: (to, from, next) => { const userRole = localStorage.getItem('role') if (userRole === 'admin') { next() } else { next('/forbidden') } } } ] })
- 全局后置守卫:主要用于页面切换后的一些操作,如页面标题的更新等。
router.afterEach((to, from) => { document.title = to.meta.title || '默认标题' })
- 全局前置守卫:用于全局的权限控制,例如在进入任何页面之前检查用户是否登录。可以在
- 组件生命周期钩子函数:
- created:在此钩子函数中可以进行数据的初始化获取,例如调用API获取页面所需数据。对于多层嵌套路由,父组件获取的数据可以通过props传递给子组件。
export default { data() { return { userData: null } }, created() { this.fetchUserData() }, methods: { async fetchUserData() { const response = await axios.get('/api/user') this.userData = response.data } } }
- mounted:适合进行一些DOM操作相关的初始化,比如初始化第三方插件(如echarts)。如果需要在组件挂载后根据路由参数更新数据,也可以在这里进行。
export default { data() { return { chart: null } }, mounted() { this.chart = echarts.init(this.$el.querySelector('.chart - container')) this.updateChartData() }, methods: { async updateChartData() { const response = await axios.get('/api/chart - data') this.chart.setOption({...response.data }) } } }
举例说明
假设我们有一个多层嵌套路由的博客管理系统,有/posts
(展示文章列表),/posts/:id
(展示文章详情),/admin/posts
(管理员管理文章页面,需要管理员权限)。
- 权限控制:
- 在
/admin/posts
路由上设置路由独享守卫,检查用户是否为管理员。 - 在全局前置守卫中检查用户是否登录,若未登录,阻止进入需要登录的页面。
- 在
- 数据加载:
- 在
PostsList
组件(对应/posts
)的created
钩子函数中获取文章列表数据。 - 在
PostDetail
组件(对应/posts/:id
)的created
钩子函数中,根据路由参数:id
获取文章详细数据。
- 在
可能遇到的问题及解决方案
- 数据重复加载:
- 问题:在路由切换时,如果组件没有被销毁,可能会重复加载数据。例如从
/posts
切换到/posts/:id
,created
钩子函数可能会再次执行导致数据重复获取。 - 解决方案:可以通过
watch
监听路由参数的变化,只有当参数变化时才重新获取数据。
export default { data() { return { post: null } }, watch: { '$route.params.id': { immediate: true, async handler(newId) { const response = await axios.get(`/api/post/${newId}`) this.post = response.data } } } }
- 问题:在路由切换时,如果组件没有被销毁,可能会重复加载数据。例如从
- 权限控制不及时:
- 问题:如果用户在登录状态下权限发生变化,可能不会及时在路由守卫中反映出来。
- 解决方案:可以在路由守卫中增加一个获取最新权限的逻辑,或者在用户权限变化时手动刷新页面(简单粗暴但有效),也可以通过事件总线或Vuex来通知路由守卫更新权限状态。
- 组件生命周期与路由守卫冲突:
- 问题:例如在组件
created
钩子函数中获取数据,同时路由守卫中也进行一些数据处理,可能会导致数据处理顺序混乱。 - 解决方案:明确职责,尽量在路由守卫中只进行权限控制和一些与路由相关的基础数据准备,而复杂的数据获取和处理放在组件生命周期钩子函数中。同时,在涉及异步操作时,合理使用
async/await
确保操作顺序。
- 问题:例如在组件