vue 布局页,vue模板页,页面跳转,子页面切换,页面切换。页面模板,布局模板。vue路由配置 电脑版发表于:2020/11/16 21:31 vue里边点击菜单切换页面的效果,其实和mvc里边的布局页很类似。使用router-view来挖坑,和mvc里边的@RenderBody()挖坑一样,都是一个占位符。然后页面切换就是使用this.$router.push(path)方法即可。当然还要配合一点路由配置就行了。 **比如我们要实现这样一个简单的页面切换:** ![](https://img.tnblog.net/arcimg/aojiancc2/e749952933f2495f9839ea803f7ae5f6.png) 点击我的实验可以跳转到我的实验 ![](https://img.tnblog.net/arcimg/aojiancc2/3e92e34b0b1c452998a9fdd2d2b119a5.png) 就这种简单的页面切换效果。其实顶部还有切换菜单,相当于顶部1级,这块2级,其实实现方式完全一样,甚至比mvc里边的嵌套布局页,或者叫二级布局页还要简单,耦合性定低。 ### 实现上面的布局 #### 页面结构 ![](https://img.tnblog.net/arcimg/aojiancc2/e8baef28d2164b35a15df6c34d6e62e5.png) #### 路由配置 核心就是设置children ![](https://img.tnblog.net/arcimg/aojiancc2/9fd6d88e42f64ae39bd45513b136783d.png) 如果我的实验里边还需要进行页面切换,那么在我的实验里边在配置children就可以了。同样的我这里的个人中心其实也是另外一个页面下面的children。可以所以嵌套 #### index页面 ``` <template> <div class="app-container"> <div class="usercenter_left"> <div class="userinfo"> <div class="headimgwapper"> <img class="headimg" src="https://img.tnblog.net/userdata/heads/dbc68332d521436c983fbc3adc6d9c7f.jpeg" alt="" srcset=""> </div> <div style="padding:20px"> <div class="sumtimes"> <span style="background: #FE4444;height: 20px;width: 20px;color:#fff;display: inline-block;border-radius: 50px;line-height: 20px;text-align: center;">累</span> <span>计时长:506 小时 46 分2</span> </div> <div class="onlinetimes"> <span style="background: #EA740B;height: 20px;width: 20px;color:#fff;display: inline-block;border-radius: 50px;line-height: 20px;text-align: center;">今</span> <span>日时长:25 小时 46 分 50 秒</span> </div> </div> </div> <div class="menuwapper"> <div class="menuitem">学期报告</div> <div class="menuitem menuitemfocus" @click="jump('/user/myfeedback', $event)">我的反馈</div> <div class="menuitem">我的评估</div> <div class="menuitem" @click="jump('/user/mylabroom', $event)">我的实验</div> <div class="menuitem">我的产教</div> <div class="menuitem">我的考试</div> <div class="menuitem">个人信息</div> </div> </div> <div class="usercenter_right"> <router-view /> </div> </div> </template> <script> export default { data() { return { courseID: '', labId: '', chapter: {}, } }, mounted() { }, methods: { jump(path, event) { //后面换成判断地址,根据地址栏来选中 //先把元素的样式全部回归成默认状态 let childNodes = event.currentTarget.parentNode.childNodes for (let index = 0; index < childNodes.length; index++) { const element = childNodes[index]; element.className = "menuitem" } //给当前点击的元素添加选中样式 event.currentTarget.className = "menuitem menuitemfocus" //进行页面跳转 this.$router.push(path) } } } </script> <style scoped="scoped"> .app-container { width: 1200px; /* min-height: 200px; */ display: flex; margin: 20px auto; } .usercenter_left { width: 235px; } .usercenter_left .userinfo { background-color: #fff; padding-top: 20px; padding-bottom: 10px; } .usercenter_left .headimgwapper { text-align: center; } .usercenter_left .headimg { width: 100px; height: 100px; border-radius: 50%; } .usercenter_left .menuwapper { min-height: 300px; margin-top: 20px; /* width: 240px; */ background-color: #fff; } .usercenter_left .sumtimes { font-size: 13px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #000000; } .usercenter_left .onlinetimes { font-size: 13px; margin-top: 10px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #000000; } .menuwapper .menuitem { text-align: center; /* width: 66px; */ height: 60px; font-size: 15px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #747774; cursor: pointer; letter-spacing: 2px; /* line-height: 21px; */ } .menuwapper .menuitem:first-child { padding-top: 34px; } .menuwapper .menuitem:hover { color: #1C6CB8; } .menuwapper .menuitemfocus { color: #1C6CB8; } .usercenter_right { flex: 1; background-color: #fff; margin-left: 20px; /* min-height: 200px; */ } </style> ``` index页面主要就是使用`<router-view />`来做占位符。以及页面的切换方法,核心就是`this.$router.push(path)`。还有就是页面切换时候的菜单选中效果的处理。 **菜单选中调整后使用的是** 具体分析请看:https://www.tnblog.net/aojiancc2/article/details/7902 ``` <script> export default { data() { return { stuInfo: JSON.parse(localStorage['userinfo']).stuInfo, courseID: '', labId: '', chapter: {} } }, watch: { // 监听路由变化的时候在进行菜单选中 // $route(to, from) { // console.log('导航页to', to) // this.choiseMenu(to.fullPath) // } }, mounted() { const routePath = this.$route.path this.choiseMenu(routePath) }, methods: { // 菜单选中,可以跳转的路由在判断应该选中的菜单 choiseMenu(routePath) { const childNodes = document.getElementById('usersubmenu').getElementsByTagName('div') for (let index = 0; index < childNodes.length; index++) { const element = childNodes[index] console.log(element.getAttribute('href')) if (routePath === element.getAttribute('href')) { element.className = 'menuitem menuitemfocus' } else { element.className = 'menuitem' } } }, jump(event) { const href = event.currentTarget.getAttribute('href') // 菜单选中 this.choiseMenu(href) this.$router.push(href) } } } </script> ``` ### 我的实验页面 子页面的内容其实就不重要了,这里可以当中一个模板贴一下 ``` <template> <div class="labroom-container"> <div class="title-wapper"> <div class="title">我的实验</div> </div> <div class="split-line"> </div> <div class="labroom-content"> <div class="labroom-info"> <el-row :gutter="20"> <el-col :span="4"> <div class="labroom-info-item"> <div class="labroom-info-desc-wapper"> <div> 188个 </div> <div> 实验总数 </div> </div> </div> </el-col> <el-col :span="4"> <div class="labroom-info-item"> <div class="labroom-info-desc-wapper"> <div> 198个 </div> <div> 应完成数 </div> </div> </div> </el-col> <el-col :span="4"> <div class="labroom-info-item"> <div class="labroom-info-desc-wapper"> <div> 188个 </div> <div> 已完成数 </div> </div> </div> </el-col> <el-col :span="4"> <div class="labroom-info-item"> <div class="labroom-info-desc-wapper"> <div> 188个 </div> <div> 整体完成率 </div> </div> </div> </el-col> <el-col :span="4"> <div class="labroom-info-item"> <div class="labroom-info-desc-wapper"> <div> 79% </div> <div> 必做完成率 </div> </div> </div> </el-col> <el-col :span="4"> <div class="labroom-info-item"> <div class="labroom-info-desc-wapper"> <div> 7名 </div> <div> 班级排名 </div> </div> </div> </el-col> </el-row> </div> </div> </div> </template> <script> export default { // 组件名字 name: 'MyLabroom', // 组件参数 props: { percentage: { type: Number, default: 0 }, title: { type: String, default: '' }, }, data() { return { courseID: '', labId: '', chapter: {}, } }, mounted() { this.initPic() }, // 组件方法 methods: { initPic() { } } } </script> <style scoped="scoped" lang="scss"> .labroom-container { padding: 0 20px; .title-wapper { height: 60px; // background-color: #ffabcd; line-height: 60px; } .title { font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #333339; font-size: 16px; } .split-line { height: 1px; background: #EAEEF0; // width: 100%; margin-left: -20px; margin-right: -20px; } .labroom-info { margin-top: 26px; .labroom-info-item { height: 62px; background: #ECF5FF; border-radius: 2px 2px 2px 2px; opacity: 1; border: 1px solid #B3D8FF; text-align: center; display: flex; justify-content: center; font-size: 12px; font-family: MicrosoftYaHei-Regular, MicrosoftYaHei; font-weight: 400; color: #409EFF; .labroom-info-desc-wapper { align-self: center; } } } } </style> ``` 内容布局多的一版本: ### 实验页面 贴一下代码可以当一个模板,需要类似的样式可以直接用 ``` <template> <div class="feedback-container"> <div class="title-wapper"> <div class="title">我的反馈</div> </div> <div class="split-line"> </div> <div> <div class="feedback-content"> <div class="feedback-item"> <div class="feedback-title"> <div class="feedback-time"> 反馈时间: 2020-09-28 15:48:51 </div> <div class="feedback-type"> 问题类型:系统问题 </div> </div> <div class="feedback-message"> 反馈内容:如果是浏览速度、系统BUG、视觉显示等问题,请注明您使用的操作系统、浏览器以及版本号,以便我们尽快对应查 找问题并解决如果是浏览速度、系统BUG、视觉显示等问题,请注明您使用的操作系统、浏尽快对应查找问题并解决。 </div> <div class="feedback-descible"> 处理描述:如果是浏览速度、系统BUG、视觉显示等问题,请注明您使用的操作系统。 </div> <div class="feedback-dealinfo"> <div class="deal-result"> <span>处理结果:</span> <span>已解决</span> </div> <div class="deal-time"> 处理时间:2020-09-30 10:31:28 </div> </div> </div> <div class="feedback-item"> <div class="feedback-title"> <div class="feedback-time"> 反馈时间: 2020-09-28 15:48:51 </div> <div class="feedback-type"> 问题类型:系统问题 </div> </div> <div class="feedback-message"> 反馈内容:如果是浏览速度、系统BUG、视觉显示等问题,请注明您使用的操作系统、浏览器以及版本号,以便我们尽快对应查 找问题并解决如果是浏览速度、系统BUG、视觉显示等问题,请注明您使用的操作系统、浏尽快对应查找问题并解决。 </div> <div class="feedback-descible"> 处理描述:如果是浏览速度、系统BUG、视觉显示等问题,请注明您使用的操作系统。 </div> <div class="feedback-dealinfo"> <div class="deal-result"> <span>处理结果:</span> <span>已解决</span> </div> <div class="deal-time"> 处理时间:2020-09-30 10:31:28 </div> </div> </div> </div> </div> </div> </template> <script> export default { // 组件名字 name: 'Myfeedback', // 组件参数 props: { percentage: { type: Number, default: 0 }, title: { type: String, default: '' }, }, data() { return { courseID: '', labId: '', chapter: {}, } }, mounted() { this.initPic() }, // 组件方法 methods: { initPic() { } } } </script> <style scoped="scoped" lang="scss"> .feedback-container { padding: 0 20px; .title-wapper { height: 60px; // background-color: #ffabcd; line-height: 60px; } .title { font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #333339; font-size: 16px; } .split-line { height: 1px; background: #EAEEF0; // width: 100%; margin-left: -20px; margin-right: -20px; } // .feedback-content { // } .feedback-item { margin-top: 20px; border: 1px solid #EAEEF0; padding-bottom: 20px; .feedback-title { display: flex; background: #EAEEF0; height: 53px; line-height: 53px; padding: 0 20px; .feedback-time { font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } .feedback-type { font-size: 14px; margin-left: 43px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } } .feedback-message { margin-top: 20px; font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; letter-spacing: 1px; color: #333339; padding: 0 20px; } .feedback-descible { margin-top: 20px; font-size: 14px; padding: 0 20px; letter-spacing: 1px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } .feedback-dealinfo { display: flex; padding: 0 20px; margin-top: 15px; .deal-result { font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; } .deal-result span:first-child { color: #7C7C7C; } .deal-result span:last-child { color: #28B28B; } .deal-time { margin-left: 50px; font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } } } } </style> ``` 包含了调用接口以及数据绑定的 ``` <template> <div class="feedback-container"> <div class="title-wapper"> <div class="title">我的反馈</div> </div> <div class="split-line"> </div> <div> <div class="feedback-content"> <div class="feedback-item" v-for="(item, i) in feedbackList" :key="i"> <div class="feedback-title"> <div class="feedback-time"> 反馈时间: {{ changeDateFormat(item.createTime) }} </div> <div class="feedback-type"> <span>问题类型:</span> <span v-if="item.feedbackType == 1" >系统问题</span> <span v-if="item.feedbackType == 2" >内容问题</span> <span v-if="item.feedbackType == 3">我要吐槽</span> </div> </div> <div class="feedback-message"> 反馈内容:{{ item.feedbackDescribe }} </div> <div class="feedback-descible"> 处理描述:{{ item.dealingOpinion }} <!-- <span>处理描述:</span> --> <!-- <span v-if="item.dealType == 0" style="color:#ffba00">{{item.dealingOpinion}}</span> <span v-if="item.dealType == 1" style="color:#13ce66">{{item.dealingOpinion}}</span> <span v-if="item.dealType == 2" style="color:#ff4949">{{item.dealingOpinion}}</span> --> </div> <div class="feedback-dealinfo"> <div class="deal-result"> <span>处理结果:</span> <!-- <span>已解决</span> --> <!-- <span v-if="item.dealType == 0" style="color:#ffba00">未处理</span> <span v-if="item.dealType == 1" style="color:#13ce66">已处理</span> <span v-if="item.dealType == 2" style="color:#ff4949">已驳回</span> --> <el-tag v-if="item.dealType == 0" type="warning">未处理</el-tag> <el-tag v-if="item.dealType == 1" type="success">已处理</el-tag> <el-tag v-if="item.dealType == 2" type="danger">已驳回</el-tag> </div> <div class="deal-time"> 处理时间:{{ changeDateFormat(item.dealTime) }} </div> </div> </div> </div> </div> </div> </template> <script> export default { // 组件名字 name: 'Myfeedback', // 组件参数 props: { percentage: { type: Number, default: 0 }, title: { type: String, default: '' }, }, data() { return { feedbackList: [] } }, mounted() { this.saveFeedback() }, // 组件方法 methods: { changeDateFormat(jsondate) { var date = new Date(jsondate).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, ''); return date; }, //获取反馈 saveFeedback() { const _this = this this.$http.get('/education/api/Feedback/GetFeedbackListByStudent').then(res => { console.log("-----------------------------------------------") console.log(res) _this.feedbackList = res.data.data }).catch(e => { } ) } } } </script> <style scoped="scoped" lang="scss"> .feedback-container { padding: 0 20px; .title-wapper { height: 60px; // background-color: #ffabcd; line-height: 60px; } .title { font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #333339; font-size: 16px; } .split-line { height: 1px; background: #EAEEF0; // width: 100%; margin-left: -20px; margin-right: -20px; } // .feedback-content { // } .feedback-item { margin-top: 20px; border: 1px solid #EAEEF0; padding-bottom: 20px; .feedback-title { display: flex; background: #EAEEF0; height: 53px; line-height: 53px; padding: 0 20px; .feedback-time { font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } .feedback-type { font-size: 14px; margin-left: 43px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } } .feedback-message { margin-top: 20px; font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; // font-weight: normal; font-weight: 500; letter-spacing: 1px; line-height: 23px; color: #333339; padding: 0 20px; } .feedback-descible { margin-top: 20px; font-size: 14px; padding: 0 20px; letter-spacing: 1px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; color: #7C7C7C; } .feedback-dealinfo { display: flex; padding: 0 20px; margin-top: 15px; .deal-result { font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; } .deal-result span:first-child { color: #7C7C7C; } // .deal-result span:last-child { // color: #28B28B; // } .deal-time { margin-left: 50px; font-size: 14px; font-family: MicrosoftYaHei-, MicrosoftYaHei; font-weight: normal; // 如果前面处理结果使用了el-tag后高度保持一直 line-height: 32px; color: #7C7C7C; } } } } </style> ```