✨ 一个简易的搜索功能解决方案
This commit is contained in:
parent
0e5ca8cfcd
commit
93c7567676
@ -6,19 +6,18 @@
|
|||||||
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
||||||
</a>
|
</a>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
<el-col :xs="0" :sm="12" :md="8" :xl="8" style="text-align: center;">
|
||||||
<!--<el-col :xs="24" :sm="16" :xl="12">-->
|
<el-row type="flex" justify="center">
|
||||||
<el-col :xs="0" :sm="0" :xl="0">
|
<el-col>
|
||||||
<el-autocomplete
|
<el-menu :default-active="getActiveMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
||||||
v-model="state"
|
@select="handleSelectMenu">
|
||||||
size="small"
|
<el-menu-item index="index">首页</el-menu-item>
|
||||||
:fetch-suggestions="querySearchAsync"
|
<el-menu-item index="topic">专题</el-menu-item>
|
||||||
placeholder="搜索帖子、标签和用户"
|
</el-menu>
|
||||||
:trigger-on-focus="false"
|
|
||||||
@select="handleSelect"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<!--<el-col v-if="user" :xs="0" :sm="8" :xl="6">-->
|
</el-row>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
||||||
<client-only>
|
<client-only>
|
||||||
<el-col v-if="user" style="text-align: right;">
|
<el-col v-if="user" style="text-align: right;">
|
||||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/article/post">发帖
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/article/post">发帖
|
||||||
@ -127,27 +126,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadAll() {
|
|
||||||
return [
|
|
||||||
{"value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号"},
|
|
||||||
{"value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号"},
|
|
||||||
{"value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
querySearchAsync(queryString, cb) {
|
|
||||||
let restaurants = this.restaurants;
|
|
||||||
let results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants;
|
|
||||||
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
this.timeout = setTimeout(() => {
|
|
||||||
cb(results);
|
|
||||||
}, 3000 * Math.random());
|
|
||||||
},
|
|
||||||
createStateFilter(queryString) {
|
|
||||||
return (state) => {
|
|
||||||
return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
handleSelectMenu(item) {
|
handleSelectMenu(item) {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
let activeMenu = _ts.$store.state.activeMenu;
|
let activeMenu = _ts.$store.state.activeMenu;
|
||||||
@ -171,9 +149,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSelect(item) {
|
|
||||||
console.log(item)
|
|
||||||
},
|
|
||||||
handleCommand(item) {
|
handleCommand(item) {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
switch (item) {
|
switch (item) {
|
||||||
@ -211,7 +186,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// this.restaurants = this.loadAll();
|
|
||||||
let user = this.user;
|
let user = this.user;
|
||||||
if (user) {
|
if (user) {
|
||||||
this.getUnreadNotifications();
|
this.getUnreadNotifications();
|
||||||
|
@ -6,37 +6,50 @@
|
|||||||
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
<img src="@/assets/rymcu.png" alt="RYMCU" class="navbar-brand-img">
|
||||||
</a>
|
</a>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="0" :sm="12" :md="14" :xl="18" style="text-align: center;">
|
<el-col :xs="0" :sm="8" :md="8" :xl="12" style="text-align: center;">
|
||||||
<el-row type="flex" justify="center">
|
<el-row type="flex" justify="center">
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-menu :default-active="getActiveMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
<el-menu :default-active="activeMenu" style="margin-top: -2px;border: 0;" mode="horizontal"
|
||||||
@select="handleSelectMenu">
|
@select="handleSelectMenu">
|
||||||
<el-menu-item index="index">首页</el-menu-item>
|
<el-menu-item index="index">首页</el-menu-item>
|
||||||
<el-menu-item index="topic">专题</el-menu-item>
|
<el-menu-item index="topic">专题</el-menu-item>
|
||||||
<!-- <el-menu-item index="github">开源代码</el-menu-item>-->
|
|
||||||
<!-- <el-menu-item index="open-source">资料下载</el-menu-item>-->
|
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="16" :sm="8" :md="6" :xl="3" style="padding-top: 1rem;">
|
<el-col :xs="10" :sm="6" :md="6" :xl="6" style="padding-top: 1rem;text-align: right;">
|
||||||
<!--<el-col :xs="24" :sm="16" :xl="12">-->
|
|
||||||
<el-col :xs="0" :sm="0" :xl="0">
|
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
v-model="state"
|
v-model="queryString"
|
||||||
size="small"
|
size="small"
|
||||||
|
value-key="label"
|
||||||
:fetch-suggestions="querySearchAsync"
|
:fetch-suggestions="querySearchAsync"
|
||||||
placeholder="搜索帖子、标签和用户"
|
placeholder="搜索帖子、作品集和用户"
|
||||||
:trigger-on-focus="false"
|
:trigger-on-focus="false"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
/>
|
style="width: 80%;"
|
||||||
|
popper-class="search-result-box"
|
||||||
|
>
|
||||||
|
<template slot-scope="{ item }">
|
||||||
|
<el-col>
|
||||||
|
<span class="search-result-type">
|
||||||
|
<small class="text-muted" v-html="getSearchResultType(item.type)"></small>
|
||||||
|
</span>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!--<el-col v-if="user" :xs="0" :sm="8" :xl="6">-->
|
</template>
|
||||||
|
<!-- <template slot="append">-->
|
||||||
|
<!-- <el-button size="small" icon="el-icon-search" @click="search"></el-button>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
</el-autocomplete>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="6" :sm="6" :md="6" :xl="3" style="padding-top: 1rem;">
|
||||||
<client-only>
|
<client-only>
|
||||||
<el-col v-if="user" style="text-align: right;">
|
<el-col v-if="user" style="text-align: right;">
|
||||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/portfolio/post">创建作品集
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;"
|
||||||
|
href="/portfolio/post">创建作品集
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;" href="/article/post">发帖
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;"
|
||||||
|
href="/article/post">发帖
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
<el-link rel="nofollow" :underline="false" style="padding-left: 10px;padding-right: 10px;">
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
@ -61,7 +74,9 @@
|
|||||||
:src="avatarURL"></el-avatar>
|
:src="avatarURL"></el-avatar>
|
||||||
<el-avatar class="mr-3" v-else size="small" style="margin-top: 1rem;"
|
<el-avatar class="mr-3" v-else size="small" style="margin-top: 1rem;"
|
||||||
src="https://static.rymcu.com/article/1578475481946.png"></el-avatar>
|
src="https://static.rymcu.com/article/1578475481946.png"></el-avatar>
|
||||||
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">{{ nickname }}</el-link>
|
<el-link rel="nofollow" :underline="false" style="margin-left: 10px;margin-bottom: 1rem;">
|
||||||
|
{{ nickname }}
|
||||||
|
</el-link>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item v-if="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
<el-dropdown-item v-if="hasPermissions" command="admin-dashboard">系统管理</el-dropdown-item>
|
||||||
<el-dropdown-item command="user">个人中心</el-dropdown-item>
|
<el-dropdown-item command="user">个人中心</el-dropdown-item>
|
||||||
@ -88,18 +103,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { isBrowser } from '~/environment'
|
import {mapState} from 'vuex';
|
||||||
|
import {isBrowser} from '~/environment';
|
||||||
|
|
||||||
const Cookie = process.client ? require('js-cookie') : undefined
|
const Cookie = process.client ? require('js-cookie') : undefined
|
||||||
export default {
|
export default {
|
||||||
name: "PcHeader",
|
name: "PcHeader",
|
||||||
computed: {
|
computed: {
|
||||||
getActiveMenu() {
|
...mapState({
|
||||||
return this.$store.state.activeMenu;
|
activeMenu: state => state.activeMenu,
|
||||||
},
|
user: state => state.oauth,
|
||||||
user() {
|
initialSearchData: state => state.search.list
|
||||||
return this.$store.state.oauth;
|
}),
|
||||||
},
|
|
||||||
avatarURL() {
|
avatarURL() {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
@ -130,8 +145,7 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
restaurants: [],
|
queryString: '',
|
||||||
state: '',
|
|
||||||
timeout: null,
|
timeout: null,
|
||||||
show: false,
|
show: false,
|
||||||
notifications: [],
|
notifications: [],
|
||||||
@ -144,16 +158,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadAll() {
|
|
||||||
return [
|
|
||||||
{"value": "三全鲜食(北新泾店)", "address": "长宁区新渔路144号"},
|
|
||||||
{"value": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号"},
|
|
||||||
{"value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
querySearchAsync(queryString, cb) {
|
querySearchAsync(queryString, cb) {
|
||||||
let restaurants = this.restaurants;
|
let initialSearchData = this.initialSearchData;
|
||||||
let results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants;
|
let results = queryString ? initialSearchData.filter(this.createStateFilter(queryString)) : initialSearchData;
|
||||||
|
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = setTimeout(() => {
|
this.timeout = setTimeout(() => {
|
||||||
@ -162,7 +169,9 @@
|
|||||||
},
|
},
|
||||||
createStateFilter(queryString) {
|
createStateFilter(queryString) {
|
||||||
return (state) => {
|
return (state) => {
|
||||||
return (state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
if (state && state.label) {
|
||||||
|
return (state.label.toLowerCase().indexOf(queryString.toLowerCase()) > -1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleSelectMenu(item) {
|
handleSelectMenu(item) {
|
||||||
@ -189,7 +198,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSelect(item) {
|
handleSelect(item) {
|
||||||
console.log(item)
|
console.log(item);
|
||||||
|
let _ts = this;
|
||||||
|
if (item) {
|
||||||
|
_ts.$router.push({
|
||||||
|
path: `/${item.type}/${item.value}`
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleCommand(item) {
|
handleCommand(item) {
|
||||||
let _ts = this;
|
let _ts = this;
|
||||||
@ -225,10 +240,26 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
console.log(this.queryString)
|
||||||
|
},
|
||||||
|
getSearchResultType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'article':
|
||||||
|
type = '文章';
|
||||||
|
break;
|
||||||
|
case 'portfolio':
|
||||||
|
type = '作品集';
|
||||||
|
break;
|
||||||
|
case 'user':
|
||||||
|
type = '用户';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// this.restaurants = this.loadAll();
|
|
||||||
let user = this.user;
|
let user = this.user;
|
||||||
if (user) {
|
if (user) {
|
||||||
this.getUnreadNotifications();
|
this.getUnreadNotifications();
|
||||||
@ -256,4 +287,12 @@
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-result-box {
|
||||||
|
min-width: 20vw !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-type {
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -136,6 +136,9 @@
|
|||||||
currentChangeArticle(page) {
|
currentChangeArticle(page) {
|
||||||
this.$store.dispatch('portfolio/fetchArticleList', {page: page, portfolio_id: this.routePortfolioId})
|
this.$store.dispatch('portfolio/fetchArticleList', {page: page, portfolio_id: this.routePortfolioId})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.commit('setActiveMenu', 'portfolioDetail');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Element from 'element-ui'
|
import Element from 'element-ui'
|
||||||
import locale from 'element-ui/lib/locale/lang/zh-CN'
|
import language from 'element-ui/lib/locale/lang/zh-CN'
|
||||||
|
|
||||||
Vue.use(Element, { locale })
|
Vue.use(Element, { language })
|
||||||
|
@ -4,7 +4,7 @@ export const state = () => ({
|
|||||||
// ua
|
// ua
|
||||||
userAgent: '',
|
userAgent: '',
|
||||||
// 默认语言
|
// 默认语言
|
||||||
language: '',
|
language: 'zh-CN',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { isServer } from '~/environment'
|
import { isServer } from '~/environment'
|
||||||
|
|
||||||
const cookieparser = process.server ? require('cookieparser') : undefined
|
const cookieParser = isServer ? require('cookieparser') : undefined
|
||||||
|
|
||||||
export const state = () => {
|
export const state = () => {
|
||||||
return {
|
return {
|
||||||
@ -52,7 +52,7 @@ export const actions = {
|
|||||||
android: userAgent.indexOf('Android') > -1 || userAgent.indexOf('Linux') > -1, //android终端或uc浏览器
|
android: userAgent.indexOf('Android') > -1 || userAgent.indexOf('Linux') > -1, //android终端或uc浏览器
|
||||||
iPhone: userAgent.indexOf('iPhone') > -1, //是否为iPhone或者QQHD浏览器
|
iPhone: userAgent.indexOf('iPhone') > -1, //是否为iPhone或者QQHD浏览器
|
||||||
iPad: userAgent.indexOf('iPad') > -1, //是否iPad
|
iPad: userAgent.indexOf('iPad') > -1, //是否iPad
|
||||||
webApp: userAgent.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部
|
webApp: userAgent.indexOf('Safari') == -1 //是否web应用程序,没有头部与底部
|
||||||
};
|
};
|
||||||
} ()
|
} ()
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ export const actions = {
|
|||||||
}
|
}
|
||||||
let auth = null
|
let auth = null
|
||||||
if (req.headers.cookie) {
|
if (req.headers.cookie) {
|
||||||
const parsed = cookieparser.parse(req.headers.cookie)
|
const parsed = cookieParser.parse(req.headers.cookie)
|
||||||
try {
|
try {
|
||||||
auth = JSON.parse(parsed.auth)
|
auth = JSON.parse(parsed.auth)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -75,7 +75,8 @@ export const actions = {
|
|||||||
const initFetchAppData = [
|
const initFetchAppData = [
|
||||||
// 内容数据
|
// 内容数据
|
||||||
store.dispatch('topic/fetchNavList'),
|
store.dispatch('topic/fetchNavList'),
|
||||||
store.dispatch('article/fetchList')
|
store.dispatch('article/fetchList'),
|
||||||
|
store.dispatch('search/fetchList'),
|
||||||
]
|
]
|
||||||
|
|
||||||
return Promise.all(initFetchAppData)
|
return Promise.all(initFetchAppData)
|
||||||
|
38
store/search.js
Normal file
38
store/search.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
export const BASE_API_PATH = '/api/console';
|
||||||
|
|
||||||
|
export const state = () => {
|
||||||
|
return {
|
||||||
|
fetching: false,
|
||||||
|
list: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
// 数据列表
|
||||||
|
updateListFetching(state, action) {
|
||||||
|
state.fetching = action
|
||||||
|
},
|
||||||
|
updateListData(state, action) {
|
||||||
|
state.list = action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
// 获取文章列表
|
||||||
|
fetchList({commit}, params = {}) {
|
||||||
|
// 清空已有数据
|
||||||
|
commit('updateListData', []);
|
||||||
|
commit('updateListFetching', true);
|
||||||
|
|
||||||
|
return this.$axios
|
||||||
|
.$get(`${BASE_API_PATH}/initial-search`)
|
||||||
|
.then(response => {
|
||||||
|
commit('updateListFetching', false);
|
||||||
|
commit('updateListData', response);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
commit('updateListFetching', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user