Skip to content

Commit 8728012

Browse files
committed
add the fetch data part, but did't work right now
1 parent 0c814af commit 8728012

File tree

2 files changed

+169
-23
lines changed

2 files changed

+169
-23
lines changed

tutorials/0-vue.js-vuex-router/index.html

+165-15
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<script src="https://unpkg.com/[email protected]/dist/vue-router.js" charset="utf-8"></script>
99
<script src="https://unpkg.com/[email protected]" charset="utf-8"></script>
1010
<script src="https://www.gstatic.com/firebasejs/3.6.5/firebase.js"></script>
11+
<script src="./api.js"></script>
1112
<!-- <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,700' rel='stylesheet' type='text/css'> -->
1213
<link rel="stylesheet" href="./style.css">
1314
</head>
@@ -21,49 +22,198 @@
2122
</a>
2223
<router-link to="/top">Top</router-link>
2324
<router-link to="/new">New</router-link>
24-
<a href="javascript:;">Show</a>
25-
<a href="javascript:;">Ask</a>
26-
<a href="javascript:;">Jobs</a>
25+
<router-link to="/show">Show</router-link>
26+
<router-link to="/ask">Ask</router-link>
27+
<router-link to="/jobs">Jobs</router-link>
2728
<a href="https://github.com/vuejs/vue-hackernews-2.0" target="_blank" class="github">
2829
Bulid with Vue.js
2930
</a>
3031
</div>
3132
</div>
32-
<div class="nav">
33-
<div class="pages">
34-
<a href="javascript:;">&lt; prev</a>
35-
<span>n/25</span>
36-
<a href="javascript:;">more &gt;</a>
37-
</div>
38-
</div>
3933

4034
<router-view class="view"></router-view>
4135
</div>
4236

4337
<script type="text/x-template" id="top">
4438
<div class="top">
45-
<p>You are welcome to this world!</p>
39+
<div class="nav">
40+
<div class="pages">
41+
<a href="javascript:;">&lt; prev</a>
42+
<span>n/25</span>
43+
<a href="javascript:;">more &gt;</a>
44+
</div>
45+
</div>
46+
47+
<transition :name="transition">
48+
<div class="news-list" :key="displayedPage" v-if="true">
49+
<transition-group tag="ul" name="item">
50+
<li v-for="item in displayedItems" :key="item.id" :item="item" class="news-item">
51+
<span class="score">{{ item.score }}</span>
52+
<span class="title">
53+
<template v-if="item.url">
54+
<a :href="item.url" target="_blank">{{ item.title }}</a>
55+
<span class="host">({{ item.url | host }})</span>
56+
</template>
57+
<template v-else>
58+
<router-link :to="'/item/' + item.id" >{{ item.title }}</router-link>
59+
</template>
60+
</span>
61+
<br>
62+
<span class="meta">
63+
<span v-if="item.type !== 'job'" class="by">
64+
by <router-link :to="'/user/' + item.by">{{ item.by }}</router-link>
65+
</span>
66+
<span class="time">
67+
{{ item.time | timeAgo }} ago
68+
</span>
69+
<span v-if="item.type !== 'job'" class="comments-link">
70+
| <router-link :to="'/item/' + item.id ">{{ item.descendants }}</router-link>
71+
</span>
72+
</span>
73+
<span class="label" v-if="item.type !== 'story'">{{ item.type }}</span>
74+
</li>
75+
</transition-group>
76+
</div>
77+
</transition>
4678
</div>
4779
</script>
4880

4981
<script type="text/javascript">
50-
// const Top = { template: '<p>You are welcome to this world!</p>' }
5182
const Top = Vue.extend({
52-
template: '#top'
53-
})
83+
template: '#top',
84+
85+
data() {
86+
const isInitialRender = !this.$root._isMounted
87+
return {
88+
loading: false,
89+
transition: 'slide-left',
90+
// displayedPage: isInitialRender ? Number(this.$store.state.route.params.page) || 1 : -1,
91+
// displayedItems: isInitialRender ? this.$store.getters.activeItems : []
92+
}
93+
},
94+
95+
props: ['item'],
96+
97+
computed: {
98+
page(){
99+
return Number(this.$store.state.route.params.page) || 1
100+
},
101+
maxPage(){
102+
const { itemsPerPage, lists } = this.$store.state
103+
return Math.ceil(lists[this.type].length / itemsPerPage )
104+
},
105+
hasMore(){
106+
return this.page < this.maxPage
107+
}
108+
},
109+
110+
beforeMount(){
111+
if(this.$root._isMounted){
112+
this.loadItems(this.page)
113+
}
114+
}
115+
116+
117+
118+
});
54119

55120
const router = new VueRouter({
56121
routes: [
57122
{ path: '/top', component: Top }
58123
]
59124
});
125+
126+
const store = new Vuex.Store({
127+
state: {
128+
itemsPerPage: 20,
129+
items: { },
130+
users: { },
131+
lists: {
132+
top: [],
133+
new: [],
134+
show: [],
135+
ask: [],
136+
job: []
137+
}
138+
},
139+
140+
actions: {
141+
FETCH_LIST_DATA: ({ commit, dispatch, state }, { type }) => {
142+
commit('SET_ACTIVE_TYPE', { type })
143+
return fetchIdsByType(type)
144+
.then(ids => commit('SET_LIST', { type, ids }))
145+
.then(() => dispatch('ENSURE_ACTIVE_ITEMS'))
146+
},
147+
148+
ENSURE_ACTIVE_ITEMS: ({ dispatch, getters }) => {
149+
return dispatch('FETCH_ITEMS', {
150+
ids: getters.activeIds
151+
})
152+
},
153+
154+
FETCH_ITEMS: ({ commit, state }, { ids }) => {
155+
ids = ids.filter(id => !state.items[id])
156+
if(ids.length){
157+
return fetchItems(ids).then(items => commit('SET_ITEMS', { items }))
158+
}else {
159+
return Promise.resolve()
160+
}
161+
},
162+
163+
FETCH_USER: ({ commit, state }, { id }) => {
164+
return state.users[id]
165+
? Promise.resolve(state.users[id])
166+
: fetchUser(id).then(user => commit('SET_USER', { user }))
167+
}
168+
},
169+
170+
mutations: {
171+
SET_ACTIVE_TYPE: (state, { type }) => {
172+
state.activeType = type
173+
},
174+
175+
SET_LIST: (state, { type, ids }) => {
176+
state.lists[type] = ids
177+
},
178+
179+
SET_ITEMS: (state, { items }) => {
180+
items.forEach( item => {
181+
if(item){
182+
Vue.set(state.items, item.id, item)
183+
}
184+
})
185+
},
186+
187+
SET_USER: (state, { user }) => {
188+
Vue.set(state.users, user.id, user)
189+
}
190+
},
191+
192+
getters: {
193+
activeIds(state){
194+
const { activeType, itemsPerPage, lists } = state
195+
const page = Number(state.route.params.page) || 1
196+
if(activeType){
197+
const start = (page-1) * itemsPerPage
198+
const end = page * itemsPerPage
199+
return lists[activeType].slice(start, end)
200+
}else {
201+
return []
202+
}
203+
},
204+
205+
activeItems (state, getters){
206+
return getters.activeIds.map(id => state.items[id]).filter(_ => _)
207+
}
208+
}
209+
})
210+
60211
new Vue({
61212
router,
62213
el: '#app'
63214
})
64215
</script>
65216

66-
<script src="./api.js"></script>
67217
<script src="./app.js"></script>
68218

69219
</body>

tutorials/0-vue.js-vuex-router/style.css

+4-8
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,24 @@ body {
3535
vertical-align: middle;
3636
display: inline-block;
3737
}
38-
.nav {
38+
.top .nav {
3939
background-color: #fff;
4040
box-shadow: 0 2px 1px rgba(0, 0, 0, 0.1);
4141
}
42-
.nav .pages {
42+
.top .nav .pages {
4343
max-width: 800px;
4444
margin: 0 auto;
4545
padding: 15px;
4646
text-align: center;
4747
}
48-
.nav .pages a {
48+
.top .nav .pages a {
4949
color: inherit;
5050
text-decoration: none;
5151
margin: 0 1em;
5252
}
5353

5454
.top {
55-
margin: 30px auto;
56-
border: 2px solid rgba(255, 0, 0, 0.2);
57-
padding: 0px;
58-
max-width: 800px;
59-
text-align: center;
55+
6056
}
6157
@media (max-width: 860px) {
6258
.header .inner {

0 commit comments

Comments
 (0)