父组件
<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>
网友评论