Skip to content

Commit

Permalink
feat(SPA): 动态话题
Browse files Browse the repository at this point in the history
issue #467
  • Loading branch information
mutoe committed Dec 5, 2018
1 parent 8c391c6 commit 157cf3a
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 1 deletion.
19 changes: 19 additions & 0 deletions resources/spa/src/api/topic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import api from './api'

/**
* 获取话题列表
*
* @author mutoe <[email protected]>
* @export
* @param {Object} params
* @param {string} [params.q] 搜索关键字
* @param {number} [params.limit=15]
* @param {string} [params.direction=desc]
* @param {number} [params.index=0]
* @param {string} [params.only] 是否热门 'hot'
* @returns
*/
export function getTopicList (params) {
const url = '/feed/topics'
return api.get(url, { params, validateStatus: s => s === 200 })
}
2 changes: 1 addition & 1 deletion resources/spa/src/icons/iconfont.js

Large diffs are not rendered by default.

Binary file added resources/spa/src/images/default_topic.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions resources/spa/src/page/Discover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ export default {
new_tips: false,
tips: '',
},
{
title: '话题',
icon: 'topic',
path: '/topic',
new_tips: false,
tips: '',
},
],
[
{
Expand Down
145 changes: 145 additions & 0 deletions resources/spa/src/page/topic/TopicHome.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<template>
<div class="p-topic-home">
<CommonHeader class="header">
<nav class="type-switch-bar">
<span :class="{active: currentType === 'hot'}" @click="currentType = 'hot'">
热门
</span>
<span :class="{active: currentType === 'new'}" @click="currentType = 'new'">
最新
</span>
</nav>
<div slot="right" class="buttons">
<RouterLink
tag="svg"
append
to="search"
class="m-style-svg m-svg-def"
>
<use xlink:href="#icon-search" />
</RouterLink>
<RouterLink
tag="svg"
append
to="create"
class="m-style-svg m-svg-def"
>
<use xlink:href="#icon-topic-create" />
</RouterLink>
</div>
</CommonHeader>

<main>
<JoLoadMore
ref="loadmore"
:show-bottom="currentType !== 'hot'"
@onRefresh="onRefresh"
@onLoadMore="onLoadMore"
>
<ul class="topic-list">
<TopicCard
v-for="topic in list"
:key="topic.id"
class="topic-item"
:topic="topic"
/>
</ul>
</JoLoadMore>
</main>
</div>
</template>

<script>
import { mapActions, mapState } from 'vuex'
import TopicCard from './components/TopicCard'
export default {
name: 'TopicHome',
components: {
TopicCard,
},
computed: {
...mapState('topic', {
hot: 'hotList',
new: 'newList',
}),
list () {
let type = this.currentType
return this[type]
},
currentType: {
get () {
return this.$route.query.type || 'hot'
},
set (type) {
this.$router.replace({
path: this.$route.path,
query: { type: type },
})
if (!this[type].length) this.onRefresh()
},
},
},
created () {
if (!this.$route.query.type) this.currentType = 'hot'
},
methods: {
...mapActions('topic', [
'fetchTopicList',
]),
onRefresh () {
this.fetchTopicList({ type: this.currentType, reset: true })
.then(more => void this.$refs.loadmore.afterRefresh(more))
},
onLoadMore () {
const lastTopic = [...this.list].pop() || {}
this.fetchTopicList({ type: this.currentType, params: { index: lastTopic.id } })
.then(more => void this.$refs.loadmore.afterLoadMore(more))
},
},
}
</script>

<style lang="less" scoped>
.p-topic-home {
.header {
overflow: initial;
}
.type-switch-bar {
display: flex;
justify-content: center;
align-items: center;
height: 90px;
> span {
display: inline-block;
height: 100%;
margin: 0 20px;
padding: 22px 12px;
color: #999;
transition: 0.3s;
&.active {
color: #333;
border-bottom: 2px solid @primary; /* no */
}
}
}
> main {
padding: 30px;
}
.topic-list {
display: flex;
flex-direction: column;
.topic-item {
width: 100%;
height: 300px;
margin-bottom: 30px;
}
}
}
</style>
53 changes: 53 additions & 0 deletions resources/spa/src/page/topic/components/TopicCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<li class="c-topic-card" :style="{'background-image': `url(${logo})`}">
<h2 class="title">{{ topic.name }}</h2>
</li>
</template>

<script>
export default {
name: 'TopicCard',
props: {
topic: { type: Object, required: true },
},
computed: {
logo () {
const { logo = {} } = this.topic
return logo.url || require('@/images/default_topic.jpg')
},
},
}
</script>

<style lang="less" scoped>
.c-topic-card {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: no-repeat center;
background-size: cover;
border-radius: 10px;
overflow: hidden;
&::before {
content: '';
position: absolute;
display: block;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0,0,0, .2);
z-index: 0;
}
.title {
position: relative;
color: #fff;
font-size: 42px;
letter-spacing: 8px;
z-index: 1;
}
}
</style>
2 changes: 2 additions & 0 deletions resources/spa/src/routers/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import groupRoutes from './group.js'
import messageRoutes from './message.js'
import questionRoutes from './question.js'
import profileRoutes from './profile.js'
import topicRoutes from './topic.js'

const router = [
/* 入口重定向 */
Expand All @@ -24,6 +25,7 @@ const router = [
...messageRoutes,
...questionRoutes,
...profileRoutes,
...topicRoutes,

{ path: '*', component: NotFound }, /* 404 页面 */
]
Expand Down
11 changes: 11 additions & 0 deletions resources/spa/src/routers/topic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import TopicHome from '@/page/topic/TopicHome.vue'

export default [
{
path: '/topic',
component: TopicHome,
meta: {
title: '话题',
},
},
]
2 changes: 2 additions & 0 deletions resources/spa/src/stores/module/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import news from './news'
import group from './group'
import feed from './feed'
import user from './user'
import topic from './topic'

export default {
rank,
Expand All @@ -20,4 +21,5 @@ export default {
group,
feed,
user,
topic,
}
49 changes: 49 additions & 0 deletions resources/spa/src/stores/module/topic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as api from '@/api/topic'
import { limit } from '@/api'

export const TYPES = {
SAVE_TOPIC_LIST: 'SAVE_TOPIC_LIST',
}

const state = {
hotList: [],
newList: [],
}

const getters = {}

const mutations = {
[TYPES.SAVE_TOPIC_LIST] (state, payload) {
let { list, type, reset = false } = payload
type = type === 'hot' ? 'hotList' : 'newList'
if (reset) {
state[type] = list
} else {
state[type].push(...list)
}
},
}

const actions = {
/**
* 获取动态列表
*
* @author mutoe <[email protected]>
* @returns {boolean} noMore?
*/
async fetchTopicList ({ commit }, payload) {
const { params = {}, reset, type } = payload
if (type === 'hot') params.only = 'hot'
const { data: list = [] } = await api.getTopicList(params)
commit(TYPES.SAVE_TOPIC_LIST, { list, type, reset })
return list.length < limit
},
}

export default {
namespaced: true,
state,
getters,
mutations,
actions,
}

0 comments on commit 157cf3a

Please sign in to comment.