vue + element-plus 开发中遇到的问题

1.问题之路由守卫

      初写路由守卫,对于next()的理解不是很透彻,就想着都放行,不然看不到效果,结果控制台出现了警告,想着报黄的问题就不是问题,但仔细一看发现他说,如果再生产阶段就会失败,就觉得有必要解决一下

 以下是我的代码

//路由鉴权
import router from "@/router"

import nprogress from "nprogress"
//引入进度条的样式
import "nprogress/nprogress.css"

//删除加载进度条傍边的小球
nprogress.configure({showSpinner:false})
//引入小仓库
import { store } from "@/stores/modules/user"
import pinia from "./stores" //在外部使用小仓库之前的引入大仓库,否则会报错,可以理解为仓库时通过大仓库的create而建立,没有引入大仓库,小仓库就不存在,而组件内是因为在main.ts中通过use()使用了
let useStore = store(pinia) //然后将pinia传进去
//console.log(useStore)
//全局守卫:项目当中任意路由切换都会触发的钩子
//全局前置首位

router.beforeEach(async (to: any, from: any, next: any) => {
    //浏览器任务栏的名字
    document.title = to.meta.title
    //to:你将要访问的路由对象
    //from:你从哪个路由而来
    //next:路由的放行函数
    //console.log(nprogress)

    nprogress.start();
    let token = useStore.token;

    //获取用户信息
    let userinfo = useStore.netName

    //通过token来鉴别是否登录成功
    if (token) {
        //登录成功,不能访问login,指向首页
        if (to.path == "/login") {

            next({ path: '/' })
        }
        //登录成功访问其余几个路由
        else {
            //有用户信息
            if (userinfo) {
                //放行
                next();
            } else {
                //如果没有用户信息,先获取用户信息再放行
                try {
                    //获取用户信息
                    await useStore.userInfo()
                    //放行
                    next();
                } catch (error) {
                    //token过期:获取不到用户信息
                    //用户手动修改了本地储存的token
                    //退出登录 用户相关的数据清空
                    useStore.userOutLogin();
                    next({ path: '/login', query: { redirect: to.path } })
                }
            }
        }
    } else {
        if (to.path == '/login') {
            next();
        } else {
            next({ path: '/login', query: { redirect: to.path } }) //返回登陆页面,并在地址栏中添加你想去的页面,登录成功后可以直接去
        }
    }






     //问题所在
    next();
})
//全局后置首位
router.afterEach(() => {
    nprogress.done();

})

问题所在我特意加了很多空行,报黄的原因是路由导航执行了两次next函数,只要把最下面的next函数善删了就OK了

2.问题之el-menu

        这个问题是我纯属眼瞎

        以下是代码

<script setup lang='ts'>
import { ref, onMounted } from "vue"
import Menu from "../menu/test.vue"
//引入路由
import { useRouter } from "vue-router";

//获取路由器对象
let router = useRouter();
//接收路由数组
defineProps({
  menuList: Object,
})

const goRouter = (item: any) => {
  //路由跳转
  router.push(item.index)
}
</script>

<template>
  <div class="menu-container">


    <template v-for="(item, index) in menuList">
      <template v-if="!(item.meta as any).hidden">
        <!--  无子路由  -->
        <el-menu-item :index="item.path" v-if="!item.children" @click="goRouter">
        





          <template #title>  <el-icon>
            <component :is="(item.meta as any).icon">
            </component>
          </el-icon>
            <span>{{ (item.meta as any).title }}</span>
          </template>



        </el-menu-item>
        <!--  仅一个子路由  -->
        <el-menu-item :index="item.path" v-if="item.children && item.children.length == 1" @click="goRouter">
          

          <template #title>
            <el-icon>
            <component :is="(item.children[0].meta as any).icon">
            </component>
          </el-icon>
            <span>{{ (item.children[0].meta as any).title }}</span>
          </template>



        </el-menu-item>
        <!--  一子路由以上  -->
        <el-sub-menu v-if="item.children && item.children.length > 1" :index="item.children[0].path">


          <template #title>
            <el-icon>
              <component :is="(item.meta as any).icon">
              </component>
            </el-icon>
            <span>{{ (item.meta as any).title }}</span>
          </template>



          <Menu :menuList="item.children"></Menu>
        </el-sub-menu>
      </template>
    </template>

  </div>
</template>



<style lang="less" scoped></style>

最后的页面,(折叠后的菜单)

预期的样子

 产生的原因:将图标放到插槽title里面,导致图标和标题一起折叠,el-sub-menu与el-menu-item有些不一样,他的图标是放在插槽里的,也正是这个原因使搞混了,看文档一定要仔细,我因为这问题耽误了有近两个小时(还有一点是因为我不爱看文档,这毛病的改了)

解决:将图标放到外面

如:

 <el-menu-item :index="item.path" v-if="!item.children" @click="goRouter">
          <el-icon>
            <component :is="(item.meta as any).icon">
            </component>
          </el-icon>
          <template #title>
            <span>{{ (item.meta as any).title }}</span>
          </template>
</el-menu-item>

3.问题之内容区跳转

 一般做某某管理系统,点击不同的菜单,内容区跳转到不同的内容路由,所以要跳转路由的一路由必须为主页的路由

如:

  {
        path: '/',
        component: () => import('@/views/main/index.vue'),  //这个路由为由组件拼成的主页面
        name: '/',
        meta: {
            title: "",
            hidden: false,
            icon:'',
        },
        redirect:'/home',
        children:[
            {
                path:'/home',
                component: ()=> import('@/views/home/index.vue'),
                name:'home',
                meta:{
                    title: "首页",
                    hidden: false,
                    icon:'House'
                }
            } 
        ]

    }
,
{
        path: '/goodsMange',



        component: () => import('@/views/main/index.vue'),  //第一次写的时候写了其他新建的文件一整个页面都跳了



        name:'goodsMange',
        meta:{
            title:'商品管理',
            hidden:false,
            icon:'Goods',
        },
        redirect: '/goodsMange/SKU',
        children: [
            {
                path: '/goodsMange/SKU',
                component: ()=> import('@/views/goodsManage/SKU/index.vue'),
                name:'sku',
                meta:{
                    title:'SKU',
                    hidden:false,
                    icon:'Goods',
                },
            },
            {
                path: '/goodsMange/SPU',
                component: ()=> import('@/views/goodsManage/SPU/index.vue'),
                name:'spu',
                meta:{
                    title:'SPU',
                    hidden:false,
                    icon:'Goods',
                },
                
            }
        ]
    },

4.pinia取名一样的错误

export const setClass = defineStore("class", {
    state: () => ({

    }),
    actions: {
        async getMainClass(currentPage: number, pageSize: number) {
            let res = await getMainClass(currentPage, pageSize)
            
            if (res.code == 200) {
                return Promise.resolve(res.data.courses)
            } else {
                return Promise.reject("获取信息失败")
            }
        },
      
        }
    },
    getters: {}
})

这个pinia仓库的名字为class ,记住你每个小仓库的名字必须是独一无二的,不然你的仓库会相互覆盖,先被使用的仓库能正常使用,后使用的会被覆盖导致找不到其中属性和方法

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这个Demo需要分为前端页面和后端代码两部分来实现,下面我将介绍具体的实现步骤。 ## 后端代码实现 1. 创建SpringBoot项目,引入相关依赖: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies> ``` 2. 创建数据库表,并使用Mybatis进行数据访问操作,这里使用Druid作为数据源: ```java @Mapper public interface DemoMapper { List<Demo> getDemoList(); Demo getDemoById(Integer id); int addDemo(Demo demo); int updateDemo(Demo demo); int deleteDemo(Integer id); } ``` 3. 在Controller层编写接口,提供增删改查的功能: ```java @RestController @RequestMapping("/demo") public class DemoController { @Autowired private DemoMapper demoMapper; @GetMapping("/list") public List<Demo> getDemoList() { return demoMapper.getDemoList(); } @GetMapping("/{id}") public Demo getDemoById(@PathVariable Integer id) { return demoMapper.getDemoById(id); } @PostMapping("/add") public int addDemo(@RequestBody Demo demo) { return demoMapper.addDemo(demo); } @PutMapping("/update") public int updateDemo(@RequestBody Demo demo) { return demoMapper.updateDemo(demo); } @DeleteMapping("/{id}") public int deleteDemo(@PathVariable Integer id) { return demoMapper.deleteDemo(id); } } ``` ## 前端页面实现 1. 创建Vue项目,并引入相关依赖: ```javascript import ElementPlus from 'element-plus'; import 'element-plus/lib/theme-chalk/index.css'; ``` 2. 在页面使用Element-Plus组件,实现增删改查的功能: ```vue <template> <div class="demo"> <el-button type="primary" @click="showAddDialog">添加</el-button> <el-table :data="tableData"> <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <el-table-column prop="sex" label="性别"></el-table-column> <el-table-column label="操作"> <template #default="{ row }"> <el-button type="text" @click="showUpdateDialog(row)">编辑</el-button> <el-button type="text" @click="deleteDemo(row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-dialog title="添加" :visible.sync="addDialogVisible"> <el-form :model="addForm" :rules="rules"> <el-form-item label="姓名" prop="name"> <el-input v-model="addForm.name"></el-input> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model="addForm.age"></el-input> </el-form-item> <el-form-item label="性别" prop="sex"> <el-radio-group v-model="addForm.sex"> <el-radio label="男"></el-radio> <el-radio label="女"></el-radio> </el-radio-group> </el-form-item> </el-form> <div slot="footer"> <el-button @click="addDialogVisible = false">取消</el-button> <el-button type="primary" @click="addDemo">确定</el-button> </div> </el-dialog> <el-dialog title="编辑" :visible.sync="updateDialogVisible"> <el-form :model="updateForm" :rules="rules"> <el-form-item label="姓名" prop="name"> <el-input v-model="updateForm.name"></el-input> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model="updateForm.age"></el-input> </el-form-item> <el-form-item label="性别" prop="sex"> <el-radio-group v-model="updateForm.sex"> <el-radio label="男"></el-radio> <el-radio label="女"></el-radio> </el-radio-group> </el-form-item> </el-form> <div slot="footer"> <el-button @click="updateDialogVisible = false">取消</el-button> <el-button type="primary" @click="updateDemo">确定</el-button> </div> </el-dialog> </div> </template> <script> import { reactive, toRefs } from 'vue'; import axios from 'axios'; export default { name: 'Demo', setup() { const state = reactive({ tableData: [], addDialogVisible: false, updateDialogVisible: false, addForm: { name: '', age: '', sex: '男' }, updateForm: { id: '', name: '', age: '', sex: '' }, rules: { name: [ { required: true, message: '请输入姓名', trigger: 'blur' } ], age: [ { required: true, message: '请输入年龄', trigger: 'blur' } ], sex: [ { required: true, message: '请选择性别', trigger: 'change' } ] } }); const getDemoList = () => { axios.get('/demo/list').then(res => { state.tableData = res.data; }); }; const addDemo = () => { axios.post('/demo/add', state.addForm).then(() => { state.addDialogVisible = false; state.addForm = { name: '', age: '', sex: '男' }; getDemoList(); }); }; const updateDemo = () => { axios.put('/demo/update', state.updateForm).then(() => { state.updateDialogVisible = false; state.updateForm = { id: '', name: '', age: '', sex: '' }; getDemoList(); }); }; const deleteDemo = id => { axios.delete(`/demo/${id}`).then(() => { getDemoList(); }); }; const showAddDialog = () => { state.addDialogVisible = true; }; const showUpdateDialog = row => { state.updateDialogVisible = true; state.updateForm = Object.assign({}, row); }; getDemoList(); return { ...toRefs(state), getDemoList, addDemo, updateDemo, deleteDemo, showAddDialog, showUpdateDialog }; } }; </script> ``` 这样就完成了一个简单的增删改查Demo,前后端分离,前端使用VueElement-Plus实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值