vant封装城市/联系人等选择器


封装成组件

<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;

 

 

演示效果


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM