1.element-ui侧边栏实现路由跳转
关键代码:
在<el-menu>中需要--:default-active="this.$route.path"。用来绑定路由表
在<el-menu>中需要--router------或者router=true
这是一个侧边栏:
<el-menu :default-active="this.$route.path" router>
<el-submenu index="2">
<template slot="title"><i class="el-icon-menu"></i>导航</template>
<el-menu-item index="/mytopic">我的题目</el-menu-item>
<el-menu-item index="/myexam">我的试卷</el-menu-item>
<el-menu-item index="/myrepo">我的试卷库</el-menu-item>
<el-menu-item index="/mytest">我的考试记录</el-menu-item>
</el-submenu>
</el-menu>
参考:
https://blog.csdn.net/qq_43219422/article/details/89919619
2.element-ui侧边栏实现默认展开
默认展开:
关键代码:
如果想展开第一块内容、里面就只写1
:default-openeds="['1']"
如果想展开其余的。想写哪个就写哪个:
:default-openeds="['1', '2', '3']"
参考:
vue使用ElementUI时导航栏默认展开_archer的技术故事-CSDN博客_el-submenu默认展开
我的个人中心完整页面:
效果:
代码:
顶部导航栏:
<template>
<div class="elnav">
<el-menu
:default-active="$route.path"
:router="true"
class="el-menu-demo"
mode="horizontal"
@open="handleOpen"
@close="handleClose"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="/">
<i class="el-icon-s-home"></i>
<span>首页</span>
</el-menu-item>
<el-submenu index="2">
<template slot="title" index="/mytopic">
<i class="el-icon-question" v-if="!mytopicActive"></i>
<i class="el-icon-question el-icon-question-change" v-else></i>
<span>学习</span>
</template>
<el-submenu index="2-1">
<template slot="title" index="/mytopic">
<i class="el-icon-question" v-if="!mytopicActive"></i>
<i class="el-icon-question el-icon-question-change" v-else></i>
<span>题目</span>
</template>
<el-menu-item index="/mytopic">我创建的题目列表</el-menu-item>
<el-menu-item index="/publictopic">公共题目列表</el-menu-item>
<el-menu-item index="/createtopic">新增题目</el-menu-item>
<el-menu-item index="/edittopic">编辑题目</el-menu-item>
<el-menu-item index="/previewtopic">预览题目</el-menu-item>
</el-submenu>
<el-submenu index="2-2">
<template slot="title" index="/myrepo">
<i class="el-icon-s-management" v-if="!myRepoActive"></i>
<i class="el-icon-s-management el-icon-s-management-change" v-else></i>
<span>试卷库</span>
</template>
<el-menu-item index="/myrepo">我创建的试卷库列表</el-menu-item>
<el-menu-item index="/publicrepo">公共试卷库列表</el-menu-item>
<el-menu-item index="/createrepo">创建试卷库</el-menu-item>
<el-menu-item index="/editrepo">编辑试卷库</el-menu-item>
<el-menu-item index="/repodetails">试卷库详情页</el-menu-item>
</el-submenu>
<el-submenu index="2-3">
<template slot="title" index="/myexam">
<i class="el-icon-document" v-if="!myexamActive"></i>
<i class="el-icon-document el-icon-document-change" v-else></i>
<span>试卷</span>
</template>
<el-menu-item index="/myexam">我创建的试卷列表</el-menu-item>
<el-menu-item index="/publicexam">公共试卷列表</el-menu-item>
<el-menu-item index="/createexam">创建试卷</el-menu-item>
<el-menu-item index="/editexam">编辑试卷</el-menu-item>
<el-menu-item index="/examdetails">试卷详情页</el-menu-item>
<el-menu-item index="/previewexam">预览试卷</el-menu-item>
</el-submenu>
<el-submenu index="2-4">
<template slot="title" index="/mytest">
<i class="el-icon-medal-1" v-if="!testActive"></i>
<i class="el-icon-medal-1 el-icon-medal-1-change" v-else></i>
<span>考试</span>
</template>
<el-menu-item index="/mytest">我的考试记录</el-menu-item>
<el-menu-item index="/previewtest">预览考试</el-menu-item>
<el-menu-item index="/begintest">开始考试</el-menu-item>
<el-menu-item index="/testresult">考试结果</el-menu-item>
<el-menu-item index="/activate">激活账号</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="/music">
<i class="el-icon-headset"></i>
<span>音乐</span>
</el-menu-item>
<el-menu-item index="/imagelibrary">
<i class="el-icon-picture"></i>
<span>图片</span>
</el-menu-item>
<el-menu-item index="/personalcenter">
<i class="el-icon-s-custom"></i>
<span>个人中心</span>
</el-menu-item>
<el-menu-item index="/logout" v-if="loginState.isLogin">
<span>退出</span>
</el-menu-item>
<template v-else>
<el-menu-item index="/login">
<span>登录</span>
</el-menu-item>
<el-menu-item index="/register">
<span>注册</span>
</el-menu-item>
</template>
</el-menu>
<!-- 路由出口-->
<!-- 路由匹配到的组件将渲染显示在这里-->
<router-view></router-view>
</div>
</template>
<script>
import global from '../Global'
export default {
name: 'TopNav',
data() {
return {
loginState: global.loginState,
myRepoActive: '',
testActive: '',
mytopicActive: '',
myexamActive: ''
}
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath)
},
handleClose(key, keyPath) {
console.log(key, keyPath)
},
handleSelect(key, keyPath) {
console.log(key, keyPath)
// console.log(keyPath[0]);
if (keyPath) {
// 试卷库图标同步变色
if (keyPath[0] == '/myrepo' && keyPath[1] != '') {
this.myRepoActive = true
} else {
this.myRepoActive = false
}
// 考试图标同步变色
if (keyPath[0] == '/mytest' && keyPath[1] != '') {
this.testActive = true
} else {
this.testActive = false
}
// 题目图标同步变色
if (keyPath[0] == '/mytopic' && keyPath[1] != '') {
this.mytopicActive = true
} else {
this.mytopicActive = false
}
// 试卷图标同步变色
if (keyPath[0] == '/myexam' && keyPath[1] != '') {
this.myexamActive = true
} else {
this.myexamActive = false
}
}
},
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
/*.el-icon-s-management:before{*/
/* color: rgb(255,208,75);*/
/*}*/
.el-icon-s-management-change {
color: rgb(255, 208, 75);
}
.el-icon-medal-1-change {
color: rgb(255, 208, 75);
}
.el-icon-question-change {
color: rgb(255, 208, 75);
}
.el-icon-document-change {
color: rgb(255, 208, 75);
}
.el-icon-star-on-change {
color: rgb(255, 208, 75);
}
/*.is-active{*/
/* color: rgb(255, 208, 75);*/
/* background-color: rgb(84, 92, 100);*/
/*}*/
.elnav {
width: 100%;
}
.el-menu-demo {
}
/*.loginHidden {*/
/* display: none;*/
/*}*/
</style>
个人中心页面:(包括了侧边栏)
<template>
<div class="elformbox">
<el-container style="height: 100%; border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-active="this.$route.path"
:default-openeds="['1']"
:router="true" >
<el-submenu index="1">
<template slot="title"><i class="el-icon-menu"></i>我的学习</template>
<el-menu-item index="/mytopic">我的题目</el-menu-item>
<el-menu-item index="/myexam">我的试卷</el-menu-item>
<el-menu-item index="/myrepo">我的试卷库</el-menu-item>
<el-menu-item index="/mytest">我的考试记录</el-menu-item>
<el-menu-item index="/mistakescollection">我的错题集</el-menu-item>
<el-menu-item index="/favorites">我的收藏夹</el-menu-item>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-setting"></i>设置</template>
<el-menu-item index="/changepassword">修改密码</el-menu-item>
<el-menu-item index="/changephonenumberoremail">修改手机号码或邮箱</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header>
<span>个人资料</span>
</el-header>
<el-main>
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item>
<img v-if="!ruleForm.imageUrl" :src="ruleForm.avatarUrl" id="avatar"
style="width: 100px; height: 100px">
<el-upload
class="avatar-uploader"
:action="ruleForm.uploadUrl"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:on-error="handleError"
:before-upload="beforeAvatarUpload"
:data="ruleForm.data"
:with-credentials='true'
>
<img v-if="ruleForm.imageUrl" :src="ruleForm.imageUrl" class="avatar">
<el-button>更换头像</el-button>
</el-upload>
</el-form-item>
<el-form-item label="昵称:" prop="nickname">
<el-input v-if="ruleForm.editing" v-model="ruleForm.nickname" clearable></el-input>
<el-form-item v-else>
{{ruleForm.nickname}}
</el-form-item>
</el-form-item>
<el-form-item label="签名:" prop="signature">
<el-input v-if="ruleForm.editing" v-model="ruleForm.signature" clearable></el-input>
<el-form-item v-else>
{{ruleForm.signature}}
</el-form-item>
</el-form-item>
<el-form-item label="手机号码:" prop="phoneNumber">
<el-form-item>
{{ruleForm.phoneNumber}}
</el-form-item>
</el-form-item>
<el-form-item label="邮箱:" prop="email">
<el-form-item>
{{ruleForm.email}}
</el-form-item>
</el-form-item>
<el-form-item label="性别:" prop="gender">
<el-select v-if="ruleForm.editing" v-model="ruleForm.gender" placeholder="请选择" clearable>
<el-option
v-for="gender in ruleForm.genders"
:key="gender"
:value="gender">
</el-option>
</el-select>
<el-form-item v-else>
{{ruleForm.gender}}
</el-form-item>
</el-form-item>
<el-form-item label="生日:" prop="birthday">
<el-date-picker v-if="ruleForm.editing"
type="date" format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd"
placeholder="选择日期"
v-model="ruleForm.birthday"
style="width: 100%;"></el-date-picker>
<el-form-item v-else>
{{ruleForm.birthday}}
</el-form-item>
</el-form-item>
<el-form-item label="所在地:" prop="signature">
<el-input v-if="ruleForm.editing" v-model="ruleForm.location" clearable>{{ruleForm.location}}</el-input>
<el-form-item v-else>
{{ruleForm.location}}
</el-form-item>
</el-form-item>
<el-form-item>
<el-button v-if="ruleForm.editing" type="primary" @click="updateUser('ruleForm')">保存</el-button>
<el-button v-else @click="ruleForm.editing=true">修改信息</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import global from '../Global'
import {refreshUserInfo} from '../Utils'
export default {
data() {
let checkMobileNumber = (rule, value, callback) => {
if (!value) {
// return new Error("请输入电话号码");
callback()
} else {
const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
const isPhone = reg.test(value)
value = Number(value) //转换为数字
if (typeof value === 'number' && !isNaN(value)) {//判断是否为数字
value = value.toString() //转换成字符串
if (value.length < 0 || value.length > 12 || !isPhone) { //判断是否为11位手机号
callback(new Error('手机号码格式如:138xxxx8754'))
} else {
callback()
}
} else {
callback(new Error('请输入正确的电话号码'))
}
}
}
let checkEmail = (rule, value, callback) => {
if (!value) {
callback()
} else {
const reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
const email = reg.test(value)
if (!email) {
callback(new Error('邮箱格式如:admin@163.com'))
} else {
callback()
}
}
}
return {
ruleForm: {
editing: false,
id: '',
email: '',
nickname: '',
signature: '',
phoneNumber: '',
gender: '',
genders: [],
birthday: '',
location: '',
avatarId: '',
avatarUrl: require('../assets/img/defaultAvatar.jpeg'),
imageUrl: '',
uploadUrl: global.BASE_URL + '/user/uploadAvatar'
},
rules: {
nickname: [
{required: false, message: '请输入昵称'},
{min: 0, max: 20, message: '长度在 0 到 20 个字符', trigger: 'blur'}
],
signature: [
{required: false, message: '请输入签名'},
{min: 0, max: 100, message: '长度在 0 到 100 个字符', trigger: 'blur'}
],
phoneNumber: [
{validator: checkMobileNumber, trigger: 'blur', required: false},
],
email: [
{validator: checkEmail, message: '请输入邮箱', trigger: 'blur', required: false}
],
gender: [
{required: false, message: '请选择性别', trigger: 'change'}
],
birthday: [
{required: false, type: 'string', message: '请选择日期', trigger: 'change'}
],
location: [
{required: false, message: '请输入所在地', trigger: 'blur'}
],
}
}
},
methods: {
getUserInfo() {
this.$axios.get('/user/info')
.then(response => {
if (response.data.result) {
this.ruleForm.id = response.data.result.id
this.ruleForm.nickname = response.data.result.nickname
this.ruleForm.signature = response.data.result.signature
this.ruleForm.phoneNumber = response.data.result.phoneNumber
this.ruleForm.gender = response.data.result.gender
this.ruleForm.birthday = response.data.result.birthday
this.ruleForm.location = response.data.result.location
this.ruleForm.avatarId = response.data.result.avatarId
if (this.ruleForm.avatarId) {
this.ruleForm.avatarUrl = global.BASE_URL + '/user/loadImage?id=' + this.ruleForm.avatarId
}
this.ruleForm.email = response.data.result.email
} else {
console.log('获取用户信息失败: ' + response.data.msg)
}
})
},
updateUser(formName) {
console.log('start updateUser')
this.$refs[formName].validate((valid) => {
if (valid) {
let params = {
id: this.ruleForm.id,
nickname: this.ruleForm.nickname,
signature: this.ruleForm.signature,
gender: this.ruleForm.gender,
birthday: this.ruleForm.birthday,
location: this.ruleForm.location
}
this.$axios.post('/user/update', params)
.then(() => {
this.$message.success('更新信息成功')
this.ruleForm.editing = false
// 更新成功后,更新session中保存的用户信息
refreshUserInfo()
})
} else {
console.log('填写的数据不符合要求,请重新输入')
return false
}
})
},
genderList() {
this.$axios.get('/user/listGender', this.data)
.then(response => {
this.ruleForm.genders = response.data.result
})
},
handleAvatarSuccess(res, file) {
this.ruleForm.imageUrl = URL.createObjectURL(file.raw)
console.log('上传图片成功')
},
handleError() {
console.log('图片上传失败')
},
beforeAvatarUpload(file) {
console.log(file.type)
const isSupportedFormat = file.type === 'image/jpeg' || file.type === 'image/png'
const isLte10M = file.size / 1024 / 1024 <= 10
if (!isSupportedFormat) {
this.$message.error('上传头像图片只能是 JPG 或 PNG 格式!')
}
if (!isLte10M) {
this.$message.error('上传头像图片大小不能超过 10MB!')
}
return isSupportedFormat && isLte10M
}
},
created() {
this.getUserInfo()
this.genderList()
}
}
</script>
<style scoped>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>