说明

1.上一章--页面图标ico的设置
2.苍渡大神的项目源码--项目地址
3.UI框架--Mint ui
4.数据接口地址--接口地址
5.下一章--组件的使用(svg及watch的简单使用)

开始

1.先看看咱们目前的city样式

2.再来看看咱们需要实现的样式

3.样式
city.vue样式修改如下

<template><div><mt-header :title="$store.state.nowcity.name" class='fs1-2' fixed><mt-button slot="left"><mt-button icon="back"></mt-button></mt-button><mt-button slot="right" class='fs0-8'>切换城市</mt-button></mt-header><div class="mgtop50 padlr10 bgfff padbot10"><input class="cityinput" placeholder="输入商务楼,学校,地址"></input><div class="submit bgcol ih40">提交</div></div><div class="main"><div class="his after"><div class='maintop fs0-8 padlr10'>搜索历史</div><div class="mainbody bgfff "><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="clearall ih30 pad10 col9f">清空所有</div></div></div><div class='search bgfff'> <div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div></div></div></div>
</template><script>export default {data () {return {}},component:{//注册组件},mounted:function(){//生命周期},computed:{//计算属性},methods:{//函数}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.cityinput{width:100%;height:40px;margin:10px 0px;outline:0px;padding:0px 5px;box-sizing:border-box;
}
.submit{text-align:center;color:white;border-radius:3px;
}
.fs0-8{font-size:0.8rem !important;
}.main{border-top:2px solid #E4E4E4;
}
.maintop{ border-bottom:2px solid #E4E4E4;
}
.clearall{text-align:center;
}
</style>

页面显示为

我们先把所有的样式都写出来,然后再来控制显示哪个div

4.点击搜索
4.1当我们在搜索框输入地址后,点击提交,应该弹出所有搜索的地址。所以我们应该设置一个变量inputval来存放输入框的值,一个变量list来存放搜索到的数据。

 data () {return {inputval:"",list:""}}

4.2点击事件。先看数据接口api

先写发送请求函数searchcity(这里我把参数拼接到url上就没错,在url后加个{}来传参数就报 参数错误 ,哪位老铁知道玄机么?)

methods:{//函数searchcity:function(){this.$http.get('http://cangdu.org:8001/v1/pois?city_id='+this.$store.state.nowcity.id+'&keyword='+this.inputval+'&type=search').then(response => {console.log(response);this.list=response.body;}, response => {console.log(response);});}}

this.$store.state.nowcity.id是从vuex里获取当前城市的id,在第八章存入;this.inputval是咱们输入框的值。
然后把点击函数searchcity绑定到元素上

 <div @click="searchcity" class="submit bgcol ih40">提交</div>

运行试试,结果如下

解决,可以看到数据已经请求回来了。

4.3显示
现在我们来控制class='his'(搜索历史的div)和class='search'(搜索结果的div)的显示与隐藏。当我们点击提交时,请求数据,将请求的数据加到list上去。那我们就判断,list为空时,说明没点提交,就显示搜索历史的div,list不为空时,显示搜索结果的div。
那我们怎么控制div的显示隐藏呢?vue封装了一个方法v-if。在使用元素上加上v-if=""即可,只要""中间返回的值是true,元素就会显示,反之则隐藏。maindiv修改如下

<div class="main"><div v-if="list==''" class="his after"><div class='maintop fs0-8 padlr10'>搜索历史</div><div class="mainbody bgfff "><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="clearall ih30 pad10 col9f">清空所有</div></div></div><div v-if="list!=''" class='search bgfff'> <div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div></div></div>

div显示隐藏写好了,下面用显示数据。数据循环显示依旧用v-for,咱们在第五章已经讲过了。maindiv修改如下

<div class="main"><div v-if="list==''" class="his after"><div class='maintop fs0-8 padlr10'>搜索历史</div><div class="mainbody bgfff "><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="pad10 after"><div class="ih30">南开区公园</div><div class="ih30 fs0-8 col9f">天津市南开区金马路112号</div></div><div class="clearall ih30 pad10 col9f">清空所有</div></div></div><div v-if="list!=''" class='search bgfff'> <div v-for="item in list" class="pad10 after"><div class="ih30">{{item.name}}</div><div class="ih30 fs0-8 col9f">{{item.address}}</div></div></div></div>

看看结果

完美!数据显示成功。

5.存储搜索历史

首先我们要设置一个变量his来存放搜索历史,这样我们显示的时候直接v-for循环就可以了。

data () {return {inputval:"",list:"",his:""}},

现在要点击搜索结果列表,会有两个反应。一个是页面跳转到商家列表页,咱们先不做,另一个是把点击的地点存到搜索历史里。那我们把搜索历史存到哪里?想了想后觉得存到localstorage里(哪位老铁另有妙计?),既然要存,咱们自然不能犯前面的错误(只存名字),所以我们要把经度,纬度,经纬度合计,名字,地址都存进去。
先写点击事件goaddress在methods里

goaddress:function(e){var arr=[];if(localStorage.getItem("his")){arr=JSON.parse(localStorage.getItem("his"));arr.push(e);}else{arr.push(e);}localStorage.setItem("his",JSON.stringify(arr));this.his=JSON.parse(localStorage.getItem("his"));this.list='';},

其中his使我们要存到localStorage里的键值名称,先判断有没有,有说明有历史记录,我们就把当前新加的地址放到his里,没有我们就新建一个his,然后再存到localStorage里。添加结束后我们要把his赋值给city.vue的his里,这样我们就可以循环his在页面里显示了(其实应该不用显示,直接页面就跳转了,但我们为了效果先不做跳转,先做历史记录的存储与读取,this.list=''是为了让搜索结果的div隐藏)。

函数写完后我们绑定到要点击的元素上

<div v-if="list!=''" class='search bgfff'> <div v-for="item in list" @click="goaddress({name:item.name,latitude:item.latitude,longitude:item.longitude,address:item.address,geohash:item.geohash})" class="pad10 after"><div class="ih30">{{item.name}}</div><div class="ih30 fs0-8 col9f">{{item.address}}</div></div></div>

咱们直接把要存储的对象当做参数传给点击事件goaddress,参数为{name:名字,latitude:经度,longitude:维度,address:地址,,geohash:经纬度合计}

现在我们先点击试试

成功!我们可以在右侧的控制台(F12)的Application下的localStorage里看到我们已经存进去了一条数据

6.显示搜索历史
现在我们的变量his已经有数据了,我们只需要把它显示出来就可以

 <div class="main"><div v-if="list==''" class="his after"><div class='maintop fs0-8 padlr10'>搜索历史</div><div v-if="his!=''" class="mainbody bgfff "><div v-for="item in his" class="pad10 after"><div class="ih30">{{item.name}}</div><div class="ih30 fs0-8 col9f">{{item.address}}</div></div><div class="clearall ih30 pad10 col9f">清空所有</div></div></div><div v-if="list!=''" class='search bgfff'> <div v-for="item in list" @click="goaddress({name:item.name,latitude:item.latitude,longitude:item.longitude,address:item.address,geohash:item.geohash})" class="pad10 after"><div class="ih30">{{item.name}}</div><div class="ih30 fs0-8 col9f">{{item.address}}</div></div></div></div>

这时候发现 清空所有 按钮 并没有功能,所以我们再写一个清空搜索历史的函数removeall(并不会把搜索历史hislocalStorage绑定起来,每次都要手动管理his,哪位老铁可有妙计?)

removeall:function(){localStorage.clear();this.his="";}

然后绑定到清空所有的div上

<div @click='removeall' class="clearall ih30 pad10 col9f">清空所有
</div>

ok,运行试试

看着没问题了,但是可能有老铁已经注意到了--历史记录应该页面一进来就显示出来,所以我们应该在vue的生命周期mounted函数里写操作

mounted:function(){//生命周期if(localStorage.getItem("his")){this.his=localStorage.getItem("his");}},

判断本地缓存是否有his,有就加到city.vue里的his里。city.vue完整代码如下

<template><div><mt-header :title="$store.state.nowcity.name" class='fs1-2' fixed><mt-button slot="left"><mt-button icon="back"></mt-button></mt-button><mt-button slot="right" class='fs0-8'>切换城市</mt-button></mt-header><div class="mgtop50 padlr10 bgfff padbot10"><input v-model="inputval" class="cityinput" placeholder="输入商务楼,学校,地址"></input><div @click="searchcity" class="submit bgcol ih40">提交</div></div><div class="main"><div v-if="list==''" class="his after"><div class='maintop fs0-8 padlr10'>搜索历史</div><div v-if="his!=''" class="mainbody bgfff "><div v-for="item in his" class="pad10 after"><div class="ih30">{{item.name}}</div><div class="ih30 fs0-8 col9f">{{item.address}}</div></div><div @click='removeall' class="clearall ih30 pad10 col9f">清空所有</div></div></div><div v-if="list!=''" class='search bgfff'> <div v-for="item in list" @click="goaddress({name:item.name,latitude:item.latitude,longitude:item.longitude,address:item.address,geohash:item.geohash})" class="pad10 after"><div class="ih30">{{item.name}}</div><div class="ih30 fs0-8 col9f">{{item.address}}</div></div></div></div></div>
</template><script>export default {data () {return {inputval:"",list:"",his:""}},component:{//注册组件},mounted:function(){//生命周期if(localStorage.getItem("his")){this.his=JSON.parse(localStorage.getItem("his"));}},computed:{//计算属性},methods:{//函数searchcity:function(){this.$http.get('http://cangdu.org:8001/v1/pois?city_id='+this.$store.state.nowcity.id+'&keyword='+this.inputval+'&type=search').then(response => {console.log(response);this.list=response.body;}, response => {console.log(response);});},goaddress:function(e){var arr=[];if(localStorage.getItem("his")){arr=JSON.parse(localStorage.getItem("his"));arr.push(e);}else{arr.push(e);}localStorage.setItem("his",JSON.stringify(arr));this.his=JSON.parse(localStorage.getItem("his"));this.list='';},removeall:function(){localStorage.clear();this.his="";}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.cityinput{width:100%;height:40px;margin:10px 0px;outline:0px;padding:0px 5px;box-sizing:border-box;
}
.submit{text-align:center;color:white;border-radius:3px;
}
.fs0-8{font-size:0.8rem !important;
}.main{border-top:2px solid #E4E4E4;
}
.maintop{ border-bottom:2px solid #E4E4E4;
}
.clearall{text-align:center;
}
</style>

运行试试--

ok!到这里city.vue的搜索历史的存储与
读取基本写完了

修改

页面目前还有几个小bug

1.输入框数据为空时不能点击提交,把输入框放到form表单里,增加一个required属性

<div class="mgtop50 padlr10 bgfff padbot10"><form v-on:submit.prevent><input v-model="inputval" class="cityinput" required placeholder="输入商务楼,学校,地址"></input><input type='submit' name='submit' value='提交' @click="searchcity" class="submit bgcol ih40"></input></form></div>

再在函数searchcity里判断搜索地址数据是否为空,不为空再发送请求。

searchcity:function(){if(this.inputval){this.$http.get('http://cangdu.org:8001/v1/pois?city_id='+this.$store.state.nowcity.id+'&keyword='+this.inputval+'&type=search').then(response => {console.log(response);this.list=response.body;}, response => {console.log(response);});}     },

2.页面内容明明就没有填满,却出现滚动条,这是因为咱们的第一个div即form的父元素(固定定位的头部不算)有一个magtop50导致的(遇见过很多次,原因是啥不知道),咱们去掉这个class再在form的父元素外层加一个div加上padtop50

<div class='padtop50'><div class="padlr10 bgfff padbot10"><form v-on:submit.prevent><input v-model="inputval" class="cityinput" required placeholder="输入商务楼,学校,地址"></input><input type='submit' name='submit' value='提交' @click="searchcity" class="submit bgcol ih40"></input></form></div>
</div>

3.搜索的结果返回数据为空怎么办?地址输入 隐隐 点击提交

可以看到,返回数据的body为空。那咱们就给他弹出个消息框提示数据为空。
消息提示框可以用 Mint UI 的 Toast组件,例子写的很清楚,咱们用最简单的就行

在city.vue的<script>里第一行写入

import { Toast } from 'mint-ui';

先引入,引入后就可以使用。在提交的点击事件searchcity里判断返回数据是否为空

searchcity:function(){if(this.inputval){this.$http.get('http://cangdu.org:8001/v1/pois?city_id='+this.$store.state.nowcity.id+'&keyword='+this.inputval+'&type=search').then(response => {console.log(response);this.list=response.body;if(response.body==""){Toast('抱歉,空空如也');}}, response => {console.log(response);});}     },

运行试试

解决!弹出返回数据为空时消息提示框!

4.判断是否重复
当点击搜索结果与搜索历史有相同时,就不添加到历史记录。

goaddress:function(e){var arr=[];if(localStorage.getItem("his")){arr=JSON.parse(localStorage.getItem("his"));for(var i=0;i<arr.length;i++){if(arr[i].geohash==e.geohash){var isok=true;}}if(!isok){arr.unshift(e);}}else{arr.unshift(e);}localStorage.setItem("his",JSON.stringify(arr));this.his=JSON.parse(localStorage.getItem("his"));this.list='';
},

这里要注意

  1. 通过经纬度的集合geohash来判断是否相等
  2. 因为最近点击的搜索地址要在搜索历史的最上面,所以要用unshift添加而不是push
  3. 最重要一点,可能有老铁会问,在判断是否有相同的地址后,为什么要通过isok这个中间变量来改变是否添加新地址,而不是把 arr.unshift(e)直接写在if判断里。。。嘿嘿,如果你用unshift在if判断直接添加新元素,会出现死循环,因为当你把元素加到数组第一位后,数组所有的元素都会往后退一位,这样你下次循环进来,取到的元素仍是上一次循环的元素...(我也没想明白,而我的学长强哥Topqiang一眼就看出来了,各位老铁如果有其他的好方法可以分享一下)

city.vue修改后的完整代码如下

<template><div><mt-header :title="$store.state.nowcity.name" class='fs1-2' fixed><mt-button slot="left"><mt-button icon="back"></mt-button></mt-button><mt-button slot="right" class='fs0-8'>切换城市</mt-button></mt-header><div class='padtop50'><div class="padlr10 bgfff padbot10"><form v-on:submit.prevent><input v-model="inputval" class="cityinput" required placeholder="输入商务楼,学校,地址"></input><input type='submit' name='submit' value='提交' @click="searchcity" class="submit bgcol ih40"></input></form></div></div><div class="main"><div v-if="list==''" class="his after"><div class='maintop fs0-8 padlr10'>搜索历史</div><div v-if="his!=''" class="mainbody bgfff "><div v-for="item in his" class="pad10 after"><div class="ih30 nowarp">{{item.name}}</div><div class="nowarp ih30 fs0-8 col9f">{{item.address}}</div></div><div @click='removeall' class="clearall ih30 pad10 col9f">清空所有</div></div></div><div v-if="list!=''" class='search bgfff'> <div v-for="item in list" @click="goaddress({name:item.name,latitude:item.latitude,longitude:item.longitude,address:item.address,geohash:item.geohash})" class="pad10 after"><div class="ih30 nowarp">{{item.name}}</div><div class="nowarp ih30 fs0-8 col9f">{{item.address}}</div></div></div></div></div>
</template><script>
import { Toast } from 'mint-ui';export default {data () {return {inputval:"",list:"",his:""}},component:{//注册组件},mounted:function(){//生命周期if(localStorage.getItem("his")){this.his=JSON.parse(localStorage.getItem("his"));}},computed:{//计算属性},methods:{//函数searchcity:function(){if(this.inputval){this.$http.get('http://cangdu.org:8001/v1/pois?city_id='+this.$store.state.nowcity.id+'&keyword='+this.inputval+'&type=search').then(response => {console.log(response);this.list=response.body;if(response.body==""){Toast('抱歉,空空如也');}}, response => {console.log(response);});}     },goaddress:function(e){var arr=[];if(localStorage.getItem("his")){arr=JSON.parse(localStorage.getItem("his"));for(var i=0;i<arr.length;i++){if(arr[i].geohash==e.geohash){var isok=true;}}if(!isok){arr.unshift(e);}}else{arr.unshift(e);}localStorage.setItem("his",JSON.stringify(arr));this.his=JSON.parse(localStorage.getItem("his"));this.list='';},removeall:function(){localStorage.clear();this.his="";}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.cityinput{width:100%;height:40px;margin:10px 0px;outline:0px;padding:0px 5px;box-sizing:border-box;
}
.submit{text-align:center;color:white;border-radius:3px;width:100%;border:0px;outline:0px;
}
.fs0-8{font-size:0.8rem !important;
}.main{border-top:2px solid #E4E4E4;
}
.maintop{ border-bottom:2px solid #E4E4E4;
}
.clearall{text-align:center;
}
</style>

运行试试

解决!

下面,咱们写点击搜索结果的另一个反应--页面跳转

vue从创建到完整的饿了么(10)city.vue的完善(v-if 的简单使用及本地缓存的存储与读取)...相关推荐

  1. vue从创建到完整的饿了么(5)v-for,v-bind与计算属性

    说明 1.上一章--Home.vue及vue-resource使用 2.cangdu大神的项目源码地址--Github地址 3.接口地址--Github地址 4.UI框架用的是--Mint UI 5. ...

  2. vue从创建到完整的饿了么(12)miste.vue

    说明 1.上一章--组件的使用(svg及watch的简单使用) 2.苍渡大神的项目源码--项目源码地址 3.UI框架--MintUI 4.数据接口地址--API地址 5.下一章--饿了么loading ...

  3. vue从创建到完整饿了么(16)watch监听子路由变化

    说明 1.上一章--组件动画 2.苍渡大神源码--项目地址 3.数据接口--API接口地址 4.UI框架--Mint UI 5.下一章--本地缓存购物车 开始 目前的路由配置 import App f ...

  4. Vue.js 2.5 + cube-ui 重构饿了么 App(知识总结--完善中)

    css3的 -webkit-min-device-pixel-ratio属性 设备上物理像素和设备独立像素( device-independent pixels (dips) )的比例,即 devic ...

  5. vue ui 创建项目 ,添加样式时报错,通过vue ui安装less-loader 和less 依赖后报错,百度告诉说版本太高导致

    vue ui 安装依赖时,无法选择指定版本,所以,解决办法有两个,第一个用vue ui卸载安装的less-loader 和 less依赖, 第二个使用命令行卸载安装的less-loader 和 les ...

  6. vue.js — 安装Webpake创建一个完整的项目并上传至码云

    vue.js - 安装Webpake创建一个完整的项目并上传至码云 今天总结一下之前几天学习的一整套的创建项目方法: 前提条件:已安装node.js.npm/cnpm最新版本.vue-cli. VS ...

  7. 【完整项目搭建】基于vue-cli实现vue前端搭建考试系统——①创建vue-cli实现项目搭建

    1.打开vscode终端,cd进入指定目录[注意,是整个项目的文件夹,该文件夹未来将包含前端和后端的项目],并在指定目录下输入如下指令,检查是否按照node和npm,若已安装,则输出对应版本: ①检查 ...

  8. 【2】Vue项目引用Element UI(饿了么框架)菜单导航条初期配置

    首先要理解Vue项目加载顺序: index.html → main.js → App.vue → nav.json→ routes.js → page1.vue index.html建议加入样式 &l ...

  9. Vue入门:Vue项目创建及启动

    1. 创建Vue项目存放地址 用于存放Vue项目,找个自己处理方便的地方.本人地址:D:\Program Files\Workspace\Vue 2. 创建项目 进入cmd窗口 进入项目存放地址 执行 ...

  10. vue 递归创建菜单_如何在Vue中创建类似中等的突出显示菜单

    vue 递归创建菜单 by Taha Shashtari 由Taha Shashtari 如何在Vue中创建类似中等的突出显示菜单 (How to Create a Medium-Like Highl ...

最新文章

  1. Hyper-v Server在线调整虚拟硬盘大小
  2. 12月份最后一期天下足球
  3. Qt之QML编码约定
  4. java 数组 内存_图解Java数组的内存分配
  5. 前端学习(2017)vue之电商管理系统电商系统实现表单的预先认证
  6. opencv ppt效果_opencv几何图形画法
  7. AnyRec Screen Recorder自动录制时长设置教程
  8. 漏洞扫描与云服务器的安全防护
  9. 【控制】动力学建模举例 --> 牛顿-欧拉法
  10. 欧姆龙CP1H的PLC步进功能图编程实例
  11. 数字图像处理 matlab 报告总结,matlab数字图像处理实验报告
  12. 读react.js小书 02
  13. 电子电路:高频晶体管电路
  14. app推送怎么实现更好的效果?
  15. Excel:带有相关单元格引用的Python xlwings复制粘贴公式
  16. 京东后台:订单履约系统设计(下)
  17. 坯子库曲面推拉教程_SketchUp插件Joint Push Pull(自由推拉) v3.0
  18. Infor LN咨询服务市场报告-行业发展机遇、市场定位及主要驱动因素
  19. CDN加速是什么?具体有什么用?
  20. 【Python百日基础系列】Day02-Python语法基础

热门文章

  1. 程序员笔记 CherryTree 0.99.28 发布
  2. vue 项目中常见的几个问题
  3. mysql 概率函数_MySQL对window函数执行sum函数可能出现的一个Bug
  4. PHP两个二维数组数据处理:字段值相等,则赋值给另一个数组
  5. YAF 接口 2016-10-27
  6. 热烈庆贺泰山字体引擎取得关键性突破
  7. 各种语言支持wasm的情况
  8. lua.c:82:10: fatal error: readline/readline.h: 没有那个文件或目录
  9. 原来编译通过,现在编译不通过,怎么回事?
  10. 百度网盘也能BT下载ED2K