ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 移动端底部菜单栏 :-: ![](https://img.kancloud.cn/05/69/056953bb33c9d7ec0d548b472d5f0144_378x669.png) ## 传统结构和样式 ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>05底部菜单栏</title> <link rel="stylesheet" href="//at.alicdn.com/t/font_1226299_mntzsrlgg2e.css"> <style> * {margin: 0;padding: 0;list-style: none;border: none;} body {background: #ccc;} .footer-tabbar {position: absolute;left: 0;bottom: 0;width: 100%;height: 44px;background: #fff;font-size: 14px;} .footer-tabbar ul{ height: 100%; display: flex; justify-content: center; align-items: center;} .footer-tabbar ul li{width: 20%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center;text-align: center;} .footer-tabbar ul li a{color: #333; text-decoration: none;} .footer-tabbar .iconfont{ font-size:18px; vertical-align: middle;} </style> </head> <body> <div id="app"> <footer class="footer-tabbar"> <ul> <li><a href="#"><i class="iconfont icon-shouye1"></i><p>首页</p></a></li> <li><a href="#"><i class="iconfont icon-huanyuan"></i><p>专题</p></a></a></li> <li><a href="#"><i class="iconfont icon-category"></i><p>分类</p></a></a></li> <li><a href="#"><i class="iconfont icon-gouwuche"></i><p>购物车</p></a></a></li> <li><a href="#"><i class="iconfont icon-wode"></i><p>我的</p></a></a></li> </ul> </footer> </div> </body> </html> ``` **效果** :-: ![](https://img.kancloud.cn/e3/16/e3168d3ab2310b77a05b0f5136c03a90_378x668.png)\*\*\*\* ## 拆分成组件 > 底栏实现,会将它分成一个整体做成组件,里面的每一项又如何管理?我们肯定将里面的每一项做成一个组件。 ## 无插槽写法 ``` <div id="app"> <tab-bar></tab-bar> </div> <script src="js/vue.js"></script> <script> Vue.component('tab-bar-item', { template: ` <li><a href="#"><i class="iconfont icon-shouye1"></i><p>首页</p></a></li> ` }) Vue.component('tab-bar', { template: `<footer class="footer-tabbar"> <ul> <tab-bar-item></tab-bar-item> </ul> </footer>` }) var vm = new Vue({ el: '#app', data: {} }) </script> ``` >[success] 我们可以发现,`tab-bar-item`组件里面的数据是死的。是不好的,可以让父组件通过属性传递来实现。 > 而且底栏的效果,可以将它们放在一个数组中存放。放在实例的data中。 ### 数据 ``` tabbar: [ {"id": 1, "icon": "icon-shouye1", "name": "首页", "url": "/"}, {"id": 2,"icon": "icon-huanyuan","name": "专题","url": "/topic"}, {"id": 3,"icon": "icon-category","name": "分类","url": "/category"}, {"id": 4,"icon": "icon-gouwuche","name": "购物车","url": "/cart"}, {"id": 5,"icon": "icon-wode","name": "我的","url": "/user"} ] ``` ``` <div id="app"> <tab-bar :tabbar="tabbar"></tab-bar> </div> <script src="js/vue.js"></script> <script> Vue.component('tab-bar-item', { props:['item'], template: ` <li> <a :href="item.url"> <i class="iconfont" :class="item.icon"></i> <p>{{item.name}}</p> </a> </li> ` }) Vue.component('tab-bar', { props:['tabbar'], template: ` <footer class="footer-tabbar"> <ul> <tab-bar-item v-for="(item,index) in tabbar" :item="item"></tab-bar-item> </ul> </footer>` }) var vm = new Vue({ el: '#app', data: { tabbar: [ {"id": 1, "icon": "icon-shouye1", "name": "首页", "url": "/"}, {"id": 2,"icon": "icon-huanyuan","name": "专题","url": "/topic"}, {"id": 3,"icon": "icon-category","name": "分类","url": "/category"}, {"id": 4,"icon": "icon-gouwuche","name": "购物车","url": "/cart"}, {"id": 5,"icon": "icon-wode","name": "我的","url": "/user"} ] } }) </script> ``` >[warning] 上面的组件看似没有问题,但是再回过头仔细查看,实例组件的数据,往`tab-bar-item`组件传递。要先传到`tab-bar` 才能传递下去。我们也可以看看有插槽的写法(编译作用域) ## 有插槽写法 > 在`tab-bar`组件上添加插槽。将 `tab-bar-item` 组件作为`tab-bar` 组件的内容传递到定义的插槽中。 ``` <div id="app"> <tab-bar> <tab-bar-item v-for="(item,index) in tabbar" :item="item" :key="item.id"></tab-bar-item> </tab-bar> </div> <script src="js/vue.js"></script> <script> Vue.component('tab-bar-item', { props: ['item'], template: ` <li> <a :href="item.url"> <i class="iconfont" :class="item.icon"></i> <p>{{item.name}}</p> </a> </li> ` }) Vue.component('tab-bar', { template: `<footer class="footer-tabbar"> <ul> <slot></slot> </ul> </footer>` }) var vm = new Vue({ el: '#app', data: { tabbar: [ {"id": 1, "icon": "icon-shouye1", "name": "首页", "url": "/"}, {"id": 2, "icon": "icon-huanyuan", "name": "专题", "url": "/topic"}, {"id": 3, "icon": "icon-category", "name": "分类", "url": "/category"}, {"id": 4, "icon": "icon-gouwuche", "name": "购物车", "url": "/cart"}, {"id": 5, "icon": "icon-wode", "name": "我的", "url": "/user"} ] } }) </script> ``` >[success] 这样写的好处,利用编译作用域,将数据直接传递给了 `tab-bar-item` 组件,而不再经历 `tab-bar` 作中转了。 >[danger] 总结: > 很多同学在初学组件时,会经历的阶段是:认为这种定义组件形式是最好的!要摒弃掉这个想法。 > 不同的组件用法只有放在不同的场景下它才更能发挥出它的作用。我们也可以看一面的一个案例无疑焦点图。