分类选择 组件开发

2019-06-27  本文已影响0人  糖醋里脊120625

父组件

<template>
  <div class="category">
    <div class="nav-wrapper">
      <div class="tabs">
        <div
          v-for="(item, index) in cats"
          :key="item"
          class="item"
          :class="getCls(index)"
          @click="switchTab(index)"
        >
          <span class="text">{{ item }}</span>
          <i class="iconfont icon-drop-down" :class="{'icon-drop-up': index === activeTabIdx}"/>
        </div>
      </div>
      <div v-show="activeTabIdx !== -1" class="tab-content">
        <SizerCategory
          v-show="activeTabIdx === 0"
          ref="sizerCategory"
          v-model="params.categories"
          @change="getMovies"
        />
        <SizerType
          v-show="activeTabIdx === 1"
          :status="params.type"
          @change="changeType"
        />
        <SizerRate
          v-show="activeTabIdx === 2"
          ref="sizerRate"
          v-model="params.rate"
          @change="getMovies"
        />
      </div>
      <div v-show="activeTabIdx !== -1" class="mask" @click="closeTab"/>
    </div>
    <div v-show="!loading" class="movie-wrapper">
      <ScrollView :data="movies">
        <Card
          v-for="movie in movies"
          :key="movie._id"
          :movie="movie"
          @select="selectItem"
        />
      </ScrollView>
      <div v-show="!movies.length" class="no-result">
        <img src="~common/images/noresult.png" class="img">
        <p class="text">没有找到相关内容</p>
      </div>
    </div>
    <div v-show="loading" class="loading-wrap">
      <Loading/>
    </div>
  </div>
</template>

<script>
import SizerCategory from 'components/SizerCategory'
import SizerType from 'components/SizerType'
import SizerRate from 'components/SizerRate'

export default {
  components: {
    SizerType,
    SizerRate,
    SizerCategory
  },
  data () {
    return {
      cats: ['分类', '已上映', '评分'],
      activeTabIdx: 2,
      movies: [],
      params: {
        categories: [],
        rate: [0, 10],
        type: 1
      },
      loading: true
    }
  },
  created () {
    this.getMovies()
  },
  methods: {
    getMovies () {
      this.activeTabIdx = -1
      this.loading = true
      const { categories, rate, type } = this.params
      const params = {
        categories: JSON.stringify(categories),
        rate: JSON.stringify(rate),
        type: type
      }
      this.$axios.get('/api/movie/get_special_movies', { params }).then(res => {
        if (res.code === 1001) {
          this.movies = res.result.movies
        }
        this.loading = false
      })
    },
    // 切换 type、tab[1] 名字
    changeType ({ type, name }) {
      this.params.type = type
      this.cats[1] = name
      this.getMovies()
    },
    switchTab (idx) {
      // 点击相同
      if (idx === this.activeTabIdx) {
        this.activeTabIdx = -1
        return
      }

      // 当选择未上映的时候,评分不可选
      if (this.params.type === 0 && idx === 2) return

      this.activeTabIdx = idx

      // 当从其他tab点击第一个时,重置组件cacheList
      if (idx === 0) {
        this.$refs.sizerCategory.resetCache()
      }

      if (idx === 2) {
        this.$nextTick(() => {
          this.$refs.sizerRate.resetCache()
        })
      }
    },
    selectItem (id) {
      this.$router.push(`/movie/${id}`)
    },
    closeTab () {
      this.activeTabIdx = -1
    },
    getCls (index) {
      return {
        'active': index === this.activeTabIdx,
        'disable': index === 2 && this.params.type === 0
      }
    }
  }
}
</script>

SizerCategory 组件

<template>
  <div class="category-wrapper">
    <div class="list">
      <span
        v-for="item in list"
        :key="item._id"
        :class="{'active': cacheList.includes(item.name)}"
        class="item"
        @click="selectItem(item.name)"
      >
        {{ item.name }}
      </span>
    </div>
    <button class="confirm-btn" @click="confirm">完成</button>
  </div>
</template>

<script>
export default {
  model: {
    prop: 'categories',
    event: 'change'
  },
  props: {
    categories: {
      type: Array,
      required: true
    }
  },
  data () {
    return {
      list: [],
      cacheList: []
    }
  },
  created () {
    this.getCategories()
  },
  methods: {
    getCategories () {
      this.$axios.get('/api/category/get_cates').then(res => {
        if (res.code === 1001) {
          this.list = res.result.cates
        }
      })
    },
    resetCache () {
      this.cacheList = this.categories.slice()
    },
    selectItem (name) {
      const arr = this.cacheList.slice()
      const idx = arr.indexOf(name)
      if (idx > -1) {
        arr.splice(idx, 1)
      } else {
        arr.push(name)
      }
      this.cacheList = arr
    },
    confirm () {
      this.$emit('change', this.cacheList)
    }
  }
}
</script>

SizerType组件

<template>
  <div class="type-wrapper">
    <div
      v-for="item in types"
      :key="item.name"
      class="item"
      :class="{'active': status === item.type}"
      @click="selectItem(item)"
    >
      <i class="iconfont icon-dui"/>
      <span class="text">{{ item.name }}</span>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    status: {
      type: [String, Number],
      required: true
    }
  },
  data () {
    return {
      types: [
        { name: '全部', type: '' },
        { name: '已上映', type: 1 },
        { name: '未上映', type: 0 }
      ]
    }
  },
  methods: {
    selectItem (item) {
      this.$emit('change', item)
    }
  }
}
</script>

<style lang="stylus" scoped>
.type-wrapper
  display flex
  flex-direction column
  background #fff
  .item
    position relative
    flex 1
    line-height 40px
    margin 0 30px
    color #333
    border-bottom 1px solid #e5e5e5
    .icon-dui
      display none
      position absolute
      left -25px
    &.active
      color #faaf00
      .icon-dui
        display inline
</style>


上一篇 下一篇

猜你喜欢

热点阅读