zoukankan      html  css  js  c++  java
  • 仿美团pc,koa+ssr(四)

    一,城市服务功能

    components-->新建changeCity目录--》新建isselect.vue组件

     

    <template>
      <div class="m-iselect">
        <span class="name">按省份选择:</span>
        <el-select
          v-model="pvalue"
          placeholder="省份">
          <el-option
            v-for="item in province"
            :key="item.value"
            :label="item.label"
            :value="item.value"/>
        </el-select>
        <el-select
          v-model="cvalue"
          :disabled="!city.length"
          placeholder="城市">
          <el-option
            v-for="item in city"
            :key="item.value"
            :label="item.label"
            :value="item.value"/>
        </el-select>
        <el-autocomplete
          v-model="input"
          :fetch-suggestions="querySearchAsync"
          placeholder="请输入城市中文或拼音"
          @select="handleSelect"
        />
      </div>
    </template>
    
    <script>
    import _ from 'lodash';
    export default {
      data(){
        return {
          province:[],
          pvalue:'',
          city:[],
          cvalue:'',
          input:'',
          // 全国城市
          cities:[]
        }
      },
      watch:{
        // 省份数据改变,立刻获取对应的市级数据
        pvalue:async function(newPvalue){
          let self=this;
          let {status,data:{city}}=await self.$axios.get(`/geo/province/${newPvalue}`)
          if(status===200){
            self.city=city.map(item=>{
              return {
                value:item.id,
                label:item.name
              }
            })
            self.cvalue=''
          }
        }
      },
      // 刚加载页面,把所有的省份数据获取
      mounted:async function(){
        let self=this;
        let {status,data:{province}}=await self.$axios.get('/geo/province')
        if(status===200){
          self.province=province.map(item=>{
            return {
              value:item.id,
              label:item.name
            }
          })
        }
      },
      methods:{
        // 远端搜索,只要输入关键字,触发该函数,防抖优化,query为输入的关键字
        querySearchAsync:_.debounce(async function(query,cb){
          let self=this;
          if(self.cities.length){
            // cb回调函数,搜索符合条件的城市
            cb(self.cities.filter(item => item.value.indexOf(query)>-1))
          }else{
            // 没有全国城市数据,请求接口获取
            let {status,data:{city}}=await self.$axios.get('/geo/city')
            if(status===200){
              self.cities=city.map(item=>{return {
                value:item.name
              }})
              cb(self.cities.filter(item => item.value.indexOf(query)>-1))
            }else{
              cb([])
            }
          }
        },200),
        // 选中城市触发
        handleSelect:function(item){
          console.log(item.value);
        }
      }
    }
    </script>
    
    <style lang="scss">
      @import "@/assets/css/changeCity/iselect.scss";
    </style>

    components-->新建changeCity目录--》新建hot.vue热门城市组件

    <template>
      <div class="m-hcity">
        <dl>
          <dt>热门城市:</dt>
          <dd
            v-for="item in list"
            :key="item.id">{{ item.name==='市辖区'?item.province:item.name }}</dd>
        </dl>
      </div>
    </template>
    
    <script>
    export default {
      data(){
        return {
          list:[]
        }
      },
      async mounted(){
        let {status,data:{hots}}=await this.$axios.get('/geo/hotCity')
        if(status===200){
          this.list=hots
        }
      }
    }
    </script>
    
    <style lang="scss">
      @import "@/assets/css/changeCity/hot.scss";
    </style>

    components-->新建changeCity目录--》新建categrory.vue排序城市组件

    注,用很少的dom节点完成,多看看,

    还有用了一个pinyin库,拼音code值

    根据a标签的瞄点,跳转到固定位置

    <template>
      <div class="">
        <dl class="m-categroy">
          <dt>按拼音首字母选择:</dt>
          <dd
            v-for="item in list"
            :key="item">
            <a :href="'#city-'+item">{{ item }}</a>
          </dd>
        </dl>
        <dl
          v-for="item in block"
          :key="item.title"
          class="m-categroy-section">
          <dt :id="'city-'+item.title">{{ item.title }}</dt>
          <dd>
            <span
              v-for="c in item.city"
              :key="c">{{ c }}</span>
          </dd>
        </dl>
      </div>
    </template>
    
    <script>
    import pyjs from 'js-pinyin'
    export default {
      data(){
        return {
          list:'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),
          // 每个对象包含拼音以及对应的数组
          block:[]
        }
      },
      async mounted(){
        let self=this;
        let blocks=[]
        let {status,data:{city}}=await self.$axios.get('/geo/city');
        if(status===200){
          let p
          let c
          let d={}
          city.forEach(item=>{
            // 将汉语转化拼音,并截取首字母
            p=pyjs.getFullChars(item.name).toLocaleLowerCase().slice(0,1)
            // 获取字母的code值
            c=p.charCodeAt(0)
            // 小写a-z
            if(c>96&&c<123){ 
              if(!d[p]){
                d[p]=[]
              }
              // 每个拼音对应的数组
              d[p].push(item.name)
            }
          })
          // Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组
          for(let [k,v] of Object.entries(d)){
            blocks.push({
              title:k.toUpperCase(),
              city:v
            })
          }
          // 字母排序
          blocks.sort((a,b)=>a.title.charCodeAt(0)-b.title.charCodeAt(0))
          self.block=blocks
        }
      }
    }
    </script>
    
    <style lang="scss">
      @import "@/assets/css/changeCity/categroy.scss";
    </style>

     

     pages-->changeCity.vue组件,将hot,isselsect,categrory组件全部导入该组件

    默认引入了公共组件layout-->default.vue,<nuxt/>相当于一个slot插槽,将changeCity的结构插入进去

    <template>
      <el-container class="layout-default">
        <el-header height="197px">
          <my-header/>
        </el-header>
        <el-main>
          <nuxt/>
        </el-main>
        <el-footer height="100%">
          <my-footer/>
        </el-footer>
      </el-container>
    </template>
    
    <script>
      import MyHeader from '@/components/public/header/index.vue'
      import MyFooter from '@/components/public/footer/index.vue'
      export default {
        components:{
          MyHeader,
          MyFooter
        }
      }
    </script>
    <template>
      <div class="page-changeCity">
        <el-row>
          <el-col :span="24">
            <iSelect/>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <hot/>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <categroy/>
          </el-col>
        </el-row>
      </div>
    </template>
    
    <script>
    import iSelect from '@/components/changeCity/iselect.vue'
    import Hot from '@/components/changeCity/hot.vue'
    import Categroy from '@/components/changeCity/categroy.vue'
    export default {
      components:{
        iSelect,
        Hot,
        Categroy
      }
    }
    </script>
    
    <style lang="css">
    </style>
  • 相关阅读:
    前台组件
    IntelliJ IDEA 简体中文专题教程
    干货分享 | 创业公司绝对不会告诉你他们在用的工具们
    线程的基本概念 / 计算机程序的思维逻辑
    Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
    【转载】 准人工智能分享Deep Mind报告 ——AI“元强化学习”
    (待续)【转载】 DeepMind发Nature子刊:通过元强化学习重新理解多巴胺
    【转载】 机器学习算法岗的常见面试问题及准备
    【转载】 180623 Conda install 本地压缩包文件tar.bz2
    2017年 某次 实验室会议 —— 记
  • 原文地址:https://www.cnblogs.com/fsg6/p/14429303.html
Copyright © 2011-2022 走看看