【筆記】實戰mpvue2.0多端小程序框架——搜索模塊(上)


搜索開發 | 「小慕讀書」官網


一、搜索視覺稿

http://www.youbaobao.xyz/mpvue-design/preview/#artboard1

二、搜索頁面組件結構圖

search

三、標籤組件

可交互的標籤組件 tag

組件名稱 屬性 參數 用途 默認值
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.vueonSearchBarClick事件添加路由跳轉:

onSearchBarClick() {
  this.$router.push('/pages/search/main')
},

4.新建src\pages\search\main.json

{
  "navigationBarTitleText": "搜索"
}

四、標籤分組組件

標籤分組組件,包含一個標題和按鈕,以及標籤分組 tag_group

組件名稱 屬性 參數 用途 默認值
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.效果

在這裏插入圖片描述

五、搜索分類組件

搜索列表中的分類組件 component_search_item

組件名稱 屬性 參數 用途 默認值
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="類別"/>

六、搜索列表組件

搜索結果列表組件

component_search_table

組件名稱 屬性 參數 用途 默認值
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.效果

在這裏插入圖片描述

七、綜合搜索列表組件

包含分類和列表的綜合搜索列表
component_search_list

組件名稱 屬性 參數 用途 默認值
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>

4.效果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章