Vue项目去哪儿网

目介绍

本项目是通过慕课网来学习的vue项目,因为公司比较忙,所以一段时间只能停下来。现在也算是终于写完了,因为没有本地服务器和后台支持,现在用的json文件调用。

项目引用插件

  

  fastclick:处理移动端click事件300毫秒延迟  引用方式:main.js  fastClick.attach(document.body)

  babel-polyfill:es6转es5的转换器

  vue-awesome-swiper:vue的swiper插件  引用方式:main.js   Vue.use(VueAwesomeSwiper)

  项目中vue-router&vuex,都是分别单独放在router和store文件夹下

项目组成

  项目中分为首页,城市列表页,以及旅游项目详情页。

扫描二维码关注公众号,回复: 2140700 查看本文章

  分别对应Home.vue   city.vue  detail.vue

  • 首页 home.vue

  构成:基本组件构建加vue-awesome-swiper 实现轮播。

  

  (list.vue包含Recommend.vue和Weekend.vue。因为都是v-for循环出来的数据,很基础 这里就不做总结了)

  home.vue 中的一个组件为icon.vue

  

  这个组件每一个icon是一条数据,对于这个分页 ,同样采用swiper插件,那么第一页显示8条,剩余第二页就需要计算,在这里采用计算属性computed 定一个page(),创建一个pages变量,把父组件传来的值iconlist进行分组,8个一组,

  进行分页展示

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
    }
  }

  home.vue其他的组件还是比较简单的,基本就是v-for对数据的循环。这里就不总结了。

  • 城市列表页 city.vue

   首先显示头部组件,当前城市和热门城市组件,城市搜索组件

  头部组件:页面标题加返回按钮 这个没什么说的。

  搜索组件:一个input框,这里用padding撑开(兼容),在页面上有一个灰色的不透明遮罩。v-show='hasNoData'来判断是否有数据来进行数据展示和友情提示。HasNoData是通过计算属性,把父组件传来的list的的长度作为判断条件

  

computed: {
    hasNoData () {
      return !this.list.length
    }
  }

  在输入框搜索,进行匹配的可以是文字也可以是拼音,通过父组件传来的citylist循环遍历,再把每个citylist[i]遍历出来,就是每个数据的对象,进行匹配的文字和拼音就是name字段和spell字段,然后添加到result,然后再赋值给list,在模板中循环就ok。

(部分数据展示)

<script type="es6">
import Bscroll from 'better-scroll'
import { mapMutations } from 'vuex'
export default {
  name: 'CitySearch',
  props: {
    citylist: Object
  },
  data () {
    return {
      keyword: '',
      list: [],
      times: null
    }
  },
  methods: {
    handleCityClick (city) {
      // this.$store.commit('changeCity', city)
      this.changeCity(city)
      this.$router.push('/')
    },
    ...mapMutations(['changeCity'])
  },
  computed: {
    hasNoData () {
      return !this.list.length
    }
  },
  watch: {
    keyword () {
      if (this.times) {
        clearTimeout(this.times)
      }
      if (!this.keyword) {
        this.list = []
        return
      }
      this.times = setTimeout(() => {
        const result = []
        for (let i in this.citylist) {
          this.citylist[i].forEach((value) => {
            if (value.spell.indexOf(this.keyword) > -1 ||
            value.name.indexOf(this.keyword) > -1) {
              result.push(value)
            }
          })
        }
        this.list = result
      }, 100)
    }
  },
  mounted () {
    this.scroll = new Bscroll(this.$refs.search)
  }
}
</script>

  Alphabet.vue组件 ,根据字母滑动迅速定位到该字母的城市。

  

<template>
  <div>
    <ul class="list">
      <li class="item"
          v-for="item of letters"
          :key="item"
          :ref="item"
          @click="handleLetterClick"
          @touchstart.prevent="handleTouchStart"
          @touchmove="handleTouchMove"
          @touchend="handleTouchEnd"
      >
        {{item}}
      </li>
    </ul>
  </div>
</template>
updated () {
    this.startY = this.$refs['A'][0].offsetTop
  },
  computed: {
    letters () {
      const letters = []
      for (let i in this.citylist) {
        letters.push(i)
      }
      return letters
    }
  },
  methods: {
    handleLetterClick (e) {
      this.$emit('change', e.target.innerText)
    },
    handleTouchStart () {
      this.touchStatus = true
    },
    handleTouchMove (e) {
      if (this.touchStatus) {
        if (this.timer) {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(() => {
          const touchY = e.touches[0].clientY - 79
          const index = Math.floor((touchY - this.startY) / 20)
          if (index >= 0 && index < this.letters.length) {
            this.$emit('change', this.letters[index])
          }
        }, 16)
      }
    },
    handleTouchEnd () {
      this.touchStatus = false
    }
  }

  通过计算属性把父组件传来的值进行循环,取出key值(A,B,C...),v-for循环key值,展示在页面。

  滑动定位当前字母位置:首先三个事件,touchStart(开启滚动),touchMove(手指移动),touchEnd(停止滚动),

  touchMove:touchY(手指滑动的位置),startY(首字母A的位置),因为css设计每个字母的宽高均为20,也就是说计算下标只需要Math.floor((touchY - this.startY) / 20),这样算出来的就是每个字母对应的下标,这样我们就能得到letters里面的数据,再传给父类,

  父类再传给子组件CityList组件,再利用better-scroll提供的this.scroll.scrollToElement(element)方法,把对应的对象传进去就会自定滑到对应位置,所以在页面上直接通过父组件传来的litter就可以迅速定位到自己滑动的字母对应的位置。

猜你喜欢

转载自www.cnblogs.com/-wch/p/9269809.html