Skip to content
This repository has been archived by the owner on Nov 15, 2018. It is now read-only.

Commit

Permalink
feat: (#279) 问题搜索功能
Browse files Browse the repository at this point in the history
  • Loading branch information
mutoe committed Jul 4, 2018
1 parent 863d632 commit 4fa56fe
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 15 deletions.
24 changes: 14 additions & 10 deletions src/api/question/questions.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import request from "../../http";
import api from "../api";

/**
* Query questions list.
*
* @param {Object} query
* @return {Promise}
* @author Seven Du <[email protected]>
* @export
* @param {Object} params
* @param {string} params.type default: 'new', options: 'all', 'new', 'hot', 'reward', 'excellent'
* @param {number} params.limit
* @param {number} params.offset
* @param {string} params.subject search keyword
* @returns
*/
function queryList(query = {}) {
return request.get("/questions", {
params: query,
export function queryList(params = {}) {
return api.get("/questions", {
params,
validateStatus: status => status === 200
});
}
Expand All @@ -35,7 +39,7 @@ export function list(type, offset = 0, limit = 15) {
* @author Seven Du <[email protected]>
*/
export function show(id) {
return request.get(`/questions/${id}`, {
return api.get(`/questions/${id}`, {
validateStatus: status => status === 200
});
}
Expand All @@ -48,7 +52,7 @@ export function show(id) {
* @author Seven Du <[email protected]>
*/
export function watch(id) {
return request.put(
return api.put(
`/user/question-watches/${id}`,
{},
{
Expand All @@ -65,7 +69,7 @@ export function watch(id) {
* @author Seven Du <[email protected]>
*/
export function unwatch(id) {
return request.delete(`/user/question-watches/${id}`, {
return api.delete(`/user/question-watches/${id}`, {
validateStatus: status => status === 204
});
}
14 changes: 9 additions & 5 deletions src/api/question/topics.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ import request from "../../http";

/**
* The topics API query function.
*
* @param {Object} query
* @return {Promise}
* @author Seven Du <[email protected]>
* @export
* @param {Object} params
* @param {number} params.limit
* @param {number} params.offset
* @param {*} params.follow
* @param {string} params.name search keyword
* @returns
*/
export function query(query = {}) {
export function query(params = {}) {
return request.get("/question-topics", {
params: query,
params,
validateStatus: status => status === 200
});
}
Expand Down
201 changes: 201 additions & 0 deletions src/page/question/QuestionSearch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<template>
<div class="p-question-search">
<header class="m-box m-aln-center m-pos-f m-main m-bb1 m-head-top">
<div class="m-box m-flex-grow2 m-flex-shrink2 m-aln-center m-head-top-title">
<div class="m-search-box">
<form
action="#"
onsubmit="return false">
<input
v-model="keyword"
type="search"
placeholder="搜索"
@input="searchQuestions">
</form>
</div>
</div>
<div class="m-box m-flex-grow0 m-flex-shrink0 m-aln-center m-justify-end">
<a @click.prevent.stop="goBack">取消</a>
</div>
</header>

<nav class="questions-nav">
<router-link
to="/question/search"
replace
exact
exact-active-class="active">问题</router-link>
<router-link
:to="{path: '/question/search', query: {type: 'topic'}}"
replace
exact
exact-active-class="active">话题</router-link>
</nav>

<jo-load-more
ref="loadmore"
:auto-load="false"
:show-bottom="list.length > 0"
style="padding-top: 1.8rem"
@onRefresh="onRefresh"
@onLoadMore="onLoadMore">
<template v-if="type === 'question'">
<question-card
v-for="question in list"
:key="question.id"
:question="question" />
</template>
<template v-else>
<topic-card
v-for="topic in list"
:key="topic.id"
:topic="topic" />
</template>
</jo-load-more>
</div>
</template>

<script>
import _ from "lodash";
import TopicCard from "./components/TopicCard.vue";
import QuestionCard from "./components/QuestionCard.vue";
import { queryList as queryQuestions } from "@/api/question/questions";
import { query as queryTopics } from "@/api/question/topics";
import { limit } from "@/api/api";
const noop = () => {};
export default {
name: "QuestionSearch",
components: { TopicCard, QuestionCard },
data() {
return {
type: "question",
keyword: "", // search keyword
offset: 0, // search offset
limit: 15,
list: [] // search result
};
},
computed: {
after() {
const len = this.list.length;
return len > 0 ? this.list[len - 1].id : 0;
}
},
watch: {
$route(to) {
this.type = to.query.type || "question";
this.list = [];
this.offset = 0;
this.keyword = "";
}
},
mounted() {
this.type = this.$route.query.type || "question";
},
methods: {
/**
* 使用 lodash.debounce 节流,每输入 600ms 后执行
* 不要使用箭头函数,会导致 this 作用域丢失
* @function
* @author mutoe <[email protected]>
* @param {InputEvent} input event
* @param {requestCallback} callback
* @returns
*/
searchQuestions: _.debounce(function(event, callback) {
if (!this.keyword) return;
this.type === "question"
? this.queryQuestions(callback)
: this.queryTopics(callback);
}, 600),
queryQuestions(callback = noop) {
const params = {
offset: this.offset,
limit: this.limit,
subject: this.keyword
};
queryQuestions(params).then(({ data }) => {
if (this.offset === 0) {
this.list = data;
} else {
this.list = [...this.list, ...data];
}
callback(data.length < limit);
});
},
queryTopics(callback = noop) {
const params = {
offset: this.offset,
limit: this.limit,
name: this.keyword
};
queryTopics(params).then(({ data }) => {
if (this.offset === 0) {
this.list = data;
} else {
this.list = [...this.list, ...data];
}
callback(data.length < limit);
});
},
onRefresh(callback) {
this.offset = 0;
this.searchQuestions(null, callback);
},
onLoadMore(callback) {
this.offset = this.list.length;
this.searchQuestions(null, callback);
}
}
};
</script>

<style lang="less" scoped>
.p-question-search {
.m-head-top-title {
padding: 0 20px 0 0;
.m-search-box {
width: 100%;
}
}
.questions-nav {
position: fixed;
top: 90px;
display: flex;
width: 100%;
height: 90px;
justify-content: space-around;
align-items: center;
background: #fff;
color: #999;
font-size: 30px;
font-weight: normal;
font-stretch: normal;
line-height: 0;
letter-spacing: 0;
border-bottom: solid 0.01rem #d7d8d8;
z-index: 1;
@media screen and (min-width: 769px) {
width: 768px;
}
> a {
color: #d7d8d8;
}
.active {
color: #333;
}
}
}
</style>

<style lang="less">
.p-question-search {
.jo-loadmore-head {
top: 1.8rem;
}
}
</style>
10 changes: 10 additions & 0 deletions src/routers/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const TopicDetail = () =>
import(/*webpackChunkName:'question' */ "@/page/question/TopicDetail.vue");
const AnswerDetail = () =>
import(/*webpackChunkName:'question' */ "@/page/question/AnswerDetail.vue");
const QuestionSearch = () =>
import(/*webpackChunkName:'question' */ "@/page/question/QuestionSearch.vue");
const ArticleLikes = () =>
import(/*webpackChunkName:'question' */ "@/page/article/ArticleLikes.vue");
const ArticleRewards = () =>
Expand Down Expand Up @@ -56,6 +58,14 @@ export default [
title: "问题详情"
}
},
{
path: "/question/search",
component: QuestionSearch,
meta: {
title: "搜索",
keepAlive: true
}
},
/**
* 点赞列表 && 打赏列表 路由格式固定
* 帖子/资讯/问答 相关路由 统一使用 article 代替 id
Expand Down

0 comments on commit 4fa56fe

Please sign in to comment.