Skip to content

Commit f519772

Browse files
committed
item view
1 parent e9257b8 commit f519772

File tree

12 files changed

+99
-45
lines changed

12 files changed

+99
-45
lines changed
File renamed without changes.

src/components/Item.vue

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template>
2+
<li class="news-item">
3+
<a :href="item.url" target="_blank">{{ item.title }}</a><br>
4+
<router-link :to="'/item/' + item.id">
5+
{{ item.descendants }} comments
6+
</router-link>
7+
| by
8+
<router-link :to="'/user/' + item.by">
9+
{{ item.by }}
10+
</router-link>
11+
</li>
12+
</template>
13+
14+
<script>
15+
export default {
16+
name: 'NewsItem',
17+
props: ['item']
18+
}
19+
</script>
20+
21+
<style lang="stylus">
22+
.news-item
23+
background-color #fff
24+
margin 10px 0
25+
</style>

src/components/NewsList.vue renamed to src/components/ItemList.vue

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
<transition :name="transition">
1717
<div class="news-list" :key="displayedPage">
1818
<transition-group tag="ul" name="item">
19-
<news-item v-for="item in displayedItems" :key="item.id" :item="item">
20-
</news-item>
19+
<item v-for="item in displayedItems" :key="item.id" :item="item">
20+
</item>
2121
</transition-group>
2222
</div>
2323
</transition>
@@ -26,15 +26,15 @@
2626

2727
<script>
2828
import Spinner from './Spinner.vue'
29-
import NewsItem from './NewsItem.vue'
29+
import Item from './Item.vue'
3030
import { watchList } from '../store/api'
3131
3232
export default {
33-
name: 'NewsList',
33+
name: 'item-list',
3434
3535
components: {
3636
Spinner,
37-
NewsItem
37+
Item
3838
},
3939
4040
props: {
@@ -68,20 +68,20 @@ export default {
6868
}
6969
},
7070
71-
mounted () {
71+
beforeMount () {
7272
if (this.$root._isMounted) {
7373
this.loadItems(this.page)
7474
}
7575
// watch the current list for realtime updates
7676
this.unwatchList = watchList(this.type, ids => {
7777
this.$store.commit('SET_LIST', { type: this.type, ids })
78-
this.$store.dispatch('FETCH_ACTIVE_ITEMS').then(() => {
78+
this.$store.dispatch('ENSURE_ACTIVE_ITEMS').then(() => {
7979
this.displayedItems = this.$store.getters.activeItems
8080
})
8181
})
8282
},
8383
84-
destroyed () {
84+
beforeDestroy () {
8585
this.unwatchList()
8686
},
8787
@@ -94,7 +94,7 @@ export default {
9494
methods: {
9595
loadItems (to = this.page, from = -1) {
9696
this.loading = true
97-
this.$store.dispatch('FETCH_DATA_FOR_TYPE', {
97+
this.$store.dispatch('FETCH_LIST_DATA', {
9898
type: this.type
9999
}).then(() => {
100100
if (this.page < 0 || this.page > this.maxPage) {

src/components/NewsItem.vue

-15
This file was deleted.

src/router/index.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import Router from 'vue-router'
44
Vue.use(Router)
55

66
import { createListView } from '../views/CreateListView'
7-
import About from '../views/About.vue'
7+
import ItemView from '../views/ItemView.vue'
8+
import UserView from '../views/UserView.vue'
9+
import AboutView from '../views/AboutView.vue'
810

911
export default new Router({
1012
mode: 'history',
@@ -14,7 +16,9 @@ export default new Router({
1416
{ path: '/show/:page(\\d+)?', component: createListView('show') },
1517
{ path: '/ask/:page(\\d+)?', component: createListView('ask') },
1618
{ path: '/job/:page(\\d+)?', component: createListView('job') },
17-
{ path: '/about', component: About },
19+
{ path: '/item/:id(\\d+)', component: ItemView },
20+
{ path: '/user/:id', component: UserView },
21+
{ path: '/about', component: AboutView },
1822
{ path: '*', redirect: '/top/1' }
1923
]
2024
})

src/store/api.js

-3
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,11 @@ export function watchList (type, cb) {
7979
if (first) {
8080
first = false
8181
} else {
82-
console.log(`update for ${type}`)
8382
cb(snapshot.val())
8483
}
8584
}
86-
console.log(`watching ${type}...`)
8785
ref.on('value', handler)
8886
return () => {
89-
console.log(`stop watching ${type}`)
9087
ref.off('value', handler)
9188
}
9289
}

src/store/index.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Vue from 'vue'
22
import Vuex from 'vuex'
3-
import { fetchIdsByType, fetchItems } from './api'
3+
import { fetchIdsByType, fetchItem, fetchItems } from './api'
44

55
Vue.use(Vuex)
66

@@ -23,17 +23,23 @@ const store = new Vuex.Store({
2323

2424
actions: {
2525
// ensure data for rendering given list type
26-
FETCH_DATA_FOR_TYPE: ({ commit, dispatch, state, getters }, { type }) => {
26+
FETCH_LIST_DATA: ({ commit, dispatch, state, getters }, { type }) => {
2727
commit('SET_ACTIVE_TYPE', { type })
2828
return fetchIdsByType(type)
2929
.then(ids => commit('SET_LIST', { type, ids }))
30-
.then(() => dispatch('FETCH_ACTIVE_ITEMS'))
30+
.then(() => dispatch('ENSURE_ACTIVE_ITEMS'))
3131
},
3232

3333
// ensure all active items are fetched
34-
FETCH_ACTIVE_ITEMS: ({ commit, state, getters }) => {
34+
ENSURE_ACTIVE_ITEMS: ({ dispatch, getters }) => {
35+
return dispatch('FETCH_ITEMS', {
36+
ids: getters.activeIds
37+
})
38+
},
39+
40+
FETCH_ITEMS: ({ commit, state }, { ids }) => {
3541
// only fetch items that we don't already have.
36-
const ids = getters.activeIds.filter(id => !state.items[id])
42+
ids = ids.filter(id => !state.items[id])
3743
if (ids.length) {
3844
return fetchItems(ids).then(items => commit('SET_ITEMS', { items }))
3945
} else {

src/views/About.vue renamed to src/views/AboutView.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77

88
<script>
99
export default {
10-
name: 'about'
10+
name: 'about-view'
1111
}
1212
</script>

src/views/CreateListView.js

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
1-
import NewsList from '../components/NewsList.vue'
1+
import ItemList from '../components/ItemList.vue'
22

33
// factory function for creating root-level list views
44
// since they share most of the logic except for the type of items to display.
55
export function createListView (type) {
66
return {
7-
name: `${type}-stories`,
8-
components: {
9-
NewsList
10-
},
7+
name: `${type}-stories-view`,
118
// this will be called during SSR to pre-fetch data into the store!
129
preFetch (store) {
13-
return store.dispatch('FETCH_DATA_FOR_TYPE', { type })
14-
},
15-
created () {
16-
this.$store.commit('SET_ACTIVE_TYPE', { type })
10+
return store.dispatch('FETCH_LIST_DATA', { type })
1711
},
1812
render (h) {
19-
return h(NewsList, { props: { type }})
13+
return h(ItemList, { props: { type }})
2014
}
2115
}
2216
}

src/views/ItemView.vue

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<div class="item-view">
3+
<h2>Item!</h2>
4+
<p v-if="item">{{ item.title }}</p>
5+
</div>
6+
</template>
7+
8+
<script>
9+
export default {
10+
name: 'item-view',
11+
computed: {
12+
item () {
13+
return this.$store.state.items[this.$route.params.id]
14+
}
15+
},
16+
beforeMount () {
17+
this.$store.dispatch('FETCH_ITEMS', {
18+
ids: [this.$route.params.id]
19+
})
20+
}
21+
}
22+
</script>

src/views/User.vue

Whitespace-only changes.

src/views/UserView.vue

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<template>
2+
<div class="user-view">
3+
<h2>User!</h2>
4+
</div>
5+
</template>
6+
7+
<script>
8+
export default {
9+
name: 'user-view',
10+
11+
preFetch (store) {
12+
return store.dispatch('FETCH_USER', {
13+
id: store.state.route.params.id
14+
})
15+
},
16+
17+
mounted () {
18+
19+
}
20+
}
21+
</script>

0 commit comments

Comments
 (0)