为了防止接口异常,在上一章的基础上创建一个mork文件夹写了个menu.json放入public文件里:
Element官网:https://element.eleme.cn/#/zh-CN/guide/design
{
"data": [
{
"id": 101,
"authName": "用户管理",
"path": "users",
"children": [
{
"id": 1,
"authName": "用户列表",
"path": "users",
"children": []
},
{
"id": 2,
"authName": "添加用户",
"path": "addusers",
"children": []
}
]
},
{
"id": 102,
"authName": "分类管理",
"path": "categories",
"children": [
{
"id": 1,
"authName": "分类列表",
"path": "categories",
"children": []
},{
"id": 2,
"authName": "添加分类",
"path": "addcategories",
"children": []
}
]
},
{
"id": 103,
"authName": "商品管理",
"path": "goods",
"children": [
{
"id": 1,
"authName": "商品列表",
"path": "goods",
"children": []
}
]
}
],
"meta": {
"msg": "获取菜单列表成功",
"status": 200
}
}
App.vue里放入路由容器:
view下LoginView.vue:
import axios from 'axios';
export default {
name:"LoginView",
data() {
var checkUser = (rule, value, callback) => {
console.log('用户名:',value)
if(value.trim()==''){
callback(new Error('请输入用户名'));
}else if(!/^[0-9a-zA-Z_\u4e00-\u9fa5@.]{5,12}$/.test(value)){
callback(new Error('用户名为5-10位中英文数字或者下划线'));
}
else{
callback();
}
};
var validatePass = (rule, value, callback) => {
console.log('密码:',value)
if (value.trim()=='') {
callback(new Error('请输入密码'));
} else{
callback();
}
};
return {
ruleForm: {
password: '',
username: ''
},
rules: {
password: [
{ validator: validatePass, trigger: 'blur' }
],
username: [
{ validator: checkUser, trigger: 'blur' }
]
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
/* el-form组件的validate方法 在回调函数中
如果 valid 为 true 则表示表单校验通过
为false则表示不通过 */
if (valid) {
axios.post('https://api.***.ed***********',{
email:this.ruleForm.username,
password:this.ruleForm.password
})
.then(res=>{
let {access_token} = res.data
this.$message.success('登陆成功')
/* 当登录成功 把用户名和token存入本地缓存中方便后续使用 */
localStorage.token = access_token
/* 登录成功后过一秒跳转首页 */
setTimeout(()=>{
this.$router.push({name:'index'})
},1000)
})
/* 登录失败(包括用户名或者密码不对会走catch) */
.catch(()=>{
this.$message.error('登陆失败')
})
} else {
this.$message.error('您输入的有误')
}
});
},
resetForm(formName) {
/* 通过vue中的$refs方法来调用组件el-form中的 resetFields重置方法 */
this.$refs[formName].resetFields();
}
}
}
.myform{
width:600px;
margin:50px auto;
}
view下IndexView.vue:
//这里做了点改动,相比上一章这里采取动态路由来获取侧边栏以及二级菜单:
相关注意点已用注释表明:
:default-openeds="openList" :router="true" :default-active="pagepath" :unique-opened="true" > :index="(i + 1).toString()" v-for="(v, i) in navList" :key="i" >
>{{ v.authName }} > :index="'/index/' + item.path" v-for="(item, index) in v.children" :key="index" > {{ item.authName }}
王小虎
import axios from "axios";
export default {
data() {
return {
openList: ["1"],
navList: [],
pagepath: "/index/users",
};
},
watch: {
/* 当路由发生变化的时候,就把最新的地址给到pagepath变量
作用是为了保持路由菜单栏的高亮显示,以及解决点击不跳转的bug */
$route: {
handler: function (newV) {
console.log(newV);
this.pagepath = newV.path;
},
immediate: true,
},
},
created: function () {
this.getNaviList();
},
methods: {
getNaviList: function () {
axios
.get("/mork/menu.json", {
headers: {
Authorization: localStorage.token,
},
})
.then((res) => {
console.log(res);
let { data, meta } = res.data;
/* 数据获取成功 */
if (meta.status == 200) {
this.navList = data;
/* 动态添加路由 */
/* 因为第一个路由是默认的所以我们从第二个路由开始动态添加 */
console.log(this.navList);
let arr = this.navList.slice(1,3)
/* 循环路由数组 动态添加路由 */
console.log(arr);
arr.forEach(v => {
/* 我们尽量使用v.children[0].path 原因是我们的路径名用的是子路由的 */
/* 如果我们直接写死 v.children[0].path 会导致只有一个子路由的路径被动态添加了
如果有多个就无法生效, 所以我们要二次循环v.children,从而实现多个二级子路由
能够被动态的添加*/
v.children.forEach(r=>{
this.$router.addRoute("index",
{
path:r.path,
name:r.path,
component:()=>import(`@/views/${r.path.substring(0,1).toUpperCase()+r.
path.substring(1)}View.vue`),
},
);
})
this.$router.addRoute("index",
{
path:v.children[0].path,
name:v.children[0].path,
component:()=>import(`@/views/${v.children[0].path.substring(0,1).toUpperCase()+v.children[0].
path.substring(1)}View.vue`),
},
);
});
console.log(this.$router);
} else {
/* 防止数据获取失败给出相应的后台提示 */
this.$message.error(meta.msg);
}
})
.catch((err) => {
console.log(err);
});
},
},
};
.el-header {
background-color: #b3c0d1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
router下路由配置:采取动态路由,之前的注释掉了:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'login',
component:()=>import('@/views/LoginView.vue')
},
{
path:'/index',
name:'index',
/* 已进入页面就默认进入二级路由users页面 */
redirect:'/index/users',
component:()=>import('@/views/IndexView.vue'),
children:[{
path:'users',
name:'users',
component:()=>import('../views/UsersView.vue'),
},
{
path:'addusers',
name:'addusers',
component:()=>import('../views/AddusersView.vue'),
}
/* {
path:'roles',
name:'roles',
component:()=>import('../views/RolesView.vue'),
},
{
path:'rights',
name:'rights',
component:()=>import('../views/RightsView.vue'),
},
{
path:'goods',
name:'goods',
component:()=>import('../views/GoodsView.vue'),
},
{
path:'params',
name:'params',
component:()=>import('../views/ParamsView.vue'),
},
{
path:'categories',
name:'categories',
component:()=>import('../views/CategoriesView.vue'),
},
{
path:'categories',
name:'categories',
component:()=>import('../views/CategoriesView.vue'),
},
{
path:'orders',
name:'ordes',
component:()=>import('../views/OrdersView.vue'),
},
{
path:'reports',
name:'reports',
component:()=>import('../views/ReportsView.vue'),
}, */
]
}
]
const router = new VueRouter({
routes
})
export default router
views下跳转的AddcategoriesView.vue:
添加分类
export default {
}