vue3回到上一个路由页面

学习链接

Vue Router获取当前页面由哪个路由跳转
在Vue3的setup中如何使用this

  • beforeRouteEnter 在这个路由方法中不能访问到组件实例this,但是可以使用next里面的vm访问到组件实例,并通过vm.$data获取组件实例上的data数据
  • getCurrentInstance 是vue3提供的获取组件实例的方法,可通过getCurrentInstance函数获取了当前组件实例对象,并通过instance.data.message和instance.ctx.sayHello访问了组件实例的数据和方法
<template>
    <div class="main-box">
        <div class="title">菜单权限div>
        <div class="role-menu-box" v-loading="dataLoading">
            <div class="role-menu-header">
                <el-form inline :model="roleInfo" ref="roleInfoRef" :rules="roleInfoRules" label-width="80px">
                    <el-form-item label="角色名称" prop="roleName">
                        <el-input v-model="roleInfo.roleName">el-input>
                    el-form-item>
                    <el-form-item label="角色标识" prop="roleLabel">
                        <el-input v-model="roleInfo.roleLabel">el-input>
                    el-form-item>
                el-form>
            div>
            <div class="role-menu-body">
                <el-scrollbar>
                    <el-tree :props="defaultProps" node-key="id" :expand-on-click-node="false" check-on-click-node
                        default-expand-all ref="menuTreeRef" show-checkbox :data="roleMenuTreeData">
                    el-tree>
                el-scrollbar>
            div>
            <div class="role-menu-footer">
                <el-button @click="goBack">返回el-button>
                <el-button type="primary" @click="saveRoleMenu">保存el-button>
            div>
        div>
    div>
template>
<script>
import msgBoxer from '@/utils/msgBoxer'
export default {
    // name: 'roleMenu', // 这个组件不应该被缓存下来, 因此需要让 路由名称 与 组件名称不一致
    data() {
        return {
            formerRoute: {},
            isSaved: false
        }
    },
    // 在进入路由的时候, 记录进入之前的路由
    beforeRouteEnter(to, from, next) {
        next(vm => {
            // 通过 `vm` 访问组件实例
            let { query, params, path } = from
            vm.$data.formerRoute = { query, params, path }  // 没有this, 只能通过vm去访问组件实例上的数据
        })
    },

}
script>
<script setup>
import { ref, reactive, onMounted, nextTick, getCurrentInstance } from 'vue'
import { getRoleMenuByRoleId as getRoleMenuByRoleIdApi, saveRoleMenu as saveRoleMenuApi } from '@/api/roleApi'
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
import Messager from '@/utils/messager'

// 使用tagsViewStore
import useTagsView from '@/store/tagsView'
const tagsViewStore = useTagsView()

const dataLoading = ref(false)

// 获取组件实例
const instance = getCurrentInstance()

// 使用路由
const route = useRoute()
const router = useRouter()

const defaultProps = {
    label: 'title',
    children: 'children'
}

// 角色信息
let roleInfo = ref({})

// 菜单树ref
const menuTreeRef = ref(null)

// 菜单树数据
let roleMenuTreeData = ref([])

const roleInfoRules = {
    roleName: [
        { required: true, message: '角色名称不能为空', trigger: 'blur' }
    ],
    roleLabel: [
        { required: true, message: '角色标识不能为空', trigger: 'blur' }
    ]
}

function getRoleMenuByRoleId() {
    console.log(route);
    getRoleMenuByRoleIdApi(route.params.roleId).then(({ roleId, roleName, roleLabel, menuIdList, roleMenuTreeDTOList }) => {
        roleInfo.value = { roleId, roleName, roleLabel, menuIdList }
        roleMenuTreeData.value = roleMenuTreeDTOList
        // window.menuTreeRef = menuTreeRef
        nextTick(()=>{
            menuIdList.forEach(menuId=>{
                menuTreeRef.value.setChecked(menuId, true, false)
            })
        })
    })
}
onMounted(() => {
    getRoleMenuByRoleId()
})

function saveRoleMenu() {
    // 这里要注意下顺序, 半选的要在前面, 选中状态的要在后面
    // (半选状态对于后台权限来说是有意义的, 若子节点被选中, 那么该子节点的所有父节点都应该要有)
    let menuIdList = [...menuTreeRef.value.getHalfCheckedKeys(), ...menuTreeRef.value.getCheckedKeys(false) ]
    saveRoleMenuApi({ ...roleInfo.value, menuIdList }).then(res => {
        Messager.ok('保存成功')
        instance.data.isSaved = true // 记录保存, 通过instance访问组件实例上data配置项的数据
        router.push({ ...instance.data.formerRoute }) // 回到之前的路由去
    })
}

function goBack() {
    instance.data.isSaved = true // 记录保存, 通过instance访问组件实例上data配置项的数据
    if(instance.data.formerRoute.path) {
        router.push({ ...instance.data.formerRoute })
    } else {
        router.push('/sys/role')
    }
}

/* 在路由离开之前, 判断是否是点击保存值后离开的, 
  如果不是点击保存后离开的, 就弹框问是不是要离开, 
  如果确定是, 就离开, 并关闭页签, 如果不是, 就取消离开, */
onBeforeRouteLeave((to, from, next)=> {
    // console.log('beforeRouteLeave');
    if (!instance.data.isSaved) {
        msgBoxer.confirm('您确定要离开当前页面么?').then(res => {
            next()
            // 关闭当前页签
            tagsViewStore.closeSpecifiedTag({name: route.name})
        }).catch(err => {
            next(false)
        })
    } else {
        next()
        // 关闭当前页签
        tagsViewStore.closeSpecifiedTag({name: route.name})
    }

})

console.log('setup...');
script>

<style lang="scss" scoped>style>

你可能感兴趣的:(前端学习,vue.js,javascript,前端)