前端学习(2455):layout处理
生活随笔
收集整理的這篇文章主要介紹了
前端学习(2455):layout处理
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
# 二、Layout 處理## 創(chuàng)建首頁組件并配置路由1、創(chuàng)建 `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、登錄成功,跳轉(zhuǎn)到首頁測試## 創(chuàng)建 Layout 組件并配置路由1、創(chuàng)建 `src/views/layout/index.vue````html
<template><div class="layout-container"><div>頂部導(dǎo)航欄</div><div>側(cè)邊導(dǎo)航欄</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 布局容器 搭建頁面結(jié)構(gòu)> 參考文檔:[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>
```## 處理側(cè)邊欄導(dǎo)航菜單1、創(chuàng)建 `src/views/layout/components/aside.vue````html
<template><!--el-menu-item 的 index 不能重復(fù),確保唯一即可--><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">內(nèi)容管理</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">發(fā)布文章</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">個人設(shè)置</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 中加載使用側(cè)邊欄導(dǎo)航菜單組件<img src="assets/image-20200421173310913.png" alt="image-20200421173310913" style="zoom:50%;" />## 處理頁面頂欄1、創(chuàng)建 `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>設(shè)置</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%;" />## 在頂欄中展示當(dāng)前登錄用戶1、在 `api/user.js` 中封裝請求方法```js
// 獲取用戶信息
export const getUserProfile = () => {return request({method: 'GET',url: '/mp/v1_0/user/profile',// 后端要求把需要授權(quán)的用戶身份放到請求頭中// axios 可以通過 headers 選項(xiàng)設(shè)置請求頭headers: {// 屬性名和值都得看接口的要求// 屬性名:Authorization,接口要求的// 屬性值:Bearer空格token數(shù)據(jù)Authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTg5MDkxMjYsInVzZXJfaWQiOjEsInJlZnJlc2giOmZhbHNlLCJ2ZXJpZmllZCI6dHJ1ZX0.EdKErKDqMc3snkYxqt02jSa8t9G44002yWKY3CMOMJg'}})
}
```2、在 header 組件中請求獲取數(shù)據(jù)<img src="assets/image-20200421174841178.png" alt="image-20200421174841178" style="zoom:50%;" />3、把請求到的數(shù)據(jù)綁定到模板中<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%;" />> 注意:代碼是不折行的
>
> 本地存儲只能存字符串,如果需要存儲數(shù)組或者對象數(shù)據(jù),則轉(zhuǎn)為 JSON 格式字符串2、然后在請求的時候獲取本地存儲中的 user 數(shù)據(jù)使用 token<img src="assets/image-20200422120925785.png" alt="image-20200422120925785" style="zoom:50%;" />## 使用攔截器統(tǒng)一設(shè)置用戶 Token> axios 攔截器官方示例:https://github.com/axios/axios#interceptors在 request 請求模塊中添加如下代碼:```js
// 請求攔截器
request.interceptors.request.use(// 任何所有請求會經(jīng)過這里// config 是當(dāng)前請求相關(guān)的配置信息對象// config 是可以修改的function (config) {const user = JSON.parse(window.localStorage.getItem('user'))// 如果有登錄用戶信息,則統(tǒng)一設(shè)置 tokenif (user) {config.headers.Authorization = `Bearer ${user.token}`}// 然后我們就可以在允許請求出去之前定制統(tǒng)一業(yè)務(wù)功能處理// 例如:統(tǒng)一的設(shè)置 token// 當(dāng)這里 return config 之后請求在會真正的發(fā)出去return config},// 請求失敗,會經(jīng)過這里function (error) {return Promise.reject(error)}
)
```## 處理側(cè)邊菜單的展開/收起狀態(tài)1、在 layout 組件中聲明數(shù)據(jù)用來控制側(cè)邊導(dǎo)航菜單的展開收起狀態(tài)<img src="assets/image-20200422121315411.png" alt="image-20200422121315411" style="zoom:50%;" />2、在 layout 組件中處理圖標(biāo)的點(diǎn)擊狀態(tài)<img src="assets/image-20200422121352145.png" alt="image-20200422121352145" style="zoom:50%;" />3、將 layout 組件中的 `isCollapse` 傳遞給側(cè)邊欄組件<img src="assets/image-20200422121446475.png" alt="image-20200422121446475" style="zoom:50%;" />> 別忘了把 el-aside 的 width 設(shè)置為 auto4、在 aside 組件中聲明接收 props 數(shù)據(jù)并綁定到導(dǎo)航菜單組件中<img src="assets/image-20200422121540402.png" alt="image-20200422121540402" style="zoom:50%;" />## 控制頁面訪問權(quán)限在我們的項(xiàng)目中,除了登錄頁面,其它所有頁面都需要具有登錄狀態(tài)才能訪問。也就是說我們要給這些需要登錄才能訪問的頁面進(jìn)行統(tǒng)一控制。通常的做法就是利用[路由的導(dǎo)航守衛(wèi)]([https://router.vuejs.org/zh/guide/advanced/navigation-guards.html)來統(tǒng)一處理。所謂的路由攔截器就是一個公共的頁面訪問門衛(wèi),說白了就是所有的頁面訪問都要經(jīng)過這里,我們可以在這里執(zhí)行一共公共的操作,例如校驗(yàn)是否具有登錄狀態(tài)。> 提示:官方文檔叫導(dǎo)航守衛(wèi),都是一個意思。具體做法就是在 `src/router/index.js` 中:```js
// 路由導(dǎo)航守衛(wèi):說白了所有頁面的導(dǎo)航都會經(jīng)過這里
// 守衛(wèi)頁面的導(dǎo)航的
// to:要去的路由信息
// from:來自哪里的路由信息
// next:放行方法
router.beforeEach((to, from, next) => {// 如果要訪問的頁面不是 /login,校驗(yàn)登錄狀態(tài)// 如果沒有登錄,則跳轉(zhuǎn)到登錄頁面// 如果登錄了,則允許通過// 允許通過// next()const user = JSON.parse(window.localStorage.getItem('user'))// 校驗(yàn)非登錄頁面的登錄狀態(tài)if (to.path !== '/login') {if (user) {// 已登錄,允許通過next()} else {// 沒有登錄,跳轉(zhuǎn)到登錄頁面next('/login')}} else {// 登錄頁面,正常允許通過next()}
})
```> 關(guān)于路由導(dǎo)航守衛(wèi)更詳細(xì)的用戶請參考官方文檔:[https://router.vuejs.org/zh/guide/advanced/navigation-guards.html## 結(jié)合導(dǎo)航守衛(wèi)實(shí)現(xiàn)頁面切換頂部進(jìn)度條- [nprogress](https://github.com/rstacruz/nprogress)
- 路由前置鉤子
- 路由后置鉤子1、安裝 nprogress```bash
# yarn add nprogress
npm i nprogress
```> 注意:項(xiàng)目中不要亂用包管理工具,要從一而終,不要一會兒這個,一會兒那個的。否則的話會導(dǎo)致一些包被莫名刪除。
>
> 提示:如果想要從一個包管理工具切換到另一個包管理工具:
>
> 1、手動刪除 node_modules
>
> 2、執(zhí)行 `npm install` 或者 `yarn install` 或者 `cnpm install` 把所有依賴項(xiàng)重新安裝一遍
>
> 3、之后固定使用 npm、yarn、cnpm 來裝包
>
> 注意:cnpm 就不建議使用了。2、在 `main.js` 中引入 `nprogress.css` 樣式文件```js
// 加載 nprogress 中的指定的樣式文件
// 注意:加載第三方包中的具體文件不需要寫具體路徑,直接寫包名即可
// 總結(jié)就是:"包名/具體文件路徑"
import "nprogress/nprogress.css";
```3、在路由的全局前置守衛(wèi)中,開啟進(jìn)度條```js
...
+ import NProgress from 'nprogress'router.beforeEach((to, from, next) => {// 開啟頂部導(dǎo)航進(jìn)度條特效
+ NProgress.start()// 停止導(dǎo)航// 我們可以在一些特殊情況下,停留在當(dāng)前頁面,中斷當(dāng)前導(dǎo)航// next(false)// next()// 1. 如果訪問的是登錄頁面,則直接放行if (to.path === '/login') {next()// 停止代碼往后執(zhí)行return}// 2. 非登錄頁面,校驗(yàn)登錄狀態(tài)// 2.1 獲取用戶 tokenconst token = window.localStorage.getItem('user-token')// 2.2 判斷是否有 token,有就通過if (token) {// 導(dǎo)航通過,放行,訪問哪里就往哪里走next()} else {// 2.3 沒有,就跳轉(zhuǎn)到登錄頁next('/login') // 跳轉(zhuǎn)到指定路由}
})
```4、在路由的全局后置鉤子中,關(guān)閉進(jìn)度條特效```js
router.afterEach((to, from) => {// 結(jié)束頂部的導(dǎo)航進(jìn)度條NProgress.done();
});
```最后,回到瀏覽器中測試訪問。## 用戶退出1、給退出按鈕注冊點(diǎn)擊事件<img src="assets/image-20200422172829358.png" alt="image-20200422172829358" style="zoom:50%;" />> 注意:并不是所有的組件在注冊事件的時候需要使用 `.native` 修飾符,例如 el-button 組件注冊點(diǎn)擊事件就不需要,這主要是因?yàn)樵摻M件內(nèi)部處理了。
>
> 什么時候使用 `.native`?首先肯定是在組件上注冊事件可能會用到,如果普通方式注冊不上,這個時候加 `.native` 修飾符。
>
> 例如你給一個組件注冊一個 `input` 事件,如果直接 `@input` 注冊無效,那就試一下 `@input.native`。2、處理函數(shù)如下```js
onLogout () {this.$confirm('確認(rèn)退出嗎?', '退出提示', {confirmButtonText: '確定',cancelButtonText: '取消',type: 'warning'}).then(() => {// 把用戶的登錄狀態(tài)清除window.localStorage.removeItem('user')// 跳轉(zhuǎn)到登錄頁面this.$router.push('/login')}).catch(() => {this.$message({type: 'info',message: '已取消退出'})})
}
```最后,回到瀏覽器測試。
?
總結(jié)
以上是生活随笔為你收集整理的前端学习(2455):layout处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “约见”面试官系列之常见面试题之第八十七
- 下一篇: 前端学习(2186):知识回顾