您好,登錄后才能下訂單哦!
vue3自己封裝面包屑功能組件的方式有哪些,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
面包屑導航可以將瀏覽過的頁面記錄下來,方便很快速的跳轉回某一個頁面,本文介紹了幾種自己封裝面包屑組件的方式,我們一起來看看如何實現的吧~
面包屑導航(BreadcrumbNavigation)這個概念來自童話故事“漢賽爾和格萊特”,當漢賽爾和格萊特穿過森林時,不小心迷路了,但是他們發現在沿途走過的地方都撒下了面包屑,讓這些面包屑來幫助他們找到回家的路。
看完上面的介紹,相信各位已經理解了面包屑組件的使用場景了。對的,沒錯,是用來記錄我們點擊了哪些頁面,方便我們再返回之前某一個頁面。
當網頁進行了多次跳轉后,用戶可能早就已經暈頭轉向了。作為程序猿的我們可能通過地址欄參數還可以分清楚當前處于哪一個位置,終歸網頁是要展示給用戶。用戶來使用的話,沒有面包屑導航的話,可能就對網頁產生了抵觸心理,使用面包屑導航將每次跳轉的頁面記錄下來,可以很好解決這一問題。
準備頁面結構和樣式,需要用到字體圖標
在public目錄下的index.html中引入cdn的字體圖標資源
<link rel="stylesheet" href="//at.alicdn.com/t/font_2143783_iq6z4ey5vu.css" rel="external nofollow" >
將需要外部傳入的值定義為自定義屬性
將外部寫在標簽內部的內容放置在默認插槽中
在src/components目錄下新建bread-crumbs.vue文件,公用的組件放在這個目錄下統一管理,文件名可自定義。
代碼如下(示例):
<template> <div class='bread-crumbs'> <div class="bread-crumbs-item"> <RouterLink to="/">首頁</RouterLink> </div> <i class="iconfont icon-angle-right"></i> <div v-if="parentName" class="bread-crumbs-item"> <RouterLink v-if="parentPath" :to="parentPath">{{parentName}}</RouterLink> <span v-else>{{parentName}}</span> </div> <i v-if="parentName" class="iconfont icon-angle-right"></i> <div class="bread-crumbs-item"> <span> <slot/> </span> </div> </div> </template> <script> export default { name: 'BreadCrumbs', props: { parentName: { type: String, default: '' }, parentPath: { type: String, default: '' } } } </script> <style scoped lang='less'> .bread-crumbs{ display: flex; padding: 25px 10px; &-item { a { text-decoration: none; color: #666; transition: all .4s; &:hover { color: #27ba9b; } } } i { font-size: 12px; font-style: normal; margin-left: 5px; margin-right: 5px; line-height: 22px; } } </style>
在src/components目錄下新建index.js文件,將封裝好的全局組件進行注冊
import BreadCrumbs from './bread-crumbs' export default { install (app) { app.component(BreadCrumbs.name, BreadCrumbs) } }
在main.js中注冊為插件
import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' // 導入并注冊 import myUI from './components' createApp(App).use(store).use(router).use(myUI).mount('#app')
傳入公共組件需要的值
代碼如下(示例):
<template> <div class="home-banner"> <bread-crumbs parentPath="/xxx" parentName="電器">空調</bread-crumbs> </div> </template> <script> export default { name: 'App', setup() { } } </script>
只能滿足基本需求,超過二級導航后就無法使用。
參考elementUI面包屑組件代碼
<el-breadcrumb separator="/"> <el-breadcrumb-item :to="{ path: '/' }">首頁</el-breadcrumb-item> <el-breadcrumb-item><a href="/" rel="external nofollow" >活動管理</a></el-breadcrumb-item> <el-breadcrumb-item>活動列表</el-breadcrumb-item> <el-breadcrumb-item>活動詳情</el-breadcrumb-item> </el-breadcrumb>
將每一個導航封裝為一個組件
在上一步封裝的基礎上繼續改進代碼
代碼如下(示例):
在src/component目錄下新建bread-crumbs-item組件,文件名可以自定義。
<template> <div class="bread-crumbs-item"> <RouterLink v-if="to" :to="to"><slot /></RouterLink> <span v-else><slot /></span> <i class="iconfont icon-angle-right"></i> </div> </template> <script> export default { name: 'BreadCurmbsItem', props: { to: { type: [String, Object] } } } </script>
還是在src/components目錄下的index.js中注冊為全局組件
import BreadCrumbs from './bread-crumbs' import BreadCrumbsItem from './bread-crumbs-item' export default { install (app) { app.component(BreadCrumbs.name, BreadCrumbs) app.component(BreadCrumbsItem .name, BreadCrumbsItem ) } }
修改BreadCrumbs.vue中代碼,將導航的每一項放置在默認插槽中
<template> <div class='bread-crumbs'> <slot /> </div> </template> <script> export default { name: 'BreadCrumbs' } </script> <style scoped lang='less'> .bread-crumbs { display: flex; padding: 25px 10px; :deep(&-item) { a { text-decoration: none; color: #666; transition: all 0.4s; &:hover { color: #27ba9b; } } } :deep(i) { font-style: normal; font-size: 12px; margin-left: 5px; margin-right: 5px; line-height: 22px; } } </style>
使用的時候,有多少個二級導航就使用幾個BreadCrumbsItem
代碼如下(示例):
<template> <div class="home-banner"> <!-- 面包屑 --> <BreadCrumbs> <BreadCrumbsItem to="/">首頁</BreadCrumbsItem> <BreadCrumbsItem to="/xxx">電器</BreadCrumbsItem> <BreadCrumbsItem >空調</BreadCrumbsItem> </BreadCrumbs> </div> </template> <script> export default { name: 'App', setup() { } } </script>
在最后一個導航后面會有多余的一個>指示標識
終極版,使用render函數自己進行拼接創建。
createElement
render render選項與h函數
指定組件顯示的內容:new Vue({選項})
el 選項,通過一個選擇器找到容器,容器內容就是組件內容
template 選項,<div>組件內容</div> 作為組件內容
render選項,它是一個函數,函數回默認傳人createElement的函數(h),這個函數用來創建結構,再render函數返回渲染為組件內容。它的優先級更高。
修改BreadCurmbsItem組件內的代碼
<template> <div class="bread-crumbs-item"> <RouterLink v-if="to" :to="to"><slot /></RouterLink> <span v-else><slot /></span> </div> </template> <script> export default { name: 'BreadCurmbsItem', props: { to: { type: [String, Object] } } } </script>
修改BreadCrumbs.vue中的代碼
代碼示例(如下):
<script> import { h } from 'vue' export default { name: 'BreadCrumbs', render () { // 用法 // 1. template 標簽去除,單文件組件 // 2. 返回值就是組件內容 // 3. vue2.0 的h函數傳參進來的,vue3.0 的h函數導入進來 // 4. h 第一個參數 標簽名字 第二個參數 標簽屬性對象 第三個參數 子節點 // 需求 // 1. 創建bread-crumbs父容器 // 2. 獲取默認插槽內容 // 3. 去除bread-crumbs-item組件的i標簽,因該由render函數來組織 // 4. 遍歷插槽中的item,得到一個動態創建的節點,最后一個item不加i標簽 // 5. 把動態創建的節點渲染再bread-crumbs標簽中 const items = this.$slots.default() const dymanicItems = [] items.forEach((item, i) => { dymanicItems.push(item) if (i < (items.length - 1)) { dymanicItems.push(h('i', { class: 'iconfont icon-angle-right' })) } }) return h('div', { class: 'bread-crumbs' }, dymanicItems) } } </script> <style lang='less'> // 將scope屬性去除,目的是為了樣式穿透至item組件中 .bread-crumbs { display: flex; padding: 25px 10px; &-item { a { text-decoration: none; color: #666; transition: all .4s; &:hover { color: #27ba9b; } } } i { font-size: 12px; margin-left: 5px; margin-right: 5px; line-height: 22px; // 樣式的方式,不合理 // &:last-child { // display: none; // } } } </style>
這個方式封裝后,讓全局組件的復用性更強了,強烈推薦使用
<template> <div class="home-banner"> <!-- 面包屑 --> <BreadCrumbs> <BreadCrumbsItem to="/">首頁</BreadCrumbsItem> <BreadCrumbsItem to="/xxx">電器</BreadCrumbsItem> <BreadCrumbsItem to="/xxx/xx">空調</BreadCrumbsItem> <BreadCrumbsItem >遙控器</BreadCrumbsItem> </BreadCrumbs> </div> </template> <script> export default { name: 'App', setup() { } } </script>
可以看到這樣封裝后,咱們自己封裝的面包屑導航已經支持多級導航了。而且最后一個導航后面的>指示標識也沒有了。
可以將高階寫法中的功能代碼使用jsx的方式進行重寫,jsx寫出來的代碼更加的簡潔明了。
export default { name: 'BreadCrumbs', render () { // vue2的render函數的形參是 h 函數 // vue3中h函數是導入的 // createElement(標簽名稱, 標簽的屬性, 標簽的子元素) // console.dir(this.$slots.default()) // 獲取XtxBread組件的所有的插槽里面填充組件實例 const items = this.$slots.default() const results = [] items.forEach((item, index) => { results.push(item) // 手動生成一個i圖標,添加到面包屑項目的后面 if (index < items.length - 1) { results.push(<i className='iconfont icon-angle-right'></i>) } }) return <div className='bread-crumbs'>{results}</div> } }
功能雖然很小,但是涵蓋的知識點很多,以上代碼均已在本地測試
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。