去哪儿-04-iconsDev

目标: 首页图标区域的布局与逻辑实现

创建index-icons分支

码云上创建一个名为index-icons的分支,然后在项目目录下git pull将在线的分支拉到本地,git checkout index-icons 转到当前分支进行开发。

准备阶段

  1. 在components目录下创建Icons.vue组件
    1. 基本框架: template、script、style
    2. 设置导出的接口对象exports default {name: 'HomeIcons'}
  2. Home.vue组件中引用子组件
    1. import
    2. components对象中添加HomeIcons
    3. 使用子组件<home-icons></home-icons>

Icons.vue组件开发

  1. 最外层设置的div用于占位,设置该区域的宽高比,大概是2:1。(因为是一个div,所以可以省略width: 100%)

    <style lang="stylus" scoped>
        .icons
             overflow: hidden
             height: 0
             padding-bottom: 50%
    
    </style>
    
  2. 小图标的布局呈现

    1. 布局
    <div class="icon">
        
    </div>
    
    1. 样式
    .icon
         float: left
         width: 25% 这里是父元素宽的25%,
         padding-bottom: 25%  
         注意: 高度设置的时候不能使用height: 50%, 因为父盒子的高度是0, 但是这里为什么是25%? 
         首先: 在css里面,padding-top,padding-bottom,margin-top,margin-bottom取值为百分比的时候,参照的是父元素的宽度。
         第一种理解是: 因为icon宽度是父盒子的25%, 而它撑开的那个高度也应该是跟这个宽度一样大,同样是占父元素宽度的25%,这个padding-bottom的百分比的设置是基于父元素的宽。
         第二种理解: 父元素的那个50%就可以看成那个撑开的高度, 而他本身的高度应该是父元素的高度的一半,所以是50%的一半。
    
    1. 呈现一个icon中的图标与文字
     <div class="icon">
         <img src="图片地址" />
         <p>表述内容</p>
     </div>
    

    此时会发现图标比盒子大,明显撑开,解决方法:

     <div class="icon">
         <div class="icon-img">
             <img src="图片地址" />
         </div>    
         <p>表述内容</p>
     </div>
    
    .icon
         overflow: hidden 
         float: left
         width: 25% 
         padding-bottom: 25%
         position: relative
         .icon-img
             position: absolute  不要忘记子绝父相
             top: 0
             left: 0
             right: 0   // 这里上左右都设置为0是为了保证装图片的这个盒子始终与父盒子一样宽,这里我们不知道具体的高度, 这里是要定位一个放置图标的盒子, 此时图标的大小还是原来的大小。 
             bottom: .44rem   // 这里是为了预留出需要写文字的部分  
    

    此时发现:图标太大,而且高度不是50%,解决方法: 先给img添加一个icon-img-content的类名,

     .icon-img
         position: absolute  
         top: 0
         left: 0
         right: 0 
         bottom: .44rem 
         .icon-img-content
             height: 100% 
    

    解决高度超出50%的问题:.icon添加一个height: 0的样式
    实现图标的水平居中显示:

    .icon-img
        position: absolute  
        top: 0
        left: 0
        right: 0  
        bottom: .44rem
        box-sizing: border-box  // IE盒子模型  2种盒模型:https://blog.csdn.net/zwkkkk1/article/details/79678177  box-sizing的默认属性是content-box
        padding: .1rem 
        .icon-img-content
            display: block  //默认情况下,block元素宽度自动填满其父元素宽度
            margin: 0 auto
            height: 100% 
    

    设置文字样式:

    .icon-desc
        position: absolute  
        left: 0
        right: 0 
        bottom: 0
        height: .44rem
        line-height: .44rem
        text-align: center
        color: $darkTextColor 这里使用的是网站主题文字颜色变量,该变量的自定义方法与$bgColor一样。
    
    1. 手动呈现8个图标
  3. 图标区域的逻辑实现:

    1. 需求说明: 首页的一个页面上呈现的是8个图标,刚有9个图标的时候,希望能够实现在两页上的轮播呈现。 ---- 借用swiper
    <swiper>
        <swiper-slide>
            <div class="icon">
                <div class="icon-img">
                    <img class="icon-img-content" src="图片网址" />
                </div>
                <p class="icon-desc"></p>
            </div>
        </swiper-slide>
        <swiper-slide>
            <div class="icon">
                <div class="icon-img">
                    <img class="icon-img-content" src="图片网址" />
                </div>
                <p class="icon-desc"></p>
            </div>
        </swiper-slide>
    </swiper>
    

    一个小问题: 只有在上部拖动的时候才会出现轮播的效果,下面那一部分无效,原因是:swiper-container的高度只有图标的高度,但是icons的高度很高,所以内容上并没有跟它有相同的高度。解决方法:
    将.icons下面的样式全部往前提一个tab, 然后重写.icons的样式:

    .icons >>> .swiper-container
         <!--overflow: hidden 这个样式可以去掉, 因为.swiper-container自带了overflow: hidden-->
         height: 0
         padding-bottom: 50%
    
    1. 设置data函数的返回数据对象,实现图标的循环呈现
    <script>
        export default {
            data () {
                return {
                    iconList: [{
                        id: '0001',
                        imgUrl: '图片地址',
                        desc: '图标描述'
                    },{
                        id: '0002',
                        imgUrl: '图片地址',
                        desc: '图标描述'
                    },{
                        id: '0003',
                        imgUrl: '图片地址',
                        desc: '图标描述'
                    },{
                        id: '0004',
                        imgUrl: '图片地址',
                        desc: '图标描述'
                    }]
                }
            }
        }
    </script>
    

    要写9个图标的信息数据,这里的数据代码是很冗余的,以后会用ajax获取到的数据。此时,就可以使用循环的形式来写:

    <swiper>
        <swiper-slide>
            <div class="icon"
                    v-for="item of iconList"
                    :key="item.id"
            >
                <div class="icon-img">
                    <img class="icon-img-content" src="item.imgUrl" />
                </div>
                <p class="icon-desc">{{item.desc}}</p>
            </div>
        </swiper-slide>
    </swiper>
    

    但是,以上的写法会将第9个图标隐藏,无法实现轮播显示—使用计算属性来实现。在data的后面定义一个计算属性(自带缓存机制,且语法简单):

     <script>
         export default {
             data () {
                 return {
                     iconList: [......]
                 }
             },
             computed: {
                 pages () {
                     const pages = []
                     this.iconList.forEach((item, index) => {
                         const page = Math.floor(index / 8)
                         if (!pages[page]) {
                             pages[page] = []
                         }
                         pages[page].push(item)
                     })
                     return pages
                 }
             }
         }
     </script>
    

    循环代码的修改:

    <swiper>
        <swiper-slide v-for="(page, index) of pages" :key="index">
            <div class="icon"
                    v-for="item of page"
                    :key="item.id"
            >
                <div class="icon-img">
                    <img class="icon-img-content" src="item.imgUrl" />
                </div>
                <p class="icon-desc">{{item.desc}}</p>
            </div>
        </swiper-slide>
    </swiper>
    

    一点优化: 当图标下方的文字描述部分比较多的时候,多出的部分呈现三个点的形式,使用css样式来实现。在.icon-desc下添加

    overflow: hidden
    whit-space: nowrap
    text-overflow: ellipsis
    

    会发现,可能很多地方都能用到这个3个css样式,所以可以借助stylus提供的Mixins将它封装起来—封装方法:在styles目录下创建mixins.styl文件,在该文件中定义一个ellipsis方法,注意与小括号中间不要有空格:

    ellipsis()
        overflow: hidden
        whit-space: nowrap
        text-overflow: ellipsis
    

    使用的时候,先在style标签下@import '~styles/mixins.styl',然后在.icon-desc中直接使用:ellipsis()

代码提交

lipsis方法,注意与小括号中间不要有空格:
css ellipsis() overflow: hidden whit-space: nowrap text-overflow: ellipsis
使用的时候,先在style标签下@import '~styles/mixins.styl',然后在.icon-desc中直接使用:ellipsis()

代码提交

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值