# 二、Layout 处理## 创建首页组件并配置路由1、创建 `src/views/home/index.vue````html
<template><div class="home-container">首页</div>
</template><script>
export default {name: 'HomeIndex',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {}
}
</script><style scoped lang="less"></style>```2、然后在路由表中<img src="assets/image-20200421172340709.png" alt="image-20200421172340709" style="zoom:50%;" />3、登录成功,跳转到首页测试## 创建 Layout 组件并配置路由1、创建 `src/views/layout/index.vue````html
<template><div class="layout-container"><div>顶部导航栏</div><div>侧边导航栏</div><!-- 子路由出口 --><router-view /></div>
</template><script>
export default {name: 'LayoutIndex',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {}
}
</script><style scoped lang="less"></style>
```2、配置 layout 路由<img src="assets/image-20200421172555035.png" alt="image-20200421172555035" style="zoom:50%;" />3、最后测试## 使用 Container 布局容器 搭建页面结构> 参考文档:[Container 布局容器](https://element.eleme.cn/#/zh-CN/component/container)```html
<template><el-container class="layout-container"><el-asideclass="aside"width="200px">Aside</el-aside><el-container><el-header class="header">Header</el-header><el-main class="main"><!-- 子路由出口 --><router-view /></el-main></el-container></el-container>
</template><script>
export default {name: 'LayoutIndex',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {}
}
</script><style scoped lang="less">
.layout-container {position: fixed;left: 0;right: 0;top: 0;bottom: 0;
}.aside {background-color: #d3dce6;
}.header {background-color: #b3c0d1;
}.main {background-color: #e9eef3;
}
</style>
```## 处理侧边栏导航菜单1、创建 `src/views/layout/components/aside.vue````html
<template><!--el-menu-item 的 index 不能重复,确保唯一即可--><el-menuclass="nav-menu"default-active="/"background-color="#002033"text-color="#fff"active-text-color="#ffd04b"router><el-menu-item index="/"><i class="el-icon-s-home"></i><span slot="title">首页</span></el-menu-item><el-menu-item index="/article"><i class="el-icon-document"></i><span slot="title">内容管理</span></el-menu-item><el-menu-item index="/image"><i class="iconfont iconimage"></i><span slot="title">素材管理</span></el-menu-item><el-menu-item index="/publish"><i class="iconfont iconpublish"></i><span slot="title">发布文章</span></el-menu-item><el-menu-item index="/comment"><i class="iconfont iconcomment"></i><span slot="title">评论管理</span></el-menu-item><el-menu-item index="/fans"><i class="el-icon-setting"></i><span slot="title">粉丝管理</span></el-menu-item><el-menu-item index="/settings"><i class="el-icon-setting"></i><span slot="title">个人设置</span></el-menu-item></el-menu>
</template><script>
export default {name: 'AppAside',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {}
}
</script><style scoped lang="less">
.nav-menu {.iconfont {margin-right: 10px;padding-left: 5px;}
}
</style>```2、在 layout 中加载使用侧边栏导航菜单组件<img src="assets/image-20200421173310913.png" alt="image-20200421173310913" style="zoom:50%;" />## 处理页面顶栏1、创建 `src/views/layout/components/header.vue` 组件```html
<template><div class="header-container"><div><i class="el-icon-s-fold"></i><span>江苏传智播客科技教育有限公司</span></div><el-dropdown><div class="avatar-wrap"><img class="avatar" src="http://toutiao.meiduo.site/FrvifflobfNNRM9V_ZBTI2ZaTH4n" alt=""><span>用户昵称</span><i class="el-icon-arrow-down el-icon--right"></i></div><el-dropdown-menu slot="dropdown"><el-dropdown-item>设置</el-dropdown-item><el-dropdown-item>退出</el-dropdown-item></el-dropdown-menu></el-dropdown></div>
</template><script>
export default {name: 'AppHeader',components: {},props: {},data () {return {}},computed: {},watch: {},created () {},mounted () {},methods: {}
}
</script><style scoped lang="less">
.header-container {width: 100%;height: 100%;display: flex;justify-content: space-between;align-items: center;border-bottom: 1px solid #ccc;.avatar-wrap {display: flex;align-items: center;.avatar {width: 30px;height: 30px;border-radius: 50%;margin-right: 10px;}}
}
</style>```2、然后在 layout 中加载使用<img src="assets/image-20200421174653839.png" alt="image-20200421174653839" style="zoom:50%;" />## 在顶栏中展示当前登录用户1、在 `api/user.js` 中封装请求方法```js
// 获取用户信息
export const getUserProfile = () => {return request({method: 'GET',url: '/mp/v1_0/user/profile',// 后端要求把需要授权的用户身份放到请求头中// axios 可以通过 headers 选项设置请求头headers: {// 属性名和值都得看接口的要求// 属性名:Authorization,接口要求的// 属性值:Bearer空格token数据Authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTg5MDkxMjYsInVzZXJfaWQiOjEsInJlZnJlc2giOmZhbHNlLCJ2ZXJpZmllZCI6dHJ1ZX0.EdKErKDqMc3snkYxqt02jSa8t9G44002yWKY3CMOMJg'}})
}
```2、在 header 组件中请求获取数据<img src="assets/image-20200421174841178.png" alt="image-20200421174841178" style="zoom:50%;" />3、把请求到的数据绑定到模板中<img src="assets/image-20200421175004383.png" alt="image-20200421175004383" style="zoom:50%;" />## Token 处理1、在登录成功以后将用户信息存储到本地存储<img src="assets/image-20200422120805576.png" alt="image-20200422120805576" style="zoom:50%;" />> 注意:代码是不折行的
>
> 本地存储只能存字符串,如果需要存储数组或者对象数据,则转为 JSON 格式字符串2、然后在请求的时候获取本地存储中的 user 数据使用 token<img src="assets/image-20200422120925785.png" alt="image-20200422120925785" style="zoom:50%;" />## 使用拦截器统一设置用户 Token> axios 拦截器官方示例:https://github.com/axios/axios#interceptors在 request 请求模块中添加如下代码:```js
// 请求拦截器
request.interceptors.request.use(// 任何所有请求会经过这里// config 是当前请求相关的配置信息对象// config 是可以修改的function (config) {const user = JSON.parse(window.localStorage.getItem('user'))// 如果有登录用户信息,则统一设置 tokenif (user) {config.headers.Authorization = `Bearer ${user.token}`}// 然后我们就可以在允许请求出去之前定制统一业务功能处理// 例如:统一的设置 token// 当这里 return config 之后请求在会真正的发出去return config},// 请求失败,会经过这里function (error) {return Promise.reject(error)}
)
```## 处理侧边菜单的展开/收起状态1、在 layout 组件中声明数据用来控制侧边导航菜单的展开收起状态<img src="assets/image-20200422121315411.png" alt="image-20200422121315411" style="zoom:50%;" />2、在 layout 组件中处理图标的点击状态<img src="assets/image-20200422121352145.png" alt="image-20200422121352145" style="zoom:50%;" />3、将 layout 组件中的 `isCollapse` 传递给侧边栏组件<img src="assets/image-20200422121446475.png" alt="image-20200422121446475" style="zoom:50%;" />> 别忘了把 el-aside 的 width 设置为 auto4、在 aside 组件中声明接收 props 数据并绑定到导航菜单组件中<img src="assets/image-20200422121540402.png" alt="image-20200422121540402" style="zoom:50%;" />## 控制页面访问权限在我们的项目中,除了登录页面,其它所有页面都需要具有登录状态才能访问。也就是说我们要给这些需要登录才能访问的页面进行统一控制。通常的做法就是利用[路由的导航守卫]([https://router.vuejs.org/zh/guide/advanced/navigation-guards.html)来统一处理。所谓的路由拦截器就是一个公共的页面访问门卫,说白了就是所有的页面访问都要经过这里,我们可以在这里执行一共公共的操作,例如校验是否具有登录状态。> 提示:官方文档叫导航守卫,都是一个意思。具体做法就是在 `src/router/index.js` 中:```js
// 路由导航守卫:说白了所有页面的导航都会经过这里
// 守卫页面的导航的
// to:要去的路由信息
// from:来自哪里的路由信息
// next:放行方法
router.beforeEach((to, from, next) => {// 如果要访问的页面不是 /login,校验登录状态// 如果没有登录,则跳转到登录页面// 如果登录了,则允许通过// 允许通过// next()const user = JSON.parse(window.localStorage.getItem('user'))// 校验非登录页面的登录状态if (to.path !== '/login') {if (user) {// 已登录,允许通过next()} else {// 没有登录,跳转到登录页面next('/login')}} else {// 登录页面,正常允许通过next()}
})
```> 关于路由导航守卫更详细的用户请参考官方文档:[https://router.vuejs.org/zh/guide/advanced/navigation-guards.html## 结合导航守卫实现页面切换顶部进度条- [nprogress](https://github.com/rstacruz/nprogress)
- 路由前置钩子
- 路由后置钩子1、安装 nprogress```bash
# yarn add nprogress
npm i nprogress
```> 注意:项目中不要乱用包管理工具,要从一而终,不要一会儿这个,一会儿那个的。否则的话会导致一些包被莫名删除。
>
> 提示:如果想要从一个包管理工具切换到另一个包管理工具:
>
> 1、手动删除 node_modules
>
> 2、执行 `npm install` 或者 `yarn install` 或者 `cnpm install` 把所有依赖项重新安装一遍
>
> 3、之后固定使用 npm、yarn、cnpm 来装包
>
> 注意:cnpm 就不建议使用了。2、在 `main.js` 中引入 `nprogress.css` 样式文件```js
// 加载 nprogress 中的指定的样式文件
// 注意:加载第三方包中的具体文件不需要写具体路径,直接写包名即可
// 总结就是:"包名/具体文件路径"
import "nprogress/nprogress.css";
```3、在路由的全局前置守卫中,开启进度条```js
...
+ import NProgress from 'nprogress'router.beforeEach((to, from, next) => {// 开启顶部导航进度条特效
+  NProgress.start()// 停止导航// 我们可以在一些特殊情况下,停留在当前页面,中断当前导航// next(false)// next()// 1. 如果访问的是登录页面,则直接放行if (to.path === '/login') {next()// 停止代码往后执行return}// 2. 非登录页面,校验登录状态// 2.1 获取用户 tokenconst token = window.localStorage.getItem('user-token')// 2.2 判断是否有 token,有就通过if (token) {// 导航通过,放行,访问哪里就往哪里走next()} else {// 2.3 没有,就跳转到登录页next('/login') // 跳转到指定路由}
})
```4、在路由的全局后置钩子中,关闭进度条特效```js
router.afterEach((to, from) => {// 结束顶部的导航进度条NProgress.done();
});
```最后,回到浏览器中测试访问。## 用户退出1、给退出按钮注册点击事件<img src="assets/image-20200422172829358.png" alt="image-20200422172829358" style="zoom:50%;" />> 注意:并不是所有的组件在注册事件的时候需要使用 `.native` 修饰符,例如 el-button 组件注册点击事件就不需要,这主要是因为该组件内部处理了。
>
> 什么时候使用 `.native`?首先肯定是在组件上注册事件可能会用到,如果普通方式注册不上,这个时候加 `.native` 修饰符。
>
> 例如你给一个组件注册一个 `input` 事件,如果直接 `@input` 注册无效,那就试一下 `@input.native`。2、处理函数如下```js
onLogout () {this.$confirm('确认退出吗?', '退出提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {// 把用户的登录状态清除window.localStorage.removeItem('user')// 跳转到登录页面this.$router.push('/login')}).catch(() => {this.$message({type: 'info',message: '已取消退出'})})
}
```最后,回到浏览器测试。

前端学习(2455):layout处理相关推荐

  1. layui前端页面table表格怎么格式化转换时间_个人经历:我的前端学习历程

    很难想象一个半年前还在做后台开发,对前端知之甚少的我,现在也可以从事前端开发了.这半年的学习过程将会是我人生一笔宝贵的财富,这让我想到一句话"在成长的道路上,我们不要给自己设定界限,只要拥有 ...

  2. web 前端学习线路图

    web 前端学习线路图 一.HTML 教程 HTML教程 HTML简介 HTML编辑器 HTML基础 HTML元素 HTML属性 HTML标题 HTML段落 HTML样式 HTML格式化 HTML引用 ...

  3. 我的前端学习历程,你认同吗

    我的前端学习历程 很难想象一个半年前还在做后台开发,对前端知之甚少的我,现在也可以从事前端开发了.这半年的学习过程将会是我人生一笔宝贵的财富,这让我想到一句话"在成长的道路上,我们不要给自己 ...

  4. 前端学习六——html5+CSS3

    前端学习六--html5+CSS3 HTML5 H5新增语义标签 多媒体标签 audio音频标签 audio音频标签常见属性 音频标签语法 视频标签video 视频标签语法 H5新增input表单.表 ...

  5. 【FE前端学习】第二阶段任务-基础

    技能学习部分: 1.需要熟练掌握HTML标签以及CSS各个常用属性. 2.掌握CSS3 常用属性 3.掌握jquery的基本用法,对于JS基本逻辑语句需要熟练掌握 上文 [FE前端学习]第二阶段任务- ...

  6. Web前端学习有哪些技巧?

    想要学好web前端技术,在学习过程中找到合适的方法和技巧,那么在实际学习过程中会更加的容易和快速掌握知识重点,尤其是对于初学者尤为关键,下面小编就为大家详细的介绍一下Web前端学习有哪些技巧?希望能够 ...

  7. “计算机之子”winter:我的前端学习路线与方法

    你好,我是winter.今天我们一起来聊聊前端的学习路线与方法. 到现在为止,前端工程师已经成为研发体系中的重要岗位之一.可是,与此相对的是,我发现极少或者几乎没有大学的计算机专业愿意开设前端课程,更 ...

  8. python比前端好学吗_前端学习到底难不难?

    难易程度是相对的,不是绝对的. 前端学习相对于java,python等肯定是更为简单的.精通会有难度,而且更新速度很快,需要不断的充实自己,提升自己,这也是一个难点. 前端学习初期,不知道该怎么学,学 ...

  9. hbuilder前端需要的插件_最新web前端学习路线

    随着互联网的深入发展,前端开发工程师已成为市场上极具竞争力的人才.许多学生,包括以前的UI,java,或完全零基础,想学习的前端.下面的思维导图是在互联网上广泛传播的前端学习地图.许多初学者说,当他们 ...

  10. html 表单自动数值,web前端学习技术之对HTML5 智能表单的理解

    原标题:web前端学习技术之对HTML5 智能表单的理解 Html5新增input的form属性,用于指向特定form表单的id,实现input无需放在form标签之中,即可通过表单进行提交. - t ...

最新文章

  1. 原创 | 常见损失函数和评价指标总结(附公式代码)
  2. 并发编程之 源码剖析 线程池 实现原理
  3. 百度API地图 ,房产频道的标注方法
  4. SQLite剖析之临时文件、内存数据库
  5. xcode选择活动的开发人员目录错误
  6. python3.6安装-python3.6的安装及注意事项
  7. c#如何识别一张图片的格式
  8. 二叉树经典题之线索二叉树(中序)
  9. 求出m~n的整数中1出现的次数
  10. AI队列长度检测:使用YOLO进行视频中的对象检测
  11. markdown 编辑器_推荐一款公众号 Markdown 编辑器
  12. 解读千人千面,洞悉数据智能的价值(附ppt下载链接)
  13. 如何解决: ModuleNotFoundError: No module named ‘object_detection‘
  14. 【Spring第九篇】AOP
  15. 串口上升时间标准_为什么串口比并口快?
  16. 苹果软解ID软件(X.PASSWORD-XIMEI 苹果id锁)--上帝左手汉化组(内附即时更新)
  17. 敏捷计划是否基于功能,是否更好?
  18. WORD文档编辑锁定
  19. 2022年6月青少年软件编程(Python)等级考试试卷(一级)
  20. 电脑没有使用计算机进入睡眠状态,电脑打不开,屏上显示:无视频输入,进入睡眠模式。怎么处理...

热门文章

  1. JAVA基础_修饰符
  2. 接口之用例编写、验证
  3. 各种蕴含算法思想的DP - 3
  4. thinkphp5 ajax搜索+分页
  5. java集合框架05——ArrayList和LinkedList的区别
  6. 由于可能不会将凭据发送到远程计算机,因此将不会进行连接。若要获得协助,请与您的系统管理员联系。...
  7. jquery +做CheckBoxList全选,反选
  8. (搬家文) c++引用深入探讨
  9. iframe vue 前进 后退_vue常见面试题
  10. python中add_Python add()函数是如何使用呢?