文章目錄
一、搜索視覺稿
http://www.youbaobao.xyz/mpvue-design/preview/#artboard1
二、搜索頁面組件結構圖
三、標籤組件
可交互的標籤組件
組件名稱 | 屬性 | 參數 | 用途 | 默認值 |
---|---|---|---|---|
Tag | props | text | 標籤文本 | (空) |
methods | onClick | 標籤點擊事件 | (空) |
1.新建src\components\base\Tag.vue
<template>
<div class="tag-wrapper" @click="onClick">
<div class="tag">{{text}}</div>
</div>
</template>
<script>
export default {
props: {
text: {
type: String,
default: ''
}
},
methods: {
onClick() {
this.$emit('onClick')
}
}
}
</script>
<style lang="scss" scoped>
.tag-wrapper {
display: flex;
justify-content: center;
background: #F7F7F9;
border-radius: 16px;
padding: 6px 17px;
.tag {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 14px;
color: #272E37;
}
}
</style>
2.新建src\pages\search\main.js
import Vue from 'vue'
import App from './search'
const app = new Vue(App)
app.$mount()
3.新建src\pages\search\search.vue
<template>
<div>
</div>
</template>
<script>
export default {
components: {
},
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>
修改src\components\home\SearchBar.vue
的如下部分(添加點擊事件):
<div class="search-bar-wrapper" @click="onSearchBarClick">
爲src\pages\index\index.vue
的onSearchBarClick
事件添加路由跳轉:
onSearchBarClick() {
this.$router.push('/pages/search/main')
},
4.新建src\pages\search\main.json
{
"navigationBarTitleText": "搜索"
}
四、標籤分組組件
標籤分組組件,包含一個標題和按鈕,以及標籤分組
組件名稱 | 屬性 | 參數 | 用途 | 默認值 |
---|---|---|---|---|
TagGroup | props | headerText | 標題文本 | (空) |
btnText | 按鈕文本 | (空) | ||
value | 標籤數據 | [] | ||
methods | onTagClick | 標籤點擊事件 | (空) | |
onBtnClick | 按鈕點擊事件 | (空) |
1.新建src\components\base\TagGroup.vue
<template>
<div class="tag-group-wrapper">
<div class="tag-group-header">
<div class="header-text">{{headerText}}</div>
<div class="header-btn" @click="onBtnClick">{{btnText}}</div>
</div>
<div class="tag-goup">
<div class="tag-group-inner" v-for="(text, index) in value" :key="index">
<Tag :text="text" @onClick="onTagClick(text, index)"/>
</div>
</div>
</div>
</template>
<script>
import Tag from './Tag'
export default {
components: {Tag},
props: {
headerText: String,
btnText: String,
value: Array
},
methods: {
onTagClick(text, index) {
this.$emit('onTagClick', text, index)
},
onBtnClick() {
this.$emit('onBtnClick')
}
}
}
</script>
<style lang="scss" scoped>
.tag-group-wrapper {
.tag-group-header {
display: flex;
justify-content: space-between;
padding: 0 16px;
font-size: 14px;
line-height: 20px;
.header-text {
color: #333333;
}
.header-btn {
color: #3696EF;
}
}
.tag-goup {
display: flex;
flex-flow: row wrap;
padding: 4px 10px 0 10px;
.tag-group-inner {
padding: 12px 6px 0 6px;
}
}
}
</style>
2.在src\pages\search\search.vue中引入TagGroup
<template>
<div>
<TagGroup
:value="tags"
header-text="熱門搜索"
btn-text="換一批"
@onTagClick="onTagClick"
@onBtnClick="onBtnClick"
/>
</div>
</template>
<script>
import TagGroup from '../../components/base/TagGroup'
export default {
components: {
TagGroup
},
data() {
return {
tags: [
'aaaaaa',
'bbbbb',
'c',
'ddddddddddddddddd',
'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
'ffffffffff'
]
}
},
methods: {
onTagClick(text, index) {
console.log('tag...', text, index)
},
onBtnClick() {
console.log('btn...')
}
}
}
</script>
3.效果
五、搜索分類組件
搜索列表中的分類組件
組件名稱 | 屬性 | 參數 | 用途 | 默認值 |
---|---|---|---|---|
SearchItem | props | title | 標題文本 | (空) |
subTitle | 副標題文本 | (空) | ||
icon | 圖標類型 | (空) | ||
methods | onClick | 分類點擊事件 | (空) |
1.新建src\components\search\SearchItem.vue
<template>
<div class="search-item-wrapper" @click="onClick">
<div class="search-item-icon">
<div class="icon-wrapper">
<van-icon name="apps-o" color="#777777" :style="{ width:'20px', height:'20px' }" />
</div>
</div>
<div class="search-item-info">
<div class="search-item-title">{{title}}</div>
<div class="search-item-sub-title">{{subTitle}}</div>
</div>
</div>
</template>
<script>
export default {
props: {
title: String,
subTitle: String,
icon: String
},
methods: {
onClick() {
this.$emit('onClick')
}
}
}
</script>
<style lang="scss" scoped>
.search-item-wrapper {
display: flex;
align-items: center;
padding: 15px;
height: 36.5px;
.search-item-icon {
.icon-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
border-radius: 50%;
background: #F7F7F9;
}
}
.search-item-info {
margin-left: 10px;
.search-item-title {
color: #333333;
font-size: 14px;
line-height: 20px;
}
.search-item-sub-title {
color: #777777;
font-size: 12px;
line-height: 16.5px;
}
}
}
</style>
2.在src\pages\search\search.vue中引入
<SearchItem icon="apps-o" title="計算機科學" sub-title="類別"/>
六、搜索列表組件
搜索結果列表組件
組件名稱 | 屬性 | 參數 | 用途 | 默認值 |
---|---|---|---|---|
SearchTable | props | data | 列表數據 | [] |
methods | onClick | 圖書點擊事件 | (空) |
1.新建src\components\search\SearchTable.vue
<template>
<div class="search-table-wrapper">
<div class="search-table-inner">
<div class="search-table-book" v-for="(book, index) in data" :key="index" @click="onClick(book)">
<div class="book-img-wrapper">
<div class="book-img">
<ImageView :src="book.cover"/>
</div>
</div>
<div class="book-info-wrapper">
<div class="book-title">{{book.title}}</div>
<div class="book-author">{{book.author}}</div>
<div class="book-category">{{book.categoryText}}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ImageView from '../base/ImageView'
export default {
components: {ImageView},
props: {
data: Array
},
methods: {
onClick(book) {
this.$emit('onClick', book)
}
}
}
</script>
<style lang="scss" scoped>
.search-table-wrapper {
padding: 0 16px;
.search-table-inner {
.search-table-book {
margin: 14.5px 0;
display: flex;
align-items: center;
.book-img-wrapper {
.book-img {
width: 47px;
height: 68.5px;
}
}
.book-info-wrapper {
width: 80%;
margin-left: 15.5px;
.book-title {
color: #333333;
font-size: 16px;
line-height: 22.5px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 500;
}
.book-author {
color: #999999;
font-size: 13px;
line-height: 18px;
margin-top: 5px;
}
.book-category {
color: #777777;
font-size: 13px;
line-height: 18px;
}
}
}
}
}
</style>
2.在src\pages\search\search.vue中引入
<SearchTable :data="list"/>
...
data() {
return {
...
list: [
{
'id': 225,
'fileName': '2016_Book_MicrofinanceEUStructuralFundsA',
'cover': 'https://www.youbaobao.xyz/book/res/img/Economics/2016_Book_MicrofinanceEUStructuralFundsA.jpeg',
'title': 'Microfinance, EU Structural Funds and Capacity Building for Managing Authorities',
'author': 'Giovanni Nicola Pes',
'publisher': 'Palgrave Macmillan',
'bookId': '2016_Book_MicrofinanceEUStructuralFundsA',
'category': 3,
'categoryText': 'Economics',
'language': 'en',
'rootFile': 'OEBPS/9781137536013.opf'
},
{
'id': 88,
'fileName': '2018_Book_BetweenMobilityAndMigration',
'cover': 'https://www.youbaobao.xyz/book/res/img/SocialSciences/978-3-319-77991-1_CoverFigure.jpg',
'title': 'Between Mobility and Migration',
'author': 'Peter Scholten',
'publisher': 'Springer International Publishing',
'bookId': '2018_Book_BetweenMobilityAndMigration',
'category': 2,
'categoryText': 'SocialSciences',
'language': 'en',
'rootFile': 'OEBPS/package.opf'
},
{
'id': 225,
'fileName': '2016_Book_MicrofinanceEUStructuralFundsA',
'cover': 'https://www.youbaobao.xyz/book/res/img/Economics/2016_Book_MicrofinanceEUStructuralFundsA.jpeg',
'title': 'Microfinance, EU Structural Funds and Capacity Building for Managing Authorities',
'author': 'Giovanni Nicola Pes',
'publisher': 'Palgrave Macmillan',
'bookId': '2016_Book_MicrofinanceEUStructuralFundsA',
'category': 3,
'categoryText': 'Economics',
'language': 'en',
'rootFile': 'OEBPS/9781137536013.opf'
},
{
'id': 88,
'fileName': '2018_Book_BetweenMobilityAndMigration',
'cover': 'https://www.youbaobao.xyz/book/res/img/SocialSciences/978-3-319-77991-1_CoverFigure.jpg',
'title': 'Between Mobility and Migration',
'author': 'Peter Scholten',
'publisher': 'Springer International Publishing',
'bookId': '2018_Book_BetweenMobilityAndMigration',
'category': 2,
'categoryText': 'SocialSciences',
'language': 'en',
'rootFile': 'OEBPS/package.opf'
},
{
'id': 225,
'fileName': '2016_Book_MicrofinanceEUStructuralFundsA',
'cover': 'https://www.youbaobao.xyz/book/res/img/Economics/2016_Book_MicrofinanceEUStructuralFundsA.jpeg',
'title': 'Microfinance, EU Structural Funds and Capacity Building for Managing Authorities',
'author': 'Giovanni Nicola Pes',
'publisher': 'Palgrave Macmillan',
'bookId': '2016_Book_MicrofinanceEUStructuralFundsA',
'category': 3,
'categoryText': 'Economics',
'language': 'en',
'rootFile': 'OEBPS/9781137536013.opf'
},
{
'id': 88,
'fileName': '2018_Book_BetweenMobilityAndMigration',
'cover': 'https://www.youbaobao.xyz/book/res/img/SocialSciences/978-3-319-77991-1_CoverFigure.jpg',
'title': 'Between Mobility and Migration',
'author': 'Peter Scholten',
'publisher': 'Springer International Publishing',
'bookId': '2018_Book_BetweenMobilityAndMigration',
'category': 2,
'categoryText': 'SocialSciences',
'language': 'en',
'rootFile': 'OEBPS/package.opf'
}
]
}
},
3.效果
七、綜合搜索列表組件
包含分類和列表的綜合搜索列表
組件名稱 | 屬性 | 參數 | 用途 | 默認值 |
---|---|---|---|---|
SearchList | props | data | 列表數據 | {} |
methods | showList | 展示分類點擊後的列表 | (空) |
1. 新建src\components\search\SearchList.vue
<template>
<div class="search-list-wrapper">
<SearchTable :data="data"/>
<SearchItem icon="apps-o" title="計算機科學" sub-title="類別"/>
<SearchItem icon="apps-o" title="計算機科學" sub-title="類別"/>
<SearchItem icon="apps-o" title="計算機科學" sub-title="類別"/>
</div>
</template>
<script>
import SearchItem from './SearchItem'
import SearchTable from './SearchTable'
export default {
components: {SearchTable, SearchItem},
props: {
data: Object
},
methods: {
showList() {
},
}
}
</script>
<style lang="scss" scoped>
</style>
2.修改src\pages\search\search.vue
- data中新增:
item: [
{ icon: 'apps-o', title: 'Compute Science', subTitle: 'Category' },
{ icon: 'contact', title: 'Compute Science', subTitle: 'Author' },
{ icon: 'newspaper-o', title: 'Compute Science', subTitle: 'Publisher' }
],
- 通過computed將data整合爲一個參數對象
computed: {
data() {
return {
item: this.item,
list: this.list
}
}
},
- 去掉SearchTable和SearchItem,替換爲SearchList
<SearchList :data="data"/>
3.修改src\components\search\SearchList.vue
在src\components\search\SearchList.vue中使用計算屬性動態拿到傳過來的數據:
computed: {
categroy() {
return this.data.item[0]
},
author() {
return this.data.item[1]
},
publisher() {
return this.data.item[2]
}
},
- 在頁面部分綁定數據:
<SearchItem
:icon="categroy.icon"
:title="categroy.title"
:sub-title="categroy.subTitle"
@onClick="showList(categroy.title, 'categroy')"
/>
<SearchItem
:icon="author.icon"
:title="author.title"
:sub-title="author.subTitle"
@onClick="showList(author.title, 'author')"
/>
<SearchItem
:icon="publisher.icon"
:title="publisher.title"
:sub-title="publisher.subTitle"
@onClick="showList(publisher.title, 'publisher')"
/>
<SearchTable :data="data.list" @onClick="onBookClick"/>
- 文件完整內容如下:
<template>
<div class="search-list-wrapper">
<SearchItem
:icon="categroy.icon"
:title="categroy.title"
:sub-title="categroy.subTitle"
@onClick="showList(categroy.title, 'categroy')"
/>
<SearchItem
:icon="author.icon"
:title="author.title"
:sub-title="author.subTitle"
@onClick="showList(author.title, 'author')"
/>
<SearchItem
:icon="publisher.icon"
:title="publisher.title"
:sub-title="publisher.subTitle"
@onClick="showList(publisher.title, 'publisher')"
/>
<SearchTable :data="data.list" @onClick="onBookClick"/>
</div>
</template>
<script>
import SearchItem from './SearchItem'
import SearchTable from './SearchTable'
export default {
components: {SearchTable, SearchItem},
props: {
data: Object
},
computed: {
categroy() {
return this.data.item[0]
},
author() {
return this.data.item[1]
},
publisher() {
return this.data.item[2]
}
},
methods: {
showList(text, key) {
console.log(text, key)
},
onBookClick(book) {
console.log(book)
}
}
}
</script>
<style lang="scss" scoped>
</style>