(超级详细)Vue项目实战App2 - - -主页

一、Home

1.安装stylus

cd Travel
#  进入项目目录文件
npm install stylus --save
#  安装stylus
npm install stylus-loader --save
#  安装stylus的依赖包
npm run dev
#  运行项目

2. 组件化开发

在这里插入图片描述
该页面可分为’Header’、‘Swiper’、‘Icons’、‘Recommend’、'Weekend’五个组件组成



3、定义全局变量、方法、目录别名

a.创建’varibles.styl’文件 (路径: src/assets/styles/varibles.styl)

// 主题色
$bgColor = #00bcd4
// 正文字体
$darkTextColor = #333
// header高度
$headerHight = .86rem

b.创建’mixins.styl’文件 (路径: src/assets/styles/mixins.styl)

// 实现文字溢出的方法
ellipsis()
  overflow hidden
  white-space nowrap
  text-overflow ellipsis


二、iconfont

1.创建’Iconfont’文件夹(路径: src/assets/styles/iconfont)

2. 下载iconfont文件,将图标’下载至本地’

3. 迁移文件至iconfont文件夹

在这里插入图片描述

4. 编辑’iconfont.css’文件(路径: src/assets/styles/iconfont.css)

@font-face {font-family: "iconfont";
  /* 字体文件不在当前目录下,所以需要修改路径 */
  src: url('./iconfont/iconfont.eot?t=1610348313991'); /* IE9 */
  src: url('./iconfont/iconfont.eot?t=1610348313991#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAQYAAsAAAAACHgAAAPKAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDSAqDaIM/ATYCJAMYCw4ABCAFhG0HWRt2B8gOJS3BwABgAABgBF/7ofvu7l8QHJLKxLMKq6joKAKVlEC1rk7WiNpqNiL/12Z+ZqqEqrNm0VPFhKRihAwJMfKGIVJRY2six+ZWUT3v/xwzXYrnX6VLNVUW7Y3G4wENLOOiPIruHeAdyPGB6KmA59KB7KDfNxNoN6oct91n0CiopfBWBeJMC8pQq6ZXRkpDq1B7DhbxFRqt6TO6C+BL+vPxH9xRi6TJvI1Hp70D0O2X++NpPKtqlpMYAdLtrFCOkbEMFOKx1/4A5/FlWLv1F6rZATq1Ssov94fxH+0fe348XVVFTeG5Q6cfJ0uP9Y/XEBUVd4I9JBp+uUMmmV/jmSR+25kEv3syKfw+3aYBdcPmdnwAfhB22Z4FUaVeQRgWvlbtF6buvQrp1ZX8uvuutcTW9aLYg1GN73nhvq/ZQ8m/ZM+mWZv32pYenn1o6ob8yfsOzGoizZ7NrV/fpMn6/c181mzlwQPvw4e++/ele/cyUVUI5ShcRt5g7d/bRFq/ac++pqkuAdLVGxmv33GvXOrmvXCPX6CRWBoJn9nT8PAJT6sHrTwnpB0e/gHv2VF362Wu6/yBjtAKrttZrseKgWWT1nPLhwmlp5udLhUapgpS4FrB350vkfNZwY+fPwH03+bmnrmz+eefX4Xw2HYEf/yIj+IjseqILCpFECLzaNdV+MYNHClXyiKIRSGUq1C/rP2WsqE3Mt2GJFGYFco29R6a/fQJ7l03UaWFTJwz9u2eg7/3Hyke3rLcRFYlMv1KyzI7jeHSaS7iHZtOjUFjUSpVMCaVhmnoWfINOgzIE6gBwPP1bOJuAKQ3aCMgH6Ib//zv+Park2dSvU7/a9kK+JnbvEXqf75eYFmiVYIt/Z+lzL5iyz1DLWbv8FIC1TwMEtr9If5dd78XW+mG2MWEVkMlJC1GIGs1jSzYZWh0WIWq1Rq0W9L3eIcBFBalDYvmCxB6HYek23fIemWRBfscGsO+Q9UbGNodR6MLdpgNje9JicxIQPRnRE3R42pgYnxWOoIEzahMq/IU5yXU0EKiy+5spvqSOKFbbDGSQTdjqqhSPSb2EW5HolFdTFA9TBRmDzGW6OBwqH2PZFf0GPC2UISMIQJEfhkijUIXp8ajGb71/SMQQaYoGR3paQl6EZRBm1zkYudkIPtq4qyeV5luSApyYxhVXKaidDGiPrASUT+uEyX654URCsYutCCa0IGDBqlcjf14XexbHoN23ofVSJGjRBM1WrReaUqFqkWj1dOaHJVrGLppmDovU6qnKqJEZTUMIlMlBAAAAA==') format('woff2'),
  url('./iconfont/iconfont.woff?t=1610348313991') format('woff'),
  url('./iconfont/iconfont.ttf?t=1610348313991') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
  url('./iconfont/iconfont.svg?t=1610348313991#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


5. 引用’Iconfont’,编辑’main.js’

// 引用iconfont
import 'styles/iconfont.css'


三、Header

1. 新建’components’、'home’文件夹(路径: src/pages/home/components/Header.vue)

2.创建’Header.vue’文件

<template>
  <div class="header">
    Home
  </div>
</template>

<script>
export default {
  name: 'Header'
}
</script>


3. 编辑’Home.vue’文件 - - - 引用’Header.vue’组件

<template>
  <div>
    <home-header></home-header>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
export default {
  name: 'Home',
  components: {
    HomeHeader
  }
}
</script>

<style>
</style>


4. 编写’Header.vue’样式

<template>
  <div class="header">
    <div class="header-left">返回</div>
    <div class="header-input">输入城市、景点、游玩主题...</div>
    <div class="header-right">城市</div>
  </div>
</template>

<script>
export default {
  name: 'HomeHeader'
}
</script>
<style lang='stylus' scoped>
// 引用'varibles.styl'变量样式
@import '~styles/varibles.styl'
  .header
    display flex
    // width 100%
    // height $headerHight
    background-color $bgColor
    color #fff
    text-align center
    line-height $headerHight
    .header-left
      float left
      width .64rem
    .header-input
      flex 1
      margin-left .2rem
      margin-top .12rem
      padding-left .2rem
      height .64rem
      text-align left 
      line-height .64rem
      color #ccc
      border-radius .1rem
      background #fff
    .header-right
      float right
      width 1.24rem
      padding 0 .1rem
</style>

5. 添加iconfont

<template>
  <div class="header">
    <div class="header-left">
      <span class="iconfont back-icon">&#xe743;</span>
    </div>
    <div class="header-input">
      <span class='iconfont'>&#xe632;</span>
      输入城市、景点、游玩主题...
    </div>
    <div class="header-right">
      城市
      <span class="iconfont arrow-icon">&#xe65c;</span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HomeHeader'
}
</script>
<style lang='stylus' scoped>
// 引用'varibles.styl'变量样式
@import '~styles/varibles.styl'
  .header
    display flex
    // width 100%
    height $headerHight
    background-color $bgColor
    color #fff
    text-align center
    line-height $headerHight
    .header-left
      float left
      width .64rem
      .back-icon
        font-size .6rem
    .header-input
      flex 1
      margin-left .2rem
      margin-top .12rem
      padding-left .2rem
      height .64rem
      text-align left 
      line-height .64rem
      color #ccc
      border-radius .1rem
      background #fff
    .header-right
      float right
      width 1.24rem
      padding 0 .1rem
      .arrow-icon
        margin-left -.1rem
        font-size .4rem
</style>



四、Swiper

1. 创建’Swiper.vue’文件

<template>
  <div class="Swiper">
    Swiper
  </div>
</template>

<script>
export default {
  name: 'HomeSwiper'
}
</script>

<style scoped>
</style>

2. 引用’Swiper.vue’组件 - - - 编辑’Home.vue’文件

<template>
  <div>
    <home-header></home-header>
    <home-swiper></home-swiper>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
export default {
  name: 'Home',
  components: {
    HomeHeader,
    HomeSwiper
  }
}
</script>

<style>
</style>


3. 安装轮播图插件

插件GitHub地址

// 当前项目目录安装
npm install vue-awesome-swiper@2.6.7 --save
#  安装的2.6.7版本

4. 导入轮播图插件 - - - 编辑’main.js’(路径: src/main.js)

// 引用轮播图插件
import VueAwesomeSwiper from 'vue-awesome-swiper'
// 引用轮播图插件的css样式
import 'swiper/dist/css/swiper.css'

// 用轮播图插件
Vue.use(VueAwesomeSwiper)

5. 编写’Swiper.vue’样式

<template>
    <swiper :options="swiperOption">
    <!-- slides -->
    <swiper-slide>I'm Slide 1</swiper-slide>
    <swiper-slide>I'm Slide 2</swiper-slide>
    <swiper-slide>I'm Slide 3</swiper-slide>
    <!-- Optional controls -->
    <div class="swiper-pagination"  slot="pagination"></div>
    <div class="swiper-button-prev" slot="button-prev"></div>
    <div class="swiper-button-next" slot="button-next"></div>
    <div class="swiper-scrollbar"   slot="scrollbar"></div>
  </swiper>
</template>

<script>
export default {
  name: 'HomeSwiper',
  data() {
    return {
      swiperOption: {}
    }
  }
}
</script>

<style lang="stylus" scoped>
</style>


6. 完善’Swiper.vue’样式 - - - 图片防抖

<template>
  <div class="wrapper">
    <swiper :options="swiperOption">
      <swiper-slide>
        <img class='swiper-img' src="http://img1.qunarzz.com/piao/fusion/1801/1a/94428c6dea109402.jpg_640x200_2cf590d8.jpg" alt="">
      </swiper-slide>
      <swiper-slide>
        <img class='swiper-img' src="http://img1.qunarzz.com/piao/fusion/1802/42/7c92b9a381e46402.jpg_640x200_1cdce2a4.jpg" alt="">
      </swiper-slide>
      <!-- 分页 -->
      <div class="swiper-pagination"  slot="pagination"></div>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeSwiper',
  data () {
    return {
      swiperOption: {}
    }
  }
}
</script>

<style lang="stylus" scoped>
  .wrapper
    height 0
    padding-bottom 31.25%
    overflow hidden
    background #fff
    .swiper-img
      width 100%
</style>


7. 完善’Swiper.vue’样式 - - - 分页样式

<template>
  <div class="wrapper">
    <swiper :options="swiperOption">
      <swiper-slide>
        <img class='swiper-img' src="http://img1.qunarzz.com/piao/fusion/1801/1a/94428c6dea109402.jpg_640x200_2cf590d8.jpg" alt="">
      </swiper-slide>
      <swiper-slide>
        <img class='swiper-img' src="http://img1.qunarzz.com/piao/fusion/1802/42/7c92b9a381e46402.jpg_640x200_1cdce2a4.jpg" alt="">
      </swiper-slide>
      <!-- 分页 -->
      <div class="swiper-pagination"  slot="pagination"></div>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeSwiper',
  data () {
    return {
      swiperOption: {
        // 填入一个配置项
        pagination: '.swiper-pagination'
      }
    }
  }
}
</script>

<style lang="stylus" scoped>
  // 通过鼠标右键审查元素定位要'class',从而修改样式(stylus的样式穿透)
  .wrapper >>> .swiper-pagination-bullet-active
    background #fff
    // background #fff !important
  .wrapper
    height 0
    padding-bottom 31.25%
    overflow hidden
    background #fff
    .swiper-img
      width 100%
</style>


8. 完善’Swiper.vue’样式 - - - banner图循环输出

<template>
  <div class="wrapper">
    <swiper :options="swiperOption">
      <swiper-slide v-for="item of swiperList" :key="item.id">
        <img class='swiper-img' :src="item.imgUrl" alt="">
      </swiper-slide>
      <!-- 分页 -->
      <div class="swiper-pagination"  slot="pagination"></div>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeSwiper',
  data () {
    return {
      swiperOption: {
        // 填入一个配置项
        pagination: '.swiper-pagination',
        // 循环轮播
        loop: true
      },
      swiperList: [{
        id: '001',
        imgUrl: 'http://img1.qunarzz.com/piao/fusion/1801/1a/94428c6dea109402.jpg_640x200_2cf590d8.jpg'
      },
      {
        id: '002',
        imgUrl: 'http://img1.qunarzz.com/piao/fusion/1802/42/7c92b9a381e46402.jpg_640x200_1cdce2a4.jpg'
      }]
    }
  }
}
</script>

<style lang="stylus" scoped>
  // 通过鼠标右键审查元素定位要'class',从而修改样式(stylus的样式穿透)
  .wrapper >>> .swiper-pagination-bullet-active
    background #fff
    // background #fff !important
  .wrapper
    height 0
    padding-bottom 31.25%
    overflow hidden
    background #fff
    .swiper-img
      width 100%
</style>



五、Icons

1. 创建’Icons.vue’文件

<template>
  <div>Icon</div>
</template>

<script>
export default {
  name: 'HomeIcon'
}
</script>

<style lang="stylus" scoped>
</style>


2. 引用’Icons.vue’组件 - - - 编辑’Home.vue’文件

<template>
  <div>
    <home-header></home-header>
    <home-swiper></home-swiper>
    <home-icon></home-icon>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
import HomeIcon from './components/Icon'
export default {
  name: 'Home',
  components: {
    HomeHeader,
    HomeSwiper,
    HomeIcon
  }
}
</script>

<style>
</style>



3. 编辑’Icons.vue’文件 - - - 实现基本布局

<template>
  <div class="icons">
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
    <div class="icon">
      <div class="icon-img">
        <img class="icon-img-content" src="https://s.qunarzz.com/homenode/images/touchheader/piao.png" alt="">
      </div>
      <p class="icon-desc">特色景点</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HomeIcons'
}
</script>

<style lang="stylus" scoped>
@import '~styles/varibles.styl';
  .icons
    height 0
    padding-bottom 50%
    background #fff
    .icon
      position relative
      float left
      width 25%
      height 0
      padding-bottom 25%
      // background skyblue
      overflow hidden
      .icon-img
        position absolute
        left 0
        top 0
        right 0
        bottom .44rem
        padding .1rem
        box-sizing border-box
        .icon-img-content
          display block
          height 100%
          margin 0 auto
      .icon-desc
        position absolute
        left 0
        right 0
        bottom 0
        height .44rem
        line-height .44rem
        text-align center
        color $darkTextColor
          
</style>

4. 完善’Icons.vue’文件 - - - 双向绑定内容

<template>
  <div class="icons">
    <swiper :options="swiperOption">
      <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" alt="">
          </div>
          <p class="icon-desc">{{item.desc}}</p>
        </div>
      </swiper-slide>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeIcons',
  // data () {
  //   return {
  //     swiperOption: {
  //       autoplay: false
  //     }
  //   }
  // },
  data () {
    return {
      iconList: [{
        id: '0001',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/piao.png',
        desc: '景点门票'
      },
      {
        id: '0002',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/package.png',
        desc: '度假'
      },
      {
        id: '0003',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/train.png',
        desc: '火车票'
      },
      {
        id: '0004',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/flight.png',
        desc: '机票'
      },
      {
        id: '0005',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/hotel.png',
        desc: '酒店'
      },
      {
        id: '0006',
        imgUrl: 'https://picbed.qunarzz.com/f5e5770393d759578962e53ee67798c8.png',
        desc: '海外酒店'
      },
      {
        id: '0007',
        imgUrl: 'https://picbed.qunarzz.com/a36d2288f19e54562338f4d8ef986288.png',
        desc: '特价机票'
      },
      {
        id: '0008',
        imgUrl: 'https://picbed.qunarzz.com/1316dc82d1ce6259686d5a68880e5a9d.png',
        desc: '攻略'
      },
      {
        id: '0009',
        imgUrl: 'https://picbed.qunarzz.com/ae617a31e0bd5803d76918b817f6d942.png',
        desc: '自由行'
      },
      {
        id: '0010',
        imgUrl: 'https://picbed.qunarzz.com/377db8cb2143aebf01869c9baad3d325.png',
        desc: '汽车票'
      }]
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/varibles.styl';
  // 右键审查元素定位到'class',从而修改样式
  .icons >>> .swiper-container
    // swiper自带overflow属性
    // overflow hidden
    height 0
    padding-bottom 50%
    // background #f5f5f5
  .icon
    position relative
    float left
    width 25%
    height 0
    padding-bottom 25%
    // background skyblue
    overflow hidden
    .icon-img
      position absolute
      left 0
      top 0
      right 0
      bottom .44rem
      padding .1rem
      box-sizing border-box
      .icon-img-content
        display block
        height 100%
        margin 0 auto
    .icon-desc
      position absolute
      left 0
      right 0
      bottom 0
      height .44rem
      line-height .44rem
      text-align center
      color $darkTextColor
</style>


5. 完善’Icons.vue’文件 - - - 实现分页计算

<template>
  <div class="icons">
    <swiper :options="swiperOption">
      <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" alt="">
          </div>
          <p class="icon-desc">{{item.desc}}</p>
        </div>
      </swiper-slide>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeIcons',
  data () {
    return {
      swiperOption: {
        // 防止轮播自动播放
        autoplay: false
      },
      iconList: [{
        id: '0001',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/piao.png',
        desc: '景点门票'
      },
      {
        id: '0002',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/package.png',
        desc: '度假'
      },
      {
        id: '0003',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/train.png',
        desc: '火车票'
      },
      {
        id: '0004',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/flight.png',
        desc: '机票'
      },
      {
        id: '0005',
        imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/hotel.png',
        desc: '酒店'
      },
      {
        id: '0006',
        imgUrl: 'https://picbed.qunarzz.com/f5e5770393d759578962e53ee67798c8.png',
        desc: '海外酒店'
      },
      {
        id: '0007',
        imgUrl: 'https://picbed.qunarzz.com/a36d2288f19e54562338f4d8ef986288.png',
        desc: '特价机票'
      },
      {
        id: '0008',
        imgUrl: 'https://picbed.qunarzz.com/1316dc82d1ce6259686d5a68880e5a9d.png',
        desc: '攻略'
      },
      {
        id: '0009',
        imgUrl: 'https://picbed.qunarzz.com/ae617a31e0bd5803d76918b817f6d942.png',
        desc: '自由行'
      },
      {
        id: '0010',
        imgUrl: 'https://picbed.qunarzz.com/377db8cb2143aebf01869c9baad3d325.png',
        desc: '汽车票'
      }]
    }
  },
  // 计算
  computed: {
    // 定义一个函数
    pages () {
      // 申明一个空数组,作为传递所有item后总共的页数
      const pages = []
      // 将iconList循环一遍,可以获取到两个数据'循环项'和它对应的'下标'
      this.iconList.forEach((item, index) => {
        // 定义一个'page',计算页数  page = index/8 
        const page = Math.floor(index / 8)
        // page = index / 8 < 1时,pages[0]不变,不执行条件
        // page = index / 8 >= 1时,pages[page]和pages[0]不一致,执行条件
        if(!pages[page]) {
          // 重新创建一个空数组,然后都把新数据添加至空数组当前页
          pages[page] = []
        }
        pages[page].push(item)
      })
      return pages
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/varibles.styl';
@import '~styles/mixins.styl';
  // 右键审查元素定位到'class',从而修改样式
  .icons >>> .swiper-container
    // swiper自带overflow属性
    // overflow hidden
    height 0
    padding-bottom 50%
    // background #f5f5f5
  .icon
    position relative
    float left
    width 25%
    height 0
    padding-bottom 25%
    // background skyblue
    overflow hidden
    .icon-img
      position absolute
      left 0
      top 0
      right 0
      bottom .44rem
      padding .1rem
      box-sizing border-box
      .icon-img-content
        display block
        height 100%
        margin 0 auto
    .icon-desc
      position absolute
      left 0
      right 0
      bottom 0
      height .44rem
      line-height .44rem
      text-align center
      color $darkTextColor
      // 封装的文字溢出效果
      ellipsis()
</style>




六、Recommend

1. 创建’Recommend.vue’文件

<template>
  <div>
    Recommend
  </div>
</template>

<script>
export default {
  name: 'HomeRecommend'
}
</script>

<style lang="stylus" scoped>
</style>

2. 引用’Recommend.vue’组件

编辑’Home.vue’文件

<template>
  <div>
    <home-header></home-header>
    <home-swiper></home-swiper>
    <home-icons></home-icons>
    <home-recommend></home-recommend>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
import HomeIcons from './components/Icons'
import HomeRecommend from './components/Recommend'
export default {
  name: 'Home',
  components: {
    HomeHeader,
    HomeSwiper,
    HomeIcons,
    HomeRecommend
  }
}
</script>

<style>
</style>


3. 编辑’Recommend.vue’ - - - 实现基本布局

<template>
  <div>
    <div class="title">热销推荐</div>
    <div class="item">
      <img class="item-img" src="https://imgs.qunarzz.com/vs_ceph_vs_tts/9608dc40-1209-4b9d-a73f-1030d1f351fe.gif">
      <div class="item-info">
        <p class="item-title">故宫</p>
        <p class="item-desc">东方建筑代表,世界宫殿典范</p>
        <button class="item-button">查看详情</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HomeRecommend'
}
</script>

<style lang="stylus" scoped>
  .title
    margin-top .2rem
    line-height .8rem
    background #eee
    text-indent .2rem
  .item
    overflow hidden
    display flex
    height 1.9rem
    background #f5f5f5
    .item-img
      width 1.7rem
      height 1.7rem
      margin .1rem
    .item-info
      flex 1
      padding .1rem
      // 限定最小宽度,实现文字溢出效果
      min-width 0
      .item-title
        line-height .54rem
        font-size .32rem
        ellipsis()
      .item-desc
        line-height .4rem
        color #ccc
        ellipsis()
      .item-button
        line-height .44rem
        color #fff
        margin-top .2rem
        padding 0 .2rem
        border-radius .6rem
        background #ff9300
</style>

4. 编辑’Recommend.vue’ - - - 双向绑定内容

<template>
  <div>
    <div class="title">热销推荐</div>
    <div class="item" v-for="item of recommendList" :key="item.id">
      <img class="item-img" :src="item.imgUrl">
      <div class="item-info">
        <p class="item-title">{{item.title}}</p>
        <p class="item-desc">{{item.desc}}</p>
        <button class="item-button">查看详情</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HomeRecommend',
  data () {
    return {
      recommendList: [{
        id: '0001',
        imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vs_tts/9608dc40-1209-4b9d-a73f-1030d1f351fe.gif',
        title: '武汉-昆明 9天跟团游',
        desc: '9天深度游云南|昆大丽版纳体验升级:省内1动1飞|吉普跟拍+雨林野象谷+雪山'
      },
      {
        id: '0002',
        imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/8a089740-f383-4210-88cf-6d7c61475304.jpg_r_480x320x95_23b8204f.jpg',
        title: '武汉-恩施 3天跟团游',
        desc: '免票进行时|腾龙洞|夷水丽川|科技激光秀|恩施黄鹤峰林大峡谷|土司城|女儿城'
      },
      {
        id: '0003',
        imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/fda85184-bdbe-45e8-80c7-1c2574922d10.jpg_r_480x320x95_7b5db4d1.jpg',
        title: '武汉-武汉欢乐谷 1天跟团游',
        desc: '旅行者:惠游湖北纯玩无购物(金龙水寨+汤池温泉)含导游门票'
      },
      {
        id: '0004',
        imgUrl: 'https://imgs.qunarzz.com/p/tts9/1711/e5/2033e06bdda7cb02.jpg_r_480x320x95_1c9f89aa.jpg',
        title: '武汉-宜昌 2天跟团游',
        desc: '冬季滑雪♥真纯玩🔥神农架精华二日游📣情人泉+昭君别院✔赠雪鞋+雪板+雪仗'
      }]
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/mixins.styl';
  .title
    margin-top .2rem
    line-height .8rem
    background #eee
    text-indent .2rem
  .item
    overflow hidden
    display flex
    height 1.9rem
    background #f5f5f5
    .item-img
      width 1.7rem
      height 1.7rem
      margin .1rem
    .item-info
      flex 1
      padding .1rem
      // 限定最小宽度,实现文字溢出效果
      min-width 0
      .item-title
        line-height .54rem
        font-size .32rem
        ellipsis()
      .item-desc
        line-height .4rem
        color #ccc
        ellipsis()
      .item-button
        line-height .44rem
        color #fff
        margin-top .2rem
        padding 0 .2rem
        border-radius .6rem
        background #ff9300
</style>



七、Weekend

1.创建’Weekend.vue’文件

<template>
  <div>weekend</div>
</template>

<script>
export default {
  name: 'HomeWeekend'
}
</script>

<style lang="stylus" scoped> 
</style>


2. 引用’Weekend.vue’组件 - - - 编辑’Home.vue’文件

<template>
  <div>
    <home-header></home-header>
    <home-swiper></home-swiper>
    <home-icons></home-icons>
    <home-recommend></home-recommend>
    <home-weekend></home-weekend>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
import HomeIcons from './components/Icons'
import HomeRecommend from './components/Recommend'
import HomeWeekend from './components/Weekend'
export default {
  name: 'Home',
  components: {
    HomeHeader,
    HomeSwiper,
    HomeIcons,
    HomeRecommend,
    HomeWeekend
  }
}
</script>

<style>
</style>


3. 编写’Weekend.vue’样式

<template>
  <div>
    <div class="title">周末去哪儿</div>
    <ul>
      <li class="item" v-for="item of weekendList" :key="item.id">
        <div class="item-img-wrapper">
          <img class="item-img" :src="item.imgUrl">
        </div>
        <div class="item-info">
          <p class="item-title">{{item.title}}</p>
          <p class="item-desc">{{item.desc}}</p>
        </div>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HomeWeekend',
  data () {
    return {
      weekendList: [{
        id: '0001',
        imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vs_tts/9608dc40-1209-4b9d-a73f-1030d1f351fe.gif',
        title: '武汉-昆明 9天跟团游',
        desc: '9天深度游云南|昆大丽版纳体验升级:省内1动1飞|吉普跟拍+雨林野象谷+雪山'
      },
      {
        id: '0002',
        imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/8a089740-f383-4210-88cf-6d7c61475304.jpg_r_480x320x95_23b8204f.jpg',
        title: '武汉-恩施 3天跟团游',
        desc: '免票进行时|腾龙洞|夷水丽川|科技激光秀|恩施黄鹤峰林大峡谷|土司城|女儿城'
      },
      {
        id: '0003',
        imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/fda85184-bdbe-45e8-80c7-1c2574922d10.jpg_r_480x320x95_7b5db4d1.jpg',
        title: '武汉-武汉欢乐谷 1天跟团游',
        desc: '旅行者:惠游湖北纯玩无购物(金龙水寨+汤池温泉)含导游门票'
      },
      {
        id: '0004',
        imgUrl: 'https://imgs.qunarzz.com/p/tts9/1711/e5/2033e06bdda7cb02.jpg_r_480x320x95_1c9f89aa.jpg',
        title: '武汉-宜昌 2天跟团游',
        desc: '冬季滑雪♥真纯玩🔥神农架精华二日游📣情人泉+昭君别院✔赠雪鞋+雪板+雪仗'
      }]
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/mixins.styl';
  .title
    margin-top .2rem
    line-height .8rem
    background #eee
    text-indent .2rem
  .item-img-wrapper
    overflow hidden
    height 0
    padding-bottom 37.09%
    background #f5
    .item-img
      width 100%
  .item-info
    padding .1rem
    .item-title
      line-height .54rem
      font-size .32rem
      ellipsis()
    .item-desc
      line-height .4rem
      color #ccc
      ellipsis()
</style>



八、Ajax

1.安装axios

npm install axios --save

2.引入Ajax数据 - - - 编辑’Home.vue’

<template>
  <div>
    <home-header></home-header>
    <home-swiper></home-swiper>
    <home-icons></home-icons>
    <home-recommend></home-recommend>
    <home-weekend></home-weekend>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
import HomeIcons from './components/Icons'
import HomeRecommend from './components/Recommend'
import HomeWeekend from './components/Weekend'
import axios from 'axios'

export default {
  name: 'Home',
  components: {
    HomeHeader,
    HomeSwiper,
    HomeIcons,
    HomeRecommend,
    HomeWeekend
  },
  methods: {
    // 创建一个函数
    getHomeInfo () {
      // 通过axios进行数据请求
      axios.get('/api/index.json')
      .then(this.getHomeInfoSucc)
    },
    getHomeInfoSucc (res) {
      console.log(res)
    }
  },
  // 创建一个生命周期函数,当页面挂载好了之后,执行这个函数
  mounted () {
    this.getHomeInfo()
  }
}
</script>

<style>
</style>


3.创建本地模拟数据

a. 新建’mock’ 文件夹和 'index.json’文件(路径: src/public/mock/index.json)

{
    "ret": true,
    "data": {
      "city":"北京",
      "swiperList": [{
          "id": "0001",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1801/1a/94428c6dea109402.jpg_640x200_2cf590d8.jpg"
        },{
          "id": "0002",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1802/42/7c92b9a381e46402.jpg_640x200_1cdce2a4.jpg"
        },{
          "id": "0003",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1802/51/e78f936a5b404102.jpg_640x200_c14f0b3a.jpg"
        },{
          "id": "0004",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1712/91/a275569091681d02.jpg_640x200_0519ccb9.jpg"
        }],
      "iconList": [{
          "id": "0001",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png",
          "desc": "景点门票"
        }, {
          "id": "0002",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1711/df/86cbcfc533330d02.png",
          "desc": "滑雪季"
        }, {
          "id": "0003",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1710/a6/83f636bd75ae6302.png",
          "desc": "泡温泉"
        }, {
          "id": "0004",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/35/2640cab202c41b02.png",
          "desc": "动植园"
        }, {
          "id": "0005",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/d0/e09575e66f4aa402.png",
          "desc": "游乐园"
        }, {
          "id": "0006",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/59/569d3c096e542502.png",
          "desc": "必游榜单"
        }, {
          "id": "0007",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/17/4bd370f3eb1acd02.png",
          "desc": "演出"
        }, {
          "id": "0008",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/7f/b1ea3c8c7fb6db02.png",
          "desc": "城市观光"
        }, {
          "id": "0009",
          "imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/a9/ffc620dbda9b9c02.png",
          "desc": "一日游"
        }],
      "recommendList": [{
          "id": "0001",
          "imgUrl": "http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_140x140_80f63803.jpg",
          "title": "故宫",
          "desc": "东方宫殿建筑代表,世界宫殿建筑典范"
        }, {
          "id": "0002",
          "imgUrl": "http://img1.qunarzz.com/sight/p0/1511/d2/d2aec2dfc5aa771290.water.jpg_140x140_abb362a7.jpg",
          "title": "南山滑雪场",
          "desc": "北京专业级滑雪圣地"
        }, {
          "id": "0003",
          "imgUrl": "http://img1.qunarzz.com/sight/p0/1501/f4/f467729126949c3a.water.jpg_140x140_ef235b1c.jpg",
          "title": "天安门广场",
          "desc": "我爱北京天安门,天安门上太阳升"
        }, {
          "id": "0004",
          "imgUrl": "http://img1.qunarzz.com/sight/p0/1501/40/40b2b6c951b28fdd.water.jpg_140x140_1c863e5c.jpg",
          "title": "水立方",
          "desc": "中国的荣耀,阳光下的晶莹水滴"
        }, {
          "id": "0005",
          "imgUrl": "http://img1.qunarzz.com/sight/p0/201308/23/b283071686e64dfec8d65eac.jpg_140x140_8c5a7c49.jpg",
          "title": "温都水城养生馆",
          "desc": "各种亚热带植物掩映其间仿佛置身热带雨林"
        }],
      "weekendList": [{
          "id": "0001",
          "imgUrl": "http://img1.qunarzz.com/sight/source/1510/6e/1ea71e2f04e.jpg_r_640x214_aa6f091d.jpg",
          "title": "北京温泉排行榜",
          "desc": "细数北京温泉,温暖你的冬天"
        }, {
          "id": "0002",
          "imgUrl": "http://img1.qunarzz.com/sight/source/1505/aa/7baaf8a851d221.jpg_r_640x214_1431200f.jpg",
          "title": "北京必游TOP10",
          "desc": "来北京必去的景点非这些地方莫属"
        }, {
          "id": "0003",
          "imgUrl": "http://img1.qunarzz.com/sight/source/1505/9e/21df651e19af5d.jpg_r_640x214_3ea5bb38.jpg",
          "title": "寻找北京的皇城范儿",
          "desc": "数百年的宫廷庙宇,至今依旧威严霸气"
        }, {
          "id": "0004",
          "imgUrl": "http://img1.qunarzz.com/sight/source/1505/ce/bc89bc2f0e33ea.jpg_r_640x214_3e408453.jpg",
          "title": "学生最爱的博物馆",
          "desc": "周末干嘛?北京很多博物馆已经免费开放啦"
        }, {
          "id": "0005",
          "imgUrl": "http://img1.qunarzz.com/sight/source/1505/b2/fde1bfcd057a52.jpg_r_640x214_bbf3fa44.jpg",
          "title": "儿童剧场,孩子的乐园",
          "desc": "带宝贝观看演出,近距离体验艺术的无穷魅力"
        }]
    }
  }

b. 编辑’.gitignore’文件 - - - 不希望该文件内容提交到线上

.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# 不会被提交到线上的仓库里
static/mock

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

c. 编辑’vue.config.js’文件 - - - 实现开发环境的路径替换

const path = require('path')

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        // 请求转发到服务器的8080端口上
        target: 'http://localhost:8080',
        // 替换路径
        pathRewrite: {
          // '^/api': '/public/mock'
          '^/api': '/mock'
        }
      }
    }
  },
  chainWebpack: (config) => {
    config.resolve.alias
      .set('styles', path.join(__dirname, './src/assets/styles/'))
      .set('@', path.join(__dirname, './src/'))
    //   .set('common', path.join(__dirname, './src/common/'))
  }
}

d. Ajax动态数据请求成功

在这里插入图片描述

4.父子组件间传值 - - - 编辑’Home.vue’

<template>
  <div>
    <home-header :city='city'></home-header>
    <home-swiper :List='swiperList'></home-swiper>
    <home-icons :List='iconList'></home-icons>
    <home-recommend :List='recommendList'></home-recommend>
    <home-weekend :List='weekendList'></home-weekend>
  </div>
</template>

<script>
// 引用Header组件
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
import HomeIcons from './components/Icons'
import HomeRecommend from './components/Recommend'
import HomeWeekend from './components/Weekend'
import axios from 'axios'

export default {
  name: 'Home',
  components: {
    HomeHeader,
    HomeSwiper,
    HomeIcons,
    HomeRecommend,
    HomeWeekend
  },
  data () {
    return {
      city: '',
      swiperList: [],
      iconList: [],
      recommendList: [],
      weekendList: []
    }
  },
  methods: {
    // 创建一个函数
    getHomeInfo () {
      // 通过axios进行数据请求
      axios.get('/api/index.json')
      .then(this.getHomeInfoSucc)
    },
    getHomeInfoSucc (res) {
      // console.log(res)
      res = res.data
      // 如果后端返回了数值,并且有data这个数据项
      if (res.ret && res.data) {
        // 定义一个'data'='res.data'
        const data = res.data
        // ajix里面的'data.city'传给了'city'
        this.city = data.city
        // swiperList里面的数据进行传输
        this.swiperList = data.swiperList
        // iconList里面的数据进行传输
        this.iconList = data.iconList
        // recommendList里面的数据进行传输
        this.recommendList = data.recommendList
        // weekendList里面的数据进行传输
        this.weekendList = data.weekendList
      }
    }
  },
  // 创建一个生命周期函数,当页面挂载好了之后,执行这个函数
  mounted () {
    this.getHomeInfo()
  }
}
</script>

<style>
</style>


5.Header接收数据 - - - 编辑’Header.vue’

<template>
  <div class="header">
    <div class="header-left">
      <span class="iconfont back-icon">&#xe743;</span>
    </div>
    <div class="header-input">
      <span class='iconfont'>&#xe632;</span>
      输入城市、景点、游玩主题...
    </div>
    <div class="header-right">
      <!-- 城市 -->
      {{this.city}}
      <span class="iconfont arrow-icon">&#xe65c;</span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HomeHeader',
  props: {
    city: String
  }
}
</script>
<style lang='stylus' scoped>
// 引用'varibles.styl'变量样式
@import '~styles/varibles.styl'
  .header
    display flex
    // width 100%
    height $headerHight
    background-color $bgColor
    color #fff
    text-align center
    line-height $headerHight
    .header-left
      float left
      width .64rem
      .back-icon
        font-size .6rem
    .header-input
      flex 1
      margin-left .2rem
      margin-top .12rem
      padding-left .2rem
      height .64rem
      text-align left 
      line-height .64rem
      color #ccc
      border-radius .1rem
      background #fff
    .header-right
      float right
      width 1.24rem
      padding 0 .1rem
      .arrow-icon
        margin-left -.1rem
        font-size .4rem
</style>


6.Swiper接收数据 - - - 编辑’Swiper.vue’

<template>
  <div class="wrapper">
    <!-- 'v-if'是为了初次创建由完整的数组来创建,而不是空数组来创建(轮播图第一页不是默认的) -->
    <!-- <swiper :options="swiperOption" v-if="list.length"> 这种写法不够优雅,模板中不要涉及计算公式 -->
    <swiper :options="swiperOption" v-if="showSwiper">
      <swiper-slide v-for="item of List" :key="item.id">
        <img class='swiper-img' :src="item.imgUrl" alt="">
      </swiper-slide>
      <!-- 分页 -->
      <div class="swiper-pagination"  slot="pagination"></div>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeSwiper',
  props: {
    List: Array
  },
  data () {
    return {
      swiperOption: {
        // 填入一个配置项
        pagination: '.swiper-pagination',
        // 循环轮播
        loop: true
      }
    }
  },
  // 创建了个计算公式,可以被引用
  computed: {
    showSwiper () {
      return this.List.length
    }
  }
}
</script>

<style lang="stylus" scoped>
  // 通过鼠标右键审查元素定位要'class',从而修改样式(stylus的样式穿透)
  .wrapper >>> .swiper-pagination-bullet-active
    background #fff
    // background #fff !important
  .wrapper
    height 0
    padding-bottom 31.25%
    overflow hidden
    background #fff
    .swiper-img
      width 100%
</style>

7.Icons接收数据 - - - 编辑’Icons.vue’

<template>
  <div class="icons">
    <swiper :options="swiperOption">
      <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" alt="">
          </div>
          <p class="icon-desc">{{item.desc}}</p>
        </div>
      </swiper-slide>
    </swiper>
  </div>
</template>

<script>
export default {
  name: 'HomeIcons',
  props: {
    List: Array
  },
  data () {
    return {
      swiperOption: {
        // 防止轮播自动播放
        autoplay: false
      }
    }
  },
  // 计算
  computed: {
    // 定义一个函数
    pages () {
      // 申明一个空数组,作为传递所有item后总共的页数
      const pages = []
      // 将iconList循环一遍,可以获取到两个数据'循环项'和它对应的'下标'
      this.List.forEach((item, index) => {
        // 定义一个'page',计算页数  page = index/8 
        const page = Math.floor(index / 8)
        // page = index / 8 < 1时,pages[0]不变,不执行条件
        // page = index / 8 >= 1时,pages[page]和pages[0]不一致,执行条件
        if(!pages[page]) {
          // 重新创建一个空数组,然后都把新数据添加至空数组当前页
          pages[page] = []
        }
        pages[page].push(item)
      })
      return pages
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/varibles.styl';
@import '~styles/mixins.styl';
  // 右键审查元素定位到'class',从而修改样式
  .icons >>> .swiper-container
    // swiper自带overflow属性
    // overflow hidden
    height 0
    padding-bottom 50%
    // background #f5f5f5
  .icons
    margin-top .1rem
    .icon
      position relative
      float left
      width 25%
      height 0
      padding-bottom 25%
      // background skyblue
      overflow hidden
      .icon-img
        position absolute
        left 0
        top 0
        right 0
        bottom .44rem
        padding .1rem
        box-sizing border-box
        .icon-img-content
          display block
          height 100%
          margin 0 auto
      .icon-desc
        position absolute
        left 0
        right 0
        bottom 0
        height .44rem
        line-height .44rem
        text-align center
        color $darkTextColor
        // 封装的文字溢出效果
        ellipsis()
</style>

8.Recommend接收数据 - - - 编辑’Recommend.vue’

<template>
  <div>
    <div class="title">热销推荐</div>
    <ul>
      <li class="item" v-for="item of List" :key="item.id">
        <img class="item-img" :src="item.imgUrl">
        <div class="item-info">
          <p class="item-title">{{item.title}}</p>
          <p class="item-desc">{{item.desc}}</p>
          <button class="item-button">查看详情</button>
        </div>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HomeRecommend',
  props: {
    List: Array
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/mixins.styl';
  .title
    margin-top .2rem
    line-height .8rem
    background #eee
    text-indent .2rem
  .item
    overflow hidden
    display flex
    height 1.9rem
    background #f5f5f5
    .item-img
      width 1.7rem
      height 1.7rem
      margin .1rem
    .item-info
      flex 1
      padding .1rem
      // 限定最小宽度,实现文字溢出效果
      min-width 0
      .item-title
        line-height .54rem
        font-size .32rem
        ellipsis()
      .item-desc
        line-height .4rem
        color #ccc
        ellipsis()
      .item-button
        line-height .44rem
        color #fff
        margin-top .2rem
        padding 0 .2rem
        border-radius .6rem
        background #ff9300
</style>


9.Recommend接收数据 - - - 编辑’Recommend.vue’

<template>
  <div>
    <div class="title">热销推荐</div>
    <ul>
      <li class="item" v-for="item of List" :key="item.id">
        <img class="item-img" :src="item.imgUrl">
        <div class="item-info">
          <p class="item-title">{{item.title}}</p>
          <p class="item-desc">{{item.desc}}</p>
          <button class="item-button">查看详情</button>
        </div>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HomeRecommend',
  props: {
    List: Array
  }
}
</script>

<style lang="stylus" scoped>
@import '~styles/mixins.styl';
  .title
    margin-top .2rem
    line-height .8rem
    background #eee
    text-indent .2rem
  .item
    overflow hidden
    display flex
    height 1.9rem
    background #f5f5f5
    .item-img
      width 1.7rem
      height 1.7rem
      margin .1rem
    .item-info
      flex 1
      padding .1rem
      // 限定最小宽度,实现文字溢出效果
      min-width 0
      .item-title
        line-height .54rem
        font-size .32rem
        ellipsis()
      .item-desc
        line-height .4rem
        color #ccc
        ellipsis()
      .item-button
        line-height .44rem
        color #fff
        margin-top .2rem
        padding 0 .2rem
        border-radius .6rem
        background #ff9300
</style>







  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后海 0_o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值