Commit 74736699 authored by Evan You's avatar Evan You

mutiple lists

parent 144379b7
......@@ -25,7 +25,7 @@ body
width 30px
.view
transition all .35s ease
transition all .2s ease
.view-enter, .view-leave-active
opacity 0
......
......@@ -44,50 +44,46 @@ export default {
data () {
return {
loading: false,
displayedPage: -1,
displayedItems: [],
transition: 'slide-left'
transition: 'slide-left',
displayedPage: Number(this.$store.state.route.params.page) || 1,
displayedItems: this.$store.getters.activeItems
}
},
computed: {
activeItems () {
return this.$store.getters.activeItems
},
page () {
return Number(this.$store.state.route.params.page) || 1
},
maxPage () {
const { itemsPerPage, itemIdsByType } = this.$store.state
return Math.floor(itemIdsByType[this.type].length / itemsPerPage)
const { itemsPerPage, lists } = this.$store.state
return Math.ceil(lists[this.type].length / itemsPerPage)
},
hasMore () {
return this.page < this.maxPage
}
},
created () {
this.displayedPage = this.page
this.displayedItems = this.activeItems
},
mounted () {
if (this.page > this.maxPage || this.page < 1) {
this.$router.replace(`/${this.type}/1`)
} else {
fetchInitialData(this.type).then(() => {
this.displayedItems = this.activeItems
})
}
this.loadItems(this.page, -1)
},
watch: {
page (to, from) {
this.loadItems(to, from)
}
},
methods: {
loadItems (to, from) {
this.loading = true
this.$store.dispatch('FETCH_ACTIVE_ITEMS').then(() => {
fetchInitialData(this.type).then(() => {
if (this.page < 0 || this.page > this.maxPage) {
this.$router.replace(`/${this.type}/1`)
return
}
this.transition = to > from ? 'slide-left' : 'slide-right'
this.displayedPage = to
this.displayedItems = this.activeItems
this.displayedItems = this.$store.getters.activeItems
this.loading = false
})
}
......
......@@ -3,17 +3,17 @@ import Router from 'vue-router'
Vue.use(Router)
import { createStoriesView } from '../views/CreateStoriesView'
import { createListView } from '../views/CreateListView'
import About from '../views/About.vue'
export default new Router({
mode: 'history',
routes: [
{ path: '/top/:page(\\d+)?', component: createStoriesView('top') },
{ path: '/new/:page(\\d+)?', component: createStoriesView('new') },
{ path: '/show/:page(\\d+)?', component: createStoriesView('show') },
{ path: '/ask/:page(\\d+)?', component: createStoriesView('ask') },
{ path: '/job/:page(\\d+)?', component: createStoriesView('job') },
{ path: '/top/:page(\\d+)?', component: createListView('top') },
{ path: '/new/:page(\\d+)?', component: createListView('new') },
{ path: '/show/:page(\\d+)?', component: createListView('show') },
{ path: '/ask/:page(\\d+)?', component: createListView('ask') },
{ path: '/job/:page(\\d+)?', component: createListView('job') },
{ path: '/about', component: About },
{ path: '*', redirect: '/top/1' }
]
......
......@@ -8,13 +8,11 @@ const store = new Vuex.Store({
state: {
activeType: null,
itemsPerPage: 20,
// the current items being displayed
activeItemIds: [/* number */],
// fetched items by id. This also serves as a cache to some extent
items: {/* [id: number]: Item */},
// the id lists for each type of stories
// will be periodically updated in realtime
itemIdsByType: {
lists: {
top: [],
new: [],
show: [],
......@@ -42,7 +40,7 @@ const store = new Vuex.Store({
state.activeType = type
},
SET_IDS: (state, { type, ids }) => {
state.itemIdsByType[type] = ids
state.lists[type] = ids
},
SET_ITEMS: (state, { items }) => {
items.forEach(item => {
......@@ -53,12 +51,12 @@ const store = new Vuex.Store({
getters: {
activeIds (state) {
const { activeType, itemsPerPage, itemIdsByType } = state
const { activeType, itemsPerPage, lists } = state
const page = Number(state.route.params.page) || 1
if (activeType) {
const start = (page - 1) * itemsPerPage
const end = page * itemsPerPage
return itemIdsByType[activeType].slice(start, end)
return lists[activeType].slice(start, end)
} else {
return []
}
......
import NewsList from '../components/NewsList.vue'
import { fetchInitialData } from '../store'
export function createStoriesView (type) {
// factory function for creating root-level list views
// since they share most of the logic except for the type of items to display.
export function createListView (type) {
return {
name: `${type}-stories`,
components: {
NewsList
},
prefetch () {
fetchInitialData(type)
return fetchInitialData(type)
},
created () {
this.$store.commit('SET_ACTIVE_TYPE', { type })
},
render (h) {
return h(NewsList, { props: { type }})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment