Vue + Element-UI —— 项目实战(八)(完结,2024年最新分享两道阿里P7究极难度算法题

32 阅读4分钟

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。 img img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

      },
    };
  },
};
</script>

<style lang="less" scoped>
.login-container {
    border-radius: 15px;
    // 背景裁剪的内边距
    background-clip: padding-box;
    margin: 180px auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background-color: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
}
.login_title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
}
.login_submit {
    margin: 10px auto 0 auto;
}
</style>

登录页面


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/22be50aac7314358bce0db63294bfcfb~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322696&x-signature=o8yOYZfJ3XDHwU4QIfYQQKFv198%3D)



###### 2. 登录权限 & 导航守卫




> 

> 1. 安装缓存插件

> 

> 

> 




npm i js-cookie



> 

> 2. 在 store 文件中,创建 user.js 文件,用于缓存输入的内容。

> 

> 

> 




import Cookie from "js-cookie";

export default {
  state: {
    token: "",
  },
  mutations: {
    // 设置cookie
    setToken(state, val) {
      (state.token = val), Cookie.set("token", val); //cookie的名称,传入的值
    },
    // 清除cookie
    clearToken(state) {
      (state.token = ""), Cookie.remove("token");
    },
    // 获取cookie
    getToken(state) {
      // 如果当前的缓存中有token,直接获取。如果没有,要从state中获取
      state.token = Cookie.get("token") || state.token;
    },
  },
};



> 

> 3. 在 ./store/index.js 中导入

> 

> 

> 




import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'
import user from './user'
// 全局使用Vuex
Vue.use(Vuex)
export default new Vuex.Store({
    // 模块化定义
    modules:{
        tab,
        user
    }
})



> 

> 4. main.js 中添加前置路由守卫

> 

> 

> 




// 前置路由守卫
router.beforeEach((to, from, next) => {
  store.commit('getToken') //防止页面刷新后vuex丢失token信息
  const token = store.state.user.token
  // 如果token不存在,并且当前页不是登录页
  if(!token && to.name !== 'login') {
    next({name: 'login'}) // 返回登录页
  } else if(token && to.name === 'login'){
    next({name: 'home'})
  } else {
    next()
  }
})

###### 2. 登录接口逻辑




> 

> 1. ./api/mockServerData/permission.js,用于定义接口相关的逻辑

> 

> 

> 




// 接口的相关逻辑
import Mock from 'mockjs'
export default {
  // 模拟菜单权限,接收传递进来的参数
  getMenu: config => {
    console.log(config);
    const { username, password } = JSON.parse(config.body)
    console.log(JSON.parse(config.body))
    // 先判断用户是否存在
    // 判断账号和密码是否对应
    if (username === 'admin' && password === 'admin') {
      return {
        code: 20000,
        data: {
          menu: [
            {
              path: '/home',
              name: 'home',
              label: '首页',
              icon: 's-home',
              url: 'home/index'
            },
            {
              path: '/mall',
              name: 'mall',
              label: '商品管理',
              icon: 'video-play',
              url: 'mall/index'
            },
            {
              path: '/user',
              name: 'user',
              label: '用户管理',
              icon: 'user',
              url: 'User/index'
            },
            {
              label: '其他',
              icon: 'location',
              children: [
                {
                  path: '/page1',
                  name: 'page1',
                  label: '页面1',
                  icon: 'setting',
                  url: 'other/pageOne.vue'
                },
                {
                  path: '/page2',
                  name: 'page2',
                  label: '页面2',
                  icon: 'setting',
                  url: 'other/pageTwo.vue'
                }
              ]
            }
          ],
          token: Mock.Random.guid(),
          message: '获取成功'
        }
      }
    } else if (username === 'xiaoxiao' && password === 'xiaoxiao') {
      return {
        code: 20000,
        data: {
          menu: [
            {
              path: '/',
              name: 'home',
              label: '首页',
              icon: 's-home',
              url: 'home/index'
            },
            {
              path: '/mall',
              name: 'mall',
              label: '商品管理',
              icon: 'video-play',
              url: 'mall/index'
            }
          ],
          token: Mock.Random.guid(),
          message: '获取成功'
        }
      }
    } else {
      return {
        code: -999,
        data: {
          message: '密码错误'
        }
      }
    }
  }
}



> 

> 2. 在 mock.js 中进行接口拦截

> 

> 

> 




import permissionApi from './mockServerData/permission'
Mock.mock(/permission\/getMenu/, 'post', permissionApi.getMenu)

###### 3. 菜单权限功能




> 

> 1. 动态添加路由,在 tab.js 中定义 menu 空数组

> 

> 

> 




menu: []



> 

> 2. 在 tab.js 的 mutations 中添加修改方法

> 

> 

> 




setMenu(state, val) {
  state.menu = val
  Cookie.set('menu', JSON.stringify(val))
},
clearMenu(state) {
  state.menu = []
  Cookie.remove('menu')
},
addMenu(state, router) {
  if(!Cookie.get('menu')) {
    return 
  }
  // 转成对象
  const menu = JSON.parse(Cookie.get('menu'))
  state.menu = menu
  const menuArray = []
  menu.forEach(item => {
    // 有二级菜单的数据
    if(item.children) {
      item.children = item.children.map(item => {
        item.component = () => import(`../views/${item.url}`)
        return item
      })
      menuArray.push(...item.children)
      // 一级菜单
    }else{
      item.component = () => import(`../views/${item.url}`)
      menuArray.push(item)
    }
  })
  // 路由的动态添加
  menuArray.forEach(item => {
    router.addRoute('Main', item)
  })
}



> 

> 3. login.vue 中添加方法

> 

> 

> 




login() {
  getMenu(this.form).then((res) => {
    console.log(res, "res");
    // 接口调用成功
    if (res.code === 20000) {
      // 登录成功后,清除当前路由
      this.$store.commit("clearMenu");
      // 设置路由,传入数据
      this.$store.commit("setMenu", res.data.menu);
      // 设置token,传入接口的数据
      this.$store.commit("setToken", res.data.token);
      // 动态添加路由,传入router 实例
      this.$store.commit("addMenu", this.$router); 
      // 页面跳转
      this.$router.push({ name: "home" });
    } else {
      //失败的提示
      this.$message.warning(res.data.message);
    }
  });
}



> 

> 这样就可以把 CommonAside.vue 中写死的数据去掉,只留 menu: []。  

>  .router/index.js 中里面的数据都删掉,只保留 children: []。

> 

> 

> 





> 

> 4. 在 CommonAside.vue 中定义 asyncMenu(),用来获取 menu

> 

> 

> 




computed: {
    noChildren() {
      // 过滤出来没有子项目的数据
      return this.asyncMenu.filter((item) => !item.children);
    },
    hasChildren() {
      // 过滤出有子项目的数据
      return this.asyncMenu.filter((item) => item.children);
    },
    isCollapse() {
      return this.$store.state.tab.isCollapse;
    },
    asyncMenu() {
      // 获取menu
      return this.$store.state.tab.menu
    }
  }

登录成功


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8907e798f0e94cfb90237e29df9b4082~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322696&x-signature=gp6FlZFtHDZC1oB61Ue62B1zZXo%3D)  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f0bd186634764faea0138b2e2b53262a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322696&x-signature=3DOZFlQVVDL0zMBevJy08CysPe0%3D)


##### Ⅱ、权限管理问题 & 退出登录


###### 1. 刷新白屏的解决方法



> 
> 1. main.js 中,在 vue实例生成前, created 钩子中调用动态路由的方法。
> 
> 
> 



created() {
  store.commit('addMenu', router)
}

###### 2. 权限管理


已经登录后,不应该还能访问登录页面,而是让它跳转到首页。




> 

> 1. 在 main.js 中修改路由守卫

> 

> 

> 




router.beforeEach((to, from, next) => {
  store.commit('getToken') //防止页面刷新后vuex丢失token信息
  const token = store.state.user.token
  // 如果token不存在,并且当前页不是登录页
  if(!token && to.name !== 'login') {
    next({name: 'login'}) // 返回登录页
  } else if(token && to.name === 'login'){
    next({name: 'home'})
  } else {
    next()
  }
})



![img](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/07ab193f9e8c421980f0fecc9592becc~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322696&x-signature=UoIoTrZjC1qvdbGx9TpeGMNtgpY%3D)
![img](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e92679bf7ee14bed8e09c1ff13fe7a1a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322696&x-signature=ReeeBsi%2BMe03ukv5wWB0J3SrKAI%3D)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**