feat:添加搜索页面

master
ewall 5 years ago
parent 821723d51b
commit d2f1f416e6

@ -1,7 +1,9 @@
import Vue from 'vue'
import ImagePic from './ImagePic'
import BackTop from './BackTop'
import NavBar from './NavBar'
// 注册一些常用的组件到全局
Vue.component('image-pic', ImagePic)
Vue.component('back-top', BackTop)
Vue.component('nav-bar', NavBar)

@ -7,7 +7,7 @@ const whiteList = ['/login'] // 白名单
router.beforeEach(async (to, from, next) => {
// 设置标题
document.title = 'panda-mall'
document.title = to.meta.title || 'panda-mall'
// 根据token判断用户是否登录
const hasToken = getToken()

@ -12,6 +12,7 @@ const routes = [
// webpackPreloadhttps://www.jianshu.com/p/bbdcfeee7fbc
component: () => import(/* webpackPreload: true */ '@/views/home'),
meta: {
title: '首页',
showTab: true,
keepAlive: true
}
@ -20,7 +21,10 @@ const routes = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/auth/login')
component: () => import('@/views/auth/login'),
meta: {
title: '登录'
}
},
// 分类
{
@ -28,6 +32,7 @@ const routes = [
name: 'Category',
component: () => import('@/views/category'),
meta: {
title: '分类',
showTab: true
}
},
@ -35,7 +40,11 @@ const routes = [
{
path: '/cart',
name: 'Cart',
component: () => import('@/views/cart')
component: () => import('@/views/cart'),
meta: {
title: '购物车',
showTab: true
}
},
// 我的
{
@ -43,6 +52,7 @@ const routes = [
name: 'User',
component: () => import('@/views/user'),
meta: {
title: '我的',
showTab: true
}
},
@ -52,6 +62,7 @@ const routes = [
name: 'Product',
component: () => import('@/views/product'),
meta: {
title: '商品列表',
keepAlive: true
}
},
@ -61,6 +72,7 @@ const routes = [
name: 'Detail',
component: () => import('@/views/detail'),
meta: {
title: '商品详情',
keepAlive: true
}
},
@ -68,13 +80,38 @@ const routes = [
{
path: '/address',
name: 'Address',
component: () => import('@/views/address')
component: () => import('@/views/address'),
meta: {
title: '地址管理'
}
},
// 地址编辑
{
path: '/address/edit',
name: 'AddressEdit',
component: () => import('@/views/address/edit')
component: () => import('@/views/address/edit'),
meta: {
title: '地址编辑'
}
},
// 搜索
{
path: '/search',
name: 'Search',
component: () => import('@/views/search'),
meta: {
title: '搜索'
}
},
// 搜索结果列表
{
path: '/search/list',
name: 'SearchList',
component: () => import('@/views/search/list'),
meta: {
title: '搜索结果',
keepAlive: true
}
}
]

@ -4,7 +4,15 @@ const getters = {
name: state => state.user.name,
userInfo: state => state.user.userInfo,
// address
selectedAddress: state => state.address.selectedAddress
selectedAddress: state => state.address.selectedAddress,
// search
searchKey: (state) => {
if (state.search.searchKey.length <= 0) {
return JSON.parse(localStorage.getItem('searchKey')) || []
} else {
return state.search.searchKey
}
}
}
export default getters

@ -0,0 +1,44 @@
const state = {
searchKey: []
}
const mutations = {
SET_KEY(state, keyarr) {
state.searchKey = keyarr
localStorage.setItem('searchKey', JSON.stringify(keyarr.slice(0, 20)))
},
DEL_KEY(state) {
state.searchKey = []
}
}
const actions = {
// 保存搜索词
setKey({ commit, state }, key) {
if (state.searchKey.length <= 0) {
const rlt = JSON.parse(localStorage.getItem('searchKey')) || []
if (rlt.indexOf(key) < 0) {
rlt.unshift(key)
commit('SET_KEY', rlt)
}
} else {
const rlt = [...state.searchKey]
if (rlt.indexOf(key) < 0) {
rlt.unshift(key)
commit('SET_KEY', rlt)
}
}
},
// 删除搜索词
delKey({ commit }) {
localStorage.removeItem('searchKey')
commit('DEL_KEY')
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

@ -2,13 +2,13 @@
<div>
<div class="home-header">
<image-pic width="28px" height="28px" :src="require('@/assets/logo.png')" />
<van-button block class="search" size="small">
<van-button block class="search" size="small" @click="onSearch">
<span style="color:#8e8e8e;margin-right:6px">
<svg-icon icon-class="search" :width="15" :height="15" />
</span>
<span>搜索商品名称</span>
</van-button>
<span style="color:#8e8e8e">
<span style="color:#8e8e8e" @click="onUser">
<svg-icon icon-class="user" :width="18" :height="18" />
</span>
</div>
@ -18,9 +18,20 @@
<script>
export default {
components: {}
methods: {
onSearch() {
this.$router.push({
path: '/search'
})
},
onUser() {
this.$router.push({
path: '/user'
})
}
}
}
</script>
</script>>
<style lang="scss" scoped>
.home-header {

@ -0,0 +1,43 @@
<template>
<div class="search">
<van-search
v-model="value"
placeholder="请输入搜索关键词"
show-action
clearable
autofocus
@search="onSearch"
@cancel="$router.back()"
/>
<search-words @input="onSearch($event)" />
</div>
</template>
<script>
import SearchWords from './modules/Words'
export default {
name: 'Search',
components: {
SearchWords
},
data() {
return {
value: ''
}
},
methods: {
onSearch(value) {
this.$store.dispatch('search/setKey', value)
this.$router.push({
path: '/search/list',
query: {
key: value,
t: +new Date()
}
})
}
}
}
</script>

@ -0,0 +1,15 @@
<template>
<div class="search-list">
11111
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>

@ -0,0 +1,102 @@
<template>
<div class="search-words">
<!-- history -->
<div class="history" v-if="searchKey.length > 0">
<h3 class="history__title">
<p class="history__title__left">
<van-icon name="underway-o" size="16" />
<span class="text">最近搜索</span>
</p>
<p class="history__title__right" @click="onDelete">
<van-icon name="delete" size="16" />
</p>
</h3>
<div class="history__main">
<p
class="history__main__item"
v-for="(item,idx) in searchKey"
:key="idx"
@click="onSearch(item)"
>{{item}}</p>
</div>
</div>
<!-- hot -->
<div class="hot" v-if="true">
<h3 class="hot__title">
<div class="hot__title__left">
<van-icon name="fire-o" size="16" />
<span class="text">热门搜索</span>
</div>
</h3>
<div class="hot__main">
<p class="hot__main__item" v-for="(item,idx) in 10" :key="idx" @click="onSearch(item)"></p>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['searchKey'])
},
methods: {
onDelete() {
this.$dialog
.confirm({
title: '提示',
message: '确定清空所有搜索记录吗?'
})
.then(() => {
this.$store.dispatch('search/delKey')
})
.catch(() => {})
},
onSearch(value) {
this.$emit('input', value)
}
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/variables.scss";
.search-words {
.history,
.hot {
.history__title,
.hot__title {
padding: 24px;
display: flex;
justify-content: space-between;
font-size: $small;
.history__title__left,
.hot__title__left {
display: flex;
align-items: center;
.text {
margin-left: 8px;
}
}
}
.history__main,
.hot__main {
display: flex;
flex-wrap: wrap;
padding: 0 0 0 24px;
.history__main__item,
.hot__main__item {
font-size: $mini;
background: #f5f5f5;
padding: 8px 12px;
color: $gray;
border-radius: 6px;
margin: 0 24px 24px 0;
}
}
}
}
</style>
Loading…
Cancel
Save