• 背景。小程序开发,需要通过城市关联获取数据。所以选择城市是必经之路。点击打开城市列表。需要实现的是可以
    1. 搜索。
    2. 可以通过右侧字母索引查看。
  • 这其中比较繁琐的就是在搜索的时候遮罩的显示和隐藏。以及查询出结果是,如果结果为空或者有值该怎样显示的情况。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
  • 下面是具体代码
    1. 需要注意的是。在遮罩层的显示和隐藏方面需要用到z-index来处理图层。
    2. 如输入框要在遮罩层上方。遮罩层要是半透明。以及未查询到结果也需要正常显示。其中他们有时需要同时显示。有时却需要互斥,不能同时显示。
<template>
  <view class="container">
    <view class="search-box" style="position: relative; z-index: 10001">
      <uni-easyinput
        type="text"
        placeholder="请输入城市名称"
        v-model="searchKeyword"
        @input="filterCities"
        @focus="onSearch = true"
        @blur="handleBlur"
        style="position: relative" />
    </view>
    <view v-if="maskShow" class="overlay" @click="onSearch = false"></view>

    <u-index-list v-if="indexSearchShow" :scrollTop="scrollTop" :index-list="['A', 'B']">
      <view v-for="(item, index) in indexList" :key="index" @click="handleClick(item)">
        <u-index-anchor :index="item.index" />
        <view class="list-cell">{{ item.cityName }} </view>
      </view>
    </u-index-list>
    <uni-list v-if="searchResShow" class="panelCustom">
      <uni-list-item
        v-for="(item, index) in searchDataList"
        :key="index"
        :title="item.cityName"
        :clickable="true"
        @click="handleSearchClick(item)" />
    </uni-list>
    <view v-if="noSearchResShow" style="text-align: center; margin-top: 20rpx; display: block">
      <text>未查询到结果</text>
    </view>
  </view>
</template>
<script>
export default {
  data() {
    return {
      scrollTop: 0,
      indexList: [
        { index: 'A', cityCode: '110000', cityName: '北京市' },
        { index: 'B', cityCode: '310000', cityName: '上海市' }
      ],
      // 输入框:是否正在查询
      onSearch: false,
      // 输入框:搜索查询结果
      searchDataList: [],
      // 输入框:搜索的关键字
      searchKeyword: ''
    };
  },
  computed: {
    // 索引:是否展示搜索结果面板
    indexSearchShow() {
      return this.maskShow || !this.onSearch;
    },
    // 定义遮罩显示变量
    maskShow() {
      return this.onSearch && !this.noSearchResShow && !this.searchResShow;
    },

    // 未查询结果面板:未查询到结果
    noSearchResShow() {
      return this.onSearch && !this.searchResShow && this.searchKeyword !== '';
    },
    // 输入框:是否展示搜索结果面板
    searchResShow() {
      return this.onSearch && this.searchDataList.length > 0;
    }
  },
  onPageScroll(e) {
    this.scrollTop = e.scrollTop;
  },
  methods: {
    /** 索引:选择结果 */
    handleClick(e) {
      uni.navigateBack({ url: './detail?cityCode=' + e.cityCode + '&cityName=' + e.cityName });
      uni.$emit('update', { cityCode: e.cityCode, cityName: e.cityName });
    },
    // 输入框:搜索
    filterCities(val) {
      if (val === '') {
        this.searchDataList = [];
        return;
      }
      this.$u.post('/api/miniWechat/resource/hospital/findHospitalRegion', { cityName: val }).then((res) => {
        console.log('filterCities.post:', res);
        if (res.code === 200) {
          this.searchDataList = res.data ? res.data : [];
        } else {
          this.searchDataList = [];
        }
      });
      console.log('filterCities:', val);
    },
    /** 输入框:点击选择结果 */
    handleSearchClick(e) {
      console.log('handleSearchClick:', e);
      this.handleClick(e);
    },
    /** 输入框:失去焦点 */
    handleBlur() {
      if (this.searchKeyword === '') {
        this.onSearch = false;
      }
    }
  }
};
</script>
<style scoped>
.list-cell {
  display: flex;
  box-sizing: border-box;
  width: 100%;
  padding: 10px 24rpx;
  overflow: hidden;
  color: #323233;
  font-size: 14px;
  line-height: 24px;
  background-color: #fff;
}
.container {
  padding: 20rpx;
}
/* 半透明遮罩层 */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.1);
  z-index: 9998;
}
.overlay_list {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: write;
  z-index: 9998;
}
.search-input {
  height: 80rpx;
  padding: 0 24rpx;
  font-size: 28rpx;
  background-color: #fff;
  z-index: 10001;
}
.panelCustom {
  z-index: 10000;
}
</style>

  • 总结。
    1. 参照现有样板制作,虽然不能百分百相同。但能学到他们的设计思路。以及在开发时处理问题时并进行学习。
    2. 这次对computed有四个计算属性的应用。逐渐发现computed和watch之间在使用上亲身理解之间的差别。我也许说的不对,但说一下。从应用情况角度来说,computed时将计算结果用于变量,比如说我定义了计算属性A,当B和C有变化时会作用于A, 此时A就自动计算,不用认为参与。那么watch就是要监听某个属性。自我感觉没有computed灵活。但watch是实时的,能做的业务逻辑就比computed要多了,因为computed是会缓存数据的。
    3. 页面之间的数据传递这里面用到了事件的通知。uni.nagitiveTo可以通过url传参。但是uni.nagitiveBack却不行。需要使用this.on和this.on和this.onthis.emit进行事件的注册和通知。但是在者之间会发现this在要回退的页面中已经无法获取了。所以需要通过另外的方式来处理。通过getCurrentPages().pop()获取到页面,并使用此变量进行数据的赋值。这部分会单独记录。
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐