封裝成組件
<template> <div class="common-ibar"> <van-search class="search" v-model="searchWord" show-action placeholder="請輸入搜索關鍵詞" @search="getFriend" @cancel="onCancel" /> <div class="content"> <van-index-bar :index-list="indexList"> <van-index-anchor :index="friendGroup.index" :key="friendGroup.index" v-for="friendGroup in handelList"> <span class="indexWord" :key="friendGroup.index">{{friendGroup.index}}</span> <van-cell :title="item.name" v-for="item in friendGroup.item" :key="item.id" @click="clickItem(item)"/> </van-index-anchor> </van-index-bar> </div> </div> </template> <script> // https://segmentfault.com/a/1190000021057413 import pinyin from "js-pinyin"; import _ from "loadsh"; export default { name: "CommonIbar", props:{ list: { type: Array, required: true, default(){ return [] } } }, data() { return { searchWord:'', indexList:[], handelList:[] }; }, methods: { transData(resource) { // 給每個元素添加first標識,用於分組 const copySc = _.cloneDeep(resource); copySc.map( item => (item.first = pinyin.getCamelChars(item.name).substring(0, 1)) ); //根據首字母分組和排序 const groupObj = _.groupBy(copySc, "first"); const groupArr = Object.keys(groupObj).map(key => ({ index: key, item: groupObj[key] })); const orderArr = _.orderBy(groupArr, "index"); return orderArr; }, getFriend(){ this.$emit('search', this.searchWord); }, onCancel(){ this.$emit('update:isOpen', false) }, clickItem(item){ this.$emit('update:isOpen', false); this.$emit('clickItem', item); } }, watch:{ list:{ handler(newVal) { this.handelList = this.transData(newVal); this.indexList = this.handelList.map(item=>item.index) }, deep: true, immediate: true } } }; </script> <style scoped> .common-ibar{ height: 100vh; } .content{ padding-top: 60px; } .search { position: fixed; z-index: 2; width: 100vw; box-shadow: 1px 1px 1px #eeeeee; } </style>
頁面使用
<template> <div id="app"> <CommonIbar :list="friends" @search="friendSearch" v-if="show" :isOpen.sync="show" @clickItem="clickItem" /> <div class="main" v-else> 請選擇: <div @click="pleaseCheck" class="check">{{current?current:'尚未選擇'}}</div> </div> </div> </template> <script> import CommonIbar from "./components/common-ibar.vue"; export default { name: "App", components: { CommonIbar }, data() { return { show: false, friends: [], current: "" }; }, methods: { async getFriend() { // const { // data: { data } // } = await this.$axios.post("/getFriend"); // this.friends = data; this.friends = [ { id: "3f11aF98-b74e-B5fe-EeDE-4c6e53eb65fb", name: "陳秀英" }, { id: "DdaFf43F-d522-1A3e-Cd9C-DF8CCec8A7Fc", name: "賈麗" }, { id: "89Bac92E-B47C-Aa1A-693F-5F45b27CC75F", name: "鄭艷" }, { id: "57865Ea9-7cAb-dCAA-4F3c-9B09fFCEF00e", name: "蔣霞" }, { id: "8A5a1EdF-7B0C-21ce-f58D-Af4Cb9F7defB", name: "謝靜" }, { id: "2e6934ca-e75B-8829-8F33-5C13F0E907B9", name: "程麗" }, { id: "208E3565-fdeb-1Df5-eCAB-e6FCBDA379dF", name: "龔娟" }, { id: "3D37F5Fe-8B3E-44dF-E1E3-65eD3f9fDDeB", name: "姜濤" }, { id: "1c6aB133-bAA3-E3fA-6BC5-3986A1fd9d0D", name: "易秀蘭" }, { id: "DbbCCB22-C536-beCB-6c6E-3550FE48DBcb", name: "陸娜" }, { id: "eB3CeCCa-7D69-E3cE-bC9e-B69b09Acce9A", name: "孔麗" }, { id: "9fBca359-BEcF-AeF6-9d28-6787bdEb299B", name: "周娟" }, { id: "fEbB8eFB-98EA-E2F4-96Ea-6FB9F4fE1bCd", name: "宋秀英" }, { id: "Fabd5A46-a6e9-B4E6-Abfd-6E926CE8b3BF", name: "余桂英" }, { id: "81CcbCdc-64bf-f95C-8582-3668B8fD8Ece", name: "戴秀英" }, { id: "DBD27e5A-CFD5-c69A-9823-5C2af59fdb5b", name: "葉秀蘭" }, { id: "BeAb3dA2-DEAC-19C4-eA8D-Db0cdDC0960F", name: "賈敏" }, { id: "dE53eD1E-Ddd2-945C-Dc2D-B1Ef8DE32Ebe", name: "鍾敏" }, { id: "2Eed58b6-01e3-CaCf-BEEF-40BFf89FDFDA", name: "徐芳" }, { id: "387dfdAe-81B1-6CBE-aBE6-bbc88186EeCb", name: "蘇麗" }, { id: "1dD6d169-1A03-C2Fd-b2C9-CaCC21cA7FdD", name: "易艷" }, { id: "c9801191-5EeD-bcbA-ec92-Ee13Ae9Ecc2B", name: "傅傑" }, { id: "EDe98edd-6Cb1-DB38-B5bB-486bDB64F2eB", name: "喬強" }, { id: "CA437477-51fA-Fdd8-Be3A-0e59cDF60B3C", name: "於傑" }, { id: "5cdDB69B-1ec8-d4Bf-AeBb-Fe1Aa4De2Bf2", name: "汪磊" } ]; }, friendSearch() { this.getFriend(); }, pleaseCheck() { this.show = true; }, clickItem(item) { this.current = item.name; } }, created() { this.getFriend(); } }; </script> <style> html, body { margin: 0; padding: 0; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } .main { height: 100vh; background: pink; padding-top: 60px; padding-left: 40px; } .check{ display: inline-block; border: red solid 1px; width: 100px; } </style>
mock的假數據
這個不重要,可以沒有
import Mock from 'mockjs'
Mock.mock('/getFriend', 'post', {
code: 200,
'data|20-30': [{
"id": "@guid",
"name": "@cname",
}]
});
export default Mock;
演示效果