封裝TabBar案例
TabBar.png
通過學習上面這個TabBar的封裝捅彻,感受一下組件化開發(fā)和封裝的思想组去。
一、第一步
先寫死步淹,就寫4個條目从隆,分別是首頁,分類缭裆,購物車键闺,我的,先寫在Vue.app中澈驼,把tab-bar的css樣式和tab-bar-item的樣式調(diào)整好
<template>
<div id="app">
<div id="tab-bar">
<div class="tab-bar-item">
<img src="./assets/img/tabbar/home.svg" alt="...">
<div class="item-text">首頁</div>
</div>
<div class="tab-bar-item">
<img src="./assets/img/tabbar/category.svg" alt="...">
<div class="item-text">分類</div>
</div>
<div class="tab-bar-item">
<img src="./assets/img/tabbar/shopcart.svg" alt="...">
<div class="item-text">購物車</div>
</div>
<div class="tab-bar-item">
<img src="./assets/img/tabbar/profile.svg" alt="...">
<div class="item-text">我的</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
/* 在style中引用文件這樣子使用@import + url */
@import './assets/css/base.css';
#tab-bar{
/* 流體布局艾杏,使得這個元素占據(jù)一行 */
display: flex;
height: 49px;
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-color: #f6f6f6;
font-size: 14px;
/*
<length>①: 第 1 個長度值定義元素的陰影水平偏移值。正值盅藻,陰影出現(xiàn)在元素右側(cè);負值畅铭,則陰影出現(xiàn)在元素左側(cè)
<length>②: 第 2 個長度值定義元素的陰影垂直偏移值氏淑。正值,陰影出現(xiàn)在元素底部硕噩;負值假残,則陰影出現(xiàn)在元素頂部
<length>③: 第 3 個長度值定義元素的陰影模糊值半徑(如果提供了)。該值越大陰影邊緣越模糊炉擅,若該值為0辉懒,陰影邊緣不出現(xiàn)模糊。不允許負值 <length>④: 第 4 個長度值定義元素的陰影外延值(如果提供了)谍失。正值眶俩,陰影將向四面擴展痴昧;負值裹匙,則陰影向里收縮
<color>: 定義元素陰影的顏色咪橙。如果該值未定義篮赢,陰影顏色將默認取當前最近的文本顏色 inset: 定義元素的陰影類型為內(nèi)陰影否灾。該值為空時昌犹,則元素的陰影類型為外陰影
*/
box-shadow: 0 -3px 1px rgba(100,100,100,.08);
}
.tab-bar-item{
/* 使得這些元素均等分布在流體元素中 */
flex: 1;
text-align: center;
}
.tab-bar-item img{
width: 24px;
height: 24px;
/* 使得圖片下面不要離文字太遠 */
/* middle: 把當前盒的垂直中心和父級盒的基線加上父級的半x-height對齊 */
vertical-align: middle;
}
</style>
第二步盏档、把tab-bar抽成一個獨立的組件
TabBar組件
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
<script>
export default {
name:"TabBar"
}
</script>
<style scoped>
#tab-bar{
display: flex;
height: 49px;
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-color: #f6f6f6;
font-size: 14px;
box-shadow: 0 -3px 1px rgba(100,100,100,.08);
}
</style>
第三步般哼、將TabBar中的每個條目抽成一個獨立的組件tab-bar-item
tab-bar-item組件
<template>
<div class="tab-bar-item">
<div v-if="isActive"><slot name="item-icon-active"></slot></div>
<div v-else><slot name="item-icon"></slot></div>
<div class="item-text">
<slot name="item-text"></slot>
</div>
</div>
</template>
<script>
export default {
name:"TabBarItem",
data(){
return {
isActive:false
}
}
}
</script>
<style scoped>
.tab-bar-item{
flex: 1;
text-align: center;
}
.tab-bar-item img{
width: 24px;
height: 24px;
vertical-align: middle;
}
</style>
第四步窃判、在進行完上面兩步后钞楼,現(xiàn)在的App.vue長這樣
<template>
<div id="app">
<tab-bar>
<tab-bar-item>
<img src="./assets/img/tabbar/home.svg" alt="..." slot="item-icon">
<img src="./assets/img/tabbar/home_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">首頁</div>
</tab-bar-item>
<tab-bar-item>
<img src="./assets/img/tabbar/category.svg" alt="..." slot="item-icon">
<img src="./assets/img/tabbar/category_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">分類</div>
</tab-bar-item>
<tab-bar-item>
<img src="./assets/img/tabbar/shopcart.svg" alt="..." slot="item-icon">
<img src="./assets/img/tabbar/shopcart_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">購物車</div>
</tab-bar-item>
<tab-bar-item>
<img src="./assets/img/tabbar/profile.svg" alt="..." slot="item-icon">
<img src="./assets/img/tabbar/profile_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</div>
</template>
<script>
import TabBar from './components/tabbar/TabBar'
import TabBarItem from './components/tabbar/TabBarItem'
export default {
name: 'App',
components:{
TabBar,
TabBarItem
}
}
</script>
<style>
/* 在style中引用文件這樣子使用@import + url */
@import './assets/css/base.css';
</style>
第五步、配置路由
import Vue from 'vue'
import Router from 'vue-router'
//使用懶加載來導入組件
const Home = () => import('../components/Home')
const Category = () => import('../components/Category')
const Profile = () => import('../components/Profile')
const ShopCart = () => import('../components/ShopCart')
//1.注入插件
Vue.use(Router)
//2.創(chuàng)建路由配置對象
const routes = [
{
path:'',
//默認顯示首頁袄琳,重定向
redirect:'/home'
},
{
path:'/home',
component:Home
},
{
path:'/category',
component:Category
},
{
path:'/shopCart',
component:ShopCart
},
{
path:'/profile',
component:Profile
}
]
export default new Router({
routes,
//使用H5的history模式改變url
mode:'history'
})
第六步询件、通過代碼跳轉(zhuǎn)路由燃乍,設(shè)置活躍時候的字體顏色可由外界傳入
<template>
<div class="tab-bar-item" @click="itemClick">
<div v-if="isActive"><slot name="item-icon-active"></slot></div>
<div v-else><slot name="item-icon"></slot></div>
<div class="item-text" :style="finalColor">
<slot name="item-text"></slot>
</div>
</div>
</template>
<script>
export default {
name:"TabBarItem",
data(){
return {
}
},
props:{
path:{
type:String,
require:true
},
color:{
type:String,
default:"red"
}
}
,
computed:{
isActive(){
return this.$route.path.indexOf(this.path) !== -1;
},
finalColor(){
return this.isActive?{color:this.color}:{};
}
},
methods:{
itemClick(){
// 判斷是否正處于活躍狀態(tài),若是的話不進行跳轉(zhuǎn)
this.$route.path.indexOf(this.path) !== -1?void(0):this.$router.replace(this.path);
}
}
}
</script>
<style scoped>
.tab-bar-item{
flex: 1;
text-align: center;
}
.tab-bar-item img{
width: 24px;
height: 24px;
vertical-align: middle;
}
</style>
第七步雳殊、將最終的TabBar抽成組件橘沥,使得App中的代碼減少
<template>
<div>
<tab-bar>
<tab-bar-item path='/home' color="deepPink">
<img src="@/assets/img/tabbar/home.svg" alt="..." slot="item-icon">
<img src="@/assets/img/tabbar/home_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">首頁</div>
</tab-bar-item>
<tab-bar-item path='/category' color="deepPink">
<img src="@/assets/img/tabbar/category.svg" alt="..." slot="item-icon">
<img src="@/assets/img/tabbar/category_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">分類</div>
</tab-bar-item>
<tab-bar-item path='/shopCart' color="deepPink">
<img src="@/assets/img/tabbar/shopcart.svg" alt="..." slot="item-icon">
<img src="@/assets/img/tabbar/shopcart_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">購物車</div>
</tab-bar-item >
<tab-bar-item path='/profile' color="deepPink">
<img src="@/assets/img/tabbar/profile.svg" alt="..." slot="item-icon">
<img src="@/assets/img/tabbar/profile_active.svg" alt="..." slot="item-icon-active">
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</div>
</template>
<script>
import TabBar from './TabBar'
import TabBarItem from './TabBarItem'
export default {
name:"FinalTabBar",
components:{
TabBar,
TabBarItem
}
}
</script>
<style scoped>
</style>
到了這里,基本的功能差不多實現(xiàn)了夯秃,不過座咆,我注意到一點,就是頻繁的復(fù)制粘貼代碼片段的時候仓洼,其中的一些涉及到路徑的東西很容易出問題介陶,因為寫的是相對路徑,所以為了使代碼更加強壯色建,可移植性更強哺呜,我們應(yīng)該把路徑從src開始寫起,但是一個個都這樣的話代碼量太大了箕戳,而且沒什么意義某残,所以我們可以給路徑改名
第八步、路徑改別名
在使用Vue/CLI2.xc創(chuàng)建的項目中陵吸,可以打開build/webpack.base.conf.js文件玻墅,找到這里進行路徑改別名
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
}
},
現(xiàn)在@已經(jīng)映射了src了,我們可以繼續(xù)添加一些別名
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
'assets':resolve('src/assets'),
'components':resolve('src/components'),
'views':resolve('src/components/views')
}
},
注意:使用別名的時候有兩種情況
-
在import或者require 中使用別名
這時候直接寫別名就可以了
-
在其它情況下使用別名
這時候在別名前面要加一個"~"
使用別名后
<template> <div> <tab-bar> <tab-bar-item path='/home' color="deepPink"> <img src="~assets/img/tabbar/home.svg" alt="..." slot="item-icon"> <img src="~assets/img/tabbar/home_active.svg" alt="..." slot="item-icon-active"> <div slot="item-text">首頁</div> </tab-bar-item> <tab-bar-item path='/category' color="deepPink"> <img src="~assets/img/tabbar/category.svg" alt="..." slot="item-icon"> <img src="~assets/img/tabbar/category_active.svg" alt="..." slot="item-icon-active"> <div slot="item-text">分類</div> </tab-bar-item> <tab-bar-item path='/shopCart' color="deepPink"> <img src="~assets/img/tabbar/shopcart.svg" alt="..." slot="item-icon"> <img src="~assets/img/tabbar/shopcart_active.svg" alt="..." slot="item-icon-active"> <div slot="item-text">購物車</div> </tab-bar-item > <tab-bar-item path='/profile' color="deepPink"> <img src="~assets/img/tabbar/profile.svg" alt="..." slot="item-icon"> <img src="~assets/img/tabbar/profile_active.svg" alt="..." slot="item-icon-active"> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </div> </template> <script> import TabBar from 'components/tabbar/TabBar' import TabBarItem from 'components/tabbar/TabBarItem' export default { name:"FinalTabBar", components:{ TabBar, TabBarItem } } </script> <style scoped> </style>
對配置文件進行修改之后一定要重新跑一下項目才會生效