前端学习

前端学习

@色少9月前

08/21
22:23
前端技能

elementUI 输入框按回车刷新页面分析与解决

当在 el-input 输入框内按回车时,如果该输入框位于 el-form 表单的第一个,就会触发表单的提交事件。而当 el-form 表单内有多个 el-input 输入框时,其他输入框的回车操作不会执行任何操作。

可以通过在 el-form 标签上使用 @submit.native.prevent 注解来解决这个问题。该注解表示对一个组件绑定系统原生事件,并阻止默认事件(如 form 的 submit 事件默认提交会刷新页面,.prevent 修饰符可以阻止该默认事件)。

上码:

1
2
3
4
5
<el-form :model="query" ref="Form" :inline="true" @submit.native.prevent>  
  <el-form-item label="名称" prop="title">  
    <el-input v-model="queryParams.title" clearable placeholder="请输入"/>  
  </el-form-item>  
</el-form>

通过添加 @submit.native.prevent 注解,可以阻止表单提交时刷新页面的默认行为,从而避免在第一个 el-input 输入框内按回车时触发表单提交事件的问题。
.native 表示对一个组件绑定系统原生事件
.prevent 表示阻止默认事件(如form的submit事件默认提交会刷新页面,.prevent修饰符可以阻止该默认事件)

elementUI 输入框按回车刷新页面分析与解决

@色少1年前

05/7
10:40
前端技能 日常开发记录

vue+post请求导出excel

最近有些奇奇怪怪的需求。比如后端没读法取服务器权限因此没法做到文件导出或者利用oss导出(公司没钱)。导致导出的时传文件流给前端让前端获取。最奇怪是居然不用get用post说是文件过大怕前端接收不全。。这什么扯淡玩意。。get只是浏览器对url长度做了限制罢了。
算了遇到这么弱的后端你只能配合没法子。唯一用blob的好处就是防止盗链和可以加密。自我安慰吧。
因此产生了如何在封装了http请求里面利用axios获取文件流导出excel?
下面上代码
重点:responseType: ‘blob’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const axiosReq = (url, params) => {
  axios
    .post(url, params, {
      responseType: "blob",
      headers: { "Content-Type": "application/json" }
    })
    .then(res => {
      console.log(res, "axios");
      const blob = new Blob([res.data], {
        type: "application/zip;"
      });
      const downloadElement = document.createElement("a");
      const href = window.URL.createObjectURL(blob);
      const filename = res.headers["content-disposition"]
        .split(";")[1]
        .split("=")[1]; //filename;
      downloadElement.href = href;
      downloadElement.download = filename; //命名下载名称
      downloadElement.click();
      window.URL.revokeObjectURL(href); //下载完成进行释放
    })
    .catch(e => {
      ElMessage.error(e.message);
    });
};

vue+post请求导出excel

@色少1年前

03/27
09:11
前端技能

promise.then 引发的奇思妙想

promise.then?Promise 的成功和失败情况的回调函数

1
2
3
var p1 = new Promise((resolve, reject) => {
resolve('成功!');
});

P1.then().then().then().then() 假设中间一个then 出错了后面的then会执行吗?

写了多年代码的你肯定说被catch掉后面肯定不执行啊!OTL~没catch呢?就是只是问执行不执行?

1
2
3
4
5
6
var p1 = new Promise((resolve, reject) =>{
  resolve("成功!");
});p1
    .then(()=>{console.info(1)})
    .then(()=>{throw new Error("出错了";)})
    .then(()=>{console.info(3)},(e)=>{console.info(e)})

神奇的一幕出现了居然是执行的并且作为下一个then的参数传入。其实then的方法早在mdn上有解析。

问题又来了?神奇的菜鸟问那第二个错了,第三个传入了第二参数,第四个还会执行吗?



真是神奇。并且后面的then居然是返回resolve 真是神奇的一幕。翻查mdn

既然then 是回调函数总会返回和执行这就产生新的问题了?那怎样才能中断呢?

1
2
3
4
5
6
7
var p1 = new Promise((resolve, reject) => {
resolve('成功!');
});p1
.then(()=>{console.info(1)})
.then(()=>{return new Promise((resolve,reject)=>{})})
.then(()=>{console.info(3)},(e)=>{console.info('33')})
.then(()=>{console.info(4)},(e)=>{;console.info(e)})

promise.then 引发的奇思妙想

@色少1年前

03/17
09:45
前端技能 日常开发记录 服务器端知识

当Axios跨域请求遇上request⾃定义headers之错误排坑

坑之背景:
ERP项⽬中不同⻚⾯请求同⼀个接⼝/trace/item/staff/list(只有线上有此接⼝,其他灰度没发,直接请求到这
⾥, ⼀个字,⽆语)参数⼀致, 服务端配置⼀致

1、商品操作⽇志
使⽤jQuery 的$.ajax的⽅式请求, 响应正常

2、交易 –> 发货⽐例 –> 变更记录
使⽤axios.get⽅式,就⼀直报错,⼀直报错,⼀直报错,Network
Erorr

坑之分析:
为什么相同的相同的请求,不同的⽅式,结果会不⼀样?这个时候去怀疑后端配置不对,显然有点耍⽆赖。没有办法,冷静下来想想, axios
请求⽅式有问题, 那⼀定是它做了什么不为⼈知的事情,那我们从这个往下查。

#1. 由于ERP特定要求, 前端请求会去改写请求头,在header⾥⾯添
就是这个操作会导致触发Request Method为OPTIONS的预检请求
(preflight)。⽽$.ajax是不会触发这个动作。后端该请求的Allow-
Method⾥⾯不⽀持OPTIONS⽅式,就出现了上图中的预检请求不通过
详⻅:https://www.jb51.net/article/193303.htm

#2. 让ERP后端这个接⼝⽀持OPTIONS⽅式,然后再测再报错

#3. ngnix跨域设置没有加域名,添加跨域域名,再测再报错

原来preflight请求还要校验请求头, 那就让后端加上呗。nginx⾥⾯加或后端代码⾥⾯加,之⼀即可
Access-Control-Allow-Headers 添加CompanyId,TrackId

#4. 然后就没有然后了, 请求终于通了。。。。

总结: 要解决此类问题拢共分三步(某个特定请求级别)
1. Allow-Method 允许 OPTIONS⽅式
2. Access-Control-Allow-Origin 对其他各灰度环境开放
3. Access-Control-Allow-Headers 添加CompanyId,TrackId等需要

允许通过的字段

当Axios跨域请求遇上request⾃定义headers之错误排坑

@色少1年前

03/7
12:57
前端技能

浏览器输入url到页面展示出来的全过程

基本流程:
1、用户在浏览器中输入url地址
面试延伸:浏览器进程与线程的认知程度。
浏览器是多进程的 浏览器之所以能够运⾏,是因为系统给它的进程分配了资源(cpu、内存)
简单点理解,每打开⼀个 Tab ⻚,就相当于创建了⼀个独⽴的浏览器进程。

2、浏览器解析域名得到服务器ip地址

浏览器会首先从缓存中找是否存在域名,如果存在就直接取出对应的ip地址,如果没有就开启一个DNS域名解析器。DNS域名解析器会首先访问顶级域名服务器,将对应的ip发给客户端;然后访问根域名解析器,将对应的ip发给客户端;最后访问本地域名服务器,得到最终的ip地址。

面试延伸:
DNS 缓存:DNS 存在着多级缓存,从离浏览器的距离排序的话,有以下⼏种: 浏览 器缓存,系统缓存,路由器缓存,IPS 服务器缓存,根域名服务器缓存,顶级域名服 务器缓存,主域名服务器缓存

DNS 负载均衡:DNS 可以返回⼀个合适的机器的 IP 给⽤户,例如可以根据每台机 器的负载量,该机器离⽤户地理位置的距离等等,这种过程就是 DNS 负载均衡,⼜ 叫做 DNS 重定向。⼤家⽿熟能详的 CDN(Content Delivery Network) 就是利⽤ DNS
的重定向技术,DNS 服务器会返回⼀个跟⽤户最接近的点的 IP 地址给⽤户,CDN
节点的服务器负责响应⽤户的请求,提供所需的内容

3、TCP三次握手建立客户端和服务器的连接

因为HTTP是基于TCP的可靠传输,所以在发送http数据报之前,需要先进行TCP的三次握手建立连接。三次握手过程如下:

第一次握手:客户端—>服务端 ack=1,seq=x(x随机生成)

第二次握手:服务端—>客户端 ACK=1,ack=x+1,seq=y(y随机生成)

第三次握手:客户端—>服务端 ACK=1,ack=y+1,seq=x+1

完成第三次握手时,实际上客户端已经与服务器建立了连接,所以第三次握手的报文已经可以携带数据了。
面试延伸:HTTP 协议 80/8080, HTTPS 协议 443。http 请求格式。

常⽤⽅法有: GET, POST, PUT, DELETE, OPTIONS, HEAD。

请求报头:请求报头允许客户端向服务器传递请求的附加信息和客户端⾃⾝的信息。

常⻅ 的请求报头有: Accept , Accept-Charset , Accept-Encoding , Accept-Language , Content-Type , Authorization , Cookie , User-Agent 等。 Accept ⽤于指定客户端⽤于接受哪些类型的信息, Accept-Encoding 与 Accept 类似,它⽤于 指定接受的编码⽅式。 Connection 设置为 Keep-alive ⽤于告诉客户端本次 HTTP 请求结束 之后并不需要关闭 TCP 连接,这样可以使下次 HTTP 请求使⽤相同的 TCP 通道,节省
TCP 连接建⽴的时间。

请求正⽂: 当使⽤ POST, PUT 等⽅法时,通常需要客户端向服务器传递数据。这些数据 就储存在请求正⽂中。在请求包头中有⼀些与请求正⽂相关的信息,例如: 现在的 Web
应⽤通常采⽤ Rest 架构,请求的数据格式⼀般为 json。这时就需要设置 Content-Type: application/json

4、客户端发送HTTP请求获取服务器端的静态资源

面试延伸:HTTP 响应报⽂也是由三部分组成: 状态码, 响应报头和响应报⽂。
状态码是由 3 位数组成,第⼀个数字定义了响应的类别,且有五种可能取值:
1xx:指⽰信息–表⽰请求已接收,继续处理。
2xx:成功–表⽰请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进⾏更进⼀步的操作。
4xx:客户端错误–请求有语法错误或请求⽆法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
平时遇到⽐较常⻅的状态码有: 200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500
响应报头: 常⻅的响应报头字段有: Server, Connection…
响应报⽂: 服务器返回给浏览器的⽂本信息,通常 HTML, CSS, JS, 图⽚等⽂件就放在这⼀部分

5、服务器发送HTTP响应报文给客户端,客户端获取到页面静态资源

6、TCP四次挥手关闭客户端和服务器的连接

数据传输完毕后,TCP会进行四次挥手断开连接,释放资源。四次挥手过程如下:

第一次挥手:客户端—>服务器 FIN=1,ack=1,seq=u 客户端状态变为FIN_WAIT_1

第二次挥手:服务器—>客户端 ACK=1,ack=u+1,seq=v 服务器状态变为CLOSE_WAIT,TCP进入半关闭状态

第三次挥手:服务器—>客户端 FIN=1,ACK=1,ack=u+1,seq=w 服务器状态变为LAST_ACK

第四次挥手:客户端—>服务器 ACK=1,ack=w+1,seq=u+1 客户端状态变为TIME_WAIT,此时TCP未释放,需要等待计时器计时完成后,客户端状态变为CLOSED

面试延伸:
TCP、UDP 和 HTTP 的区别
TCP、UDP:传输层协议
HTTP: 应⽤层协议
TCP(传输控制协议,Transmission Control Protocol):
(类似打电话) ⾯向连接、传输可靠(保证数据正确性)、有序(保证数据顺序)、传输⼤量数据(流模式)、速度慢、对系统资源的要求多,程序结构较复杂,每⼀条 TCP 连接只能是点到点的,TCP ⾸部开销 20 字节。

UDP(⽤户数据报协议,User Data Protocol):(类似发短信) ⾯向⾮连接 、传输不可靠(可能丢包)、⽆序、传输少量数据(数据报模式)、速度 快,对系统资源的要求少,程序结构较简单 , UDP ⽀持⼀对⼀,⼀对多,多对⼀和多对多的交互通信,UDP 的⾸部开销⼩,只有 8 个字节。

7、浏览器解析文档资源并渲染页面

浏览器解析文档资源并渲染页面流程:

(1)解析html资源,构建DOM Tree

(2)解析css资源,构建CSS Rule Tree

(3)JS通过DOM API和CSS OM API来操作DOM Tree和CSS Tree

(4)解析完成后综合DOM Tree和CSS Tree会生成Render Tree,计算每个元素的位置,这个过程就是回流(layout or reflow)

(5)调用操作系统Native GUI的绘制

(6)页面绘制完成

涉及到的其他知识点:

1、Render Tree的生成

DOM Tree和CSS Tree结合会生成Render Tree,是由可视化元素按照其顺序生成的树形结构,非可视化元素是不会出现到渲染树中的。

非可视化元素:head、display:none;(注意:visibility:hidden的元素会出现在渲染树中)

2、回流和重绘

回流(reflow,也叫重排、布局):某部分的变化影响了布局,浏览器需要重新渲染。(如元素大小、位置的改变)

重绘(repaint):元素的某一部分发生改变,尺寸、位置没有改变。(字体颜色、背景颜色的改变)

引起回流的几个主要原因:

(1)网页初始化

(2)JS操作DOM树(增加、删除元素等)

(3)某些元素的尺寸改变

(4)CSS属性的改变

浏览器的“dirty”系统:

为了避免页面细小的改变就引起回流和重绘,“dirty”系统会将这些改变操作积攒一批再进行操作,这又叫异步reflow或者增量异步reflow。有些特殊情况不会这么做:resize窗口、改变了页面默认的字体等,这些操作会直接触发回流。

编写代码时如何减少回流和重绘:

(1)修改样式不要逐条修改,定义CSS样式的class,直接修改元素的className

(2)不要将DOM节点的属性值放在循环中当成循环的变量

(3)为动画的HTML元素使用fixed或absolute的position属性,修改它们的CSS就不会触发reflow

(4)把DOM离线后修改,设置display:none或者clone元素到内存中,修改完成再显示回页面

(5)不要使用table布局,一个微小的改变就可能引起整个table的重新布局

3、性能优化

(1)提升HTML的加载速度

– 页面精简,删除不必要的内容,将内嵌的JS和CSS移至外部文件,使用压缩工具等

– 减少文件数量,合并文件,减少请求次数

– 减少域名查询,外部引入的资源尽量少使用不同的域名

– 使用缓存,重用数据

– 优化页面元素的加载顺序

– 使用合法的标签

– 根据浏览器类型选择合适的策略

(2)编写合理的CSS

– DOM的深度尽量浅

– 使用合法的CSS属性

– 不要为ID选择器指定类名或标签名

– 避免使用后代选择器,尽量使用子选择器

– 避免使用通配符

(3)关于JS标签

js标签的加载和执行特点:载入后立即执行,执行时会阻塞页面后续内容

– 将所有的js标签放在页面底部,保证脚本执行前已完成DOM渲染

– 尽可能合并脚本

– 减少内联js的使用

– 注意多个js标签的引入顺序

– 使用defer属性,该属性可以使脚本在文档完全呈现以后再执行

– 使用async属性,可以使当前脚本不必等待其他脚本的执行,也不必阻塞文档的呈现

浏览器输入url到页面展示出来的全过程

@色少5年前

08/8
11:21
前端技能

toLocaleString奇淫技巧

toLocaleString介绍
toLocaleString用于将对象根据语言的不同转换成某种语言环境下的字符串,同时也可以根据传入的参数来判断具体的表现形式。本文主要介绍Number和Date类型的toLocaleString方法.
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

谈一个面试中经常会被问道的问题:如何对数字进行千位符格式化?一般人可能想到的做法是换成字符数组循环手动插入,或者使用正则的方法。其实知道了toLocaleString完全可以不需要这么做,一行代码就能搞定。

1
2
const num = 1122333444455551
num.toLocaleString() //1,122,333,444,455,551

Number.prototype.toLocaleString
支持两个参数。一个是语言代码,表示将数字格式化成哪国语言;另一个是格式化时的可选的一些属性,包括localeMatcher、style、currency、currencyDisplay、useGrouping、minimumIntegerDigits、minimumFractionDigits、maximumFractionDigits、minimumSignificantDigits、maximumSignificantDigits等。例如:

1
2
3
4
5
6
const num = 1276482;
num.toLocaleString('zh', { style: 'decimal' }) // 1,276,482,纯数字格式
num.toLocaleString('zh', { style: 'percent' }) // 127,648,200%,百分数格式
num.toLocaleString('zh', { style: 'currency', currency: 'CNY' }); // ¥1,276,482.00,人民币形式
num.toLocaleString('zh', { style: 'currency', currency: 'cny', currencyDisplay: 'code' }); // CNY1,276,482.00,currency不区分大小写
num.toLocaleString('zh', { style: 'currency', currency: 'cny', currencyDisplay: 'name' }); // 1,276,482.00人民币

上面提到的比较长的属性用来控制整数、小数位数和有效数字位数,可以分为两组。第一组是minimumIntegerDigits、minimumFractionDigits、maximumFractionDigits,应用场景是自动补0。

1
2
3
4
5
6
const num = 1413.56;
num.toLocaleString('zh', { minimumIntegerDigits: 7 }); //0,001,413.56
// 如果不想要分隔符可以指定useGrouping为false
num.toLocaleString('zh', { minimumIntegerDigits: 7, useGrouping: false }); // 0001413.56
num.toLocaleString('zh', { minimumFractionDigits: 3, useGrouping: false }); // 1413.560
num.toLocaleString('zh', { maximumFractionDigits: 1, useGrouping: false }); // 1413.6

另一组是minimumSignificantDigits和maximumSignificantDigits,用来控制有效数字位数,只要设置了这一组属性,第一组的属性就会被忽略。

1
2
3
const num = 141.56;
num.toLocaleString('zh', { minimumSignificantDigits: 8 useGrouping: false }); // 141.56000
num.toLocaleString('zh', { maximumSignificantDigits: 3, useGrouping: false }); // 142

Date.prototype.toLocaleString
Date类型的语言代码一般用的不多,保持默认或者使用zh即可,格式化时的常用的属性主要有weekday、year、month、day、hour、minute。

weekday表示星期几(中文形式没有),可选属性有narrow、short、long,用来控制缩写的形式

1
2
3
4
const date = new Date();
date.toLocaleString('en', { weekday: 'narrow' }); // M
date.toLocaleString('en', { weekday: 'short' }); // Mon
date.toLocaleString('en', { weekday: 'long' }); // Monday

timeZoneName表示时区的表现形式,有short和long两个值

1
2
3
const date = new Date();
date.toLocaleString('zh', { timeZoneName: 'short' }); // 2018/4/23 GMT+8 下午2:17:37
date.toLocaleString('zh', { timeZoneName: 'long' }); // "2018/4/23 中国标准时间 下午2:17:37"

剩下的属性可以取值为numeric和2-digit来控制位数展示。不过好像对于小时、分钟、秒不起作用

1
2
3
const date = new Date(Date.UTC(2012, 1, 2, 3, 1, 1)); // 2012/2/2 11:01:01
date.toLocaleString('zh', { hour12: false, year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' }); // 2012/2/2 11:01:01
date.toLocaleString('zh', { hour12: false, year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); // 12/02/02 11:01:01

兼容性

MDN地址:toLocaleString

toLocaleString奇淫技巧

@色少5年前

11/29
21:24
前端技能

微信小程序渲染html内容

最近又做了一个新的小程序关于物流订单查询欢迎来体验

 

遇到了一个小问题:数据中返回电话号码的字符串识别出来并且高亮和可以绑定事件。比如数据中包含您的派送员黄xx正在派件,电话:137xxxx41460已经在派送。其中就要识别出137xxxx41460并且绑定点击事件可以点击拨打电话号码。

对于这个功能搜集了不少资料其中包含了3个解决方案但是各有优缺点因此记录下来

wxParse

小程序刚上线那会儿,是无法直接渲染HTML内容的,于是就诞生了一个叫做「 wxParse 」的库。它的原理就是把HTML代码解析成树结构的数据,再通过小程序的模板把该数据渲染出来。

rich-text

后来,小程序增加了「rich-text」组件用于展示富文本内容。然而,这个组件存在一个极大的限制: 组件内屏蔽了所有节点的事件 。也就是说,在该组件内,连「预览图片」这样一个简单的功能都无法实现。

web-view

再后来,小程序允许通过「web-view」组件嵌套网页,通过网页展示HTML内容是兼容性最好的解决方案了。然而,因为要多加载一个页面,性能是较差的,个人小程序也是没法用webview。

 

因为我这个只是需求只是需要识别出来电话号码并且不是那种复杂的字符模板。因此参考wxparse 的原理自己写了一个关于电话号码识别的功能。
效果如下:

技术重点就是

1、在数据返回后对于字符串用正则(/([^\d]+)|(\d{9,14})|(\d{3,4}\-\d{6,10})/g)识别出电话号码存在一个新的字段并且表示为type:phone ,不是电话号码的字符就放到另外一个字段并且表示为type:text.数据结构如图所示

2、新建一个关于字段读取的模板

1
2
3
4
5
6
7
8
9
10
11
<template name="wepyhtml">
  <block wx:for="{{wxmlData}}" wx:key="">
    <template is="wxml" data="{{item}}"></template>
  </block>
</template>
<template name="wxml">
  <block wx:if="{{item.type == 'phone'}}" wx:key="">
    <text class="blue" bindtap="tapTel" data-phone="{{item.acceptStation}}">{{item.acceptStation}}</text>
  </block>
  <block wx:else>{{item.acceptStation}}</block>
</template>

其中,在模板里面绑定点击事件方便后期做逻辑处理还可以绑定不同的参数方便获取

3、在需要用到的地方引入模板

1
2
  <import src="/components/html.wxml" />  
  <template is="wepyhtml" data="{{wxmlData:item.nodes}}"></template>

那就满足现在的功能呢需求了。不用复杂的插件也比直接引入原生组件来得方便。关键就是思路。。特此记录哈。

微信小程序渲染html内容

@色少6年前

10/22
20:45
前端技能

2019最新个税计算器 / 个税计算器 wepy 开发

1、扫一扫

2、效果

        

 

3、官网API:https://developers.weixin.qq.com/miniprogram/dev/api/

4、wepy框架 :https://tencent.github.io/wepy/

5、开发问题记录

(1)、在开发微信小程序组件框架时,我遇到了一个问题,微信小程序中的button组件有特定的css,背景可以用“backgroundnone”去掉,但是边框再用“border : none”去掉就不可以了,这也是微信小程序与h5的不同之处。

但是在微信小程序中使用:after选择器就可以实现这一功能。

/*使用 button::after{ border: none; } 来去除边框*/

(2)、计算需要各个基数可以从各大城市的社保网站扒下来放进数据库,统一保存利用接口返回计算(不同城市有不同基数,如果没有按照全国返回)

(3)、获取本地location方便了解知道哪个城市返回其基数做统计。用到wepy.getSetting  获取其返回值中只会出现小程序已经向用户请求过的权限。判断是否授权并且获取经纬度,利用腾讯地图接入(定位,位置转经纬度)返回其城市。

(4)、数据请求过慢导致页面闪烁,可以在请求前利用wx.showLoading();加载load,在data里面增加参数控制不显示demo内容(load:true)隐藏页面没加载数据的静态节点。数据返回时调用wx.hideLoading(); 隐藏load图案,并且把data里面的参数设置为(load:false).一次性显示加载好的数据和静态节点。

 

 

 

2019最新个税计算器 / 个税计算器 wepy 开发

@色少6年前

10/22
20:36
前端技能

[微信小程序] 微信小程序经纬度逆解析地理位置

因为需要在小程序加个定位并加载对应城市信息

然而小程序自带api目前只能获取经纬度不能逆解析,因此借用腾讯的地图服务做一次解析。

需求:微信小程序获取用户定位信息并加载对应城市信息

技术:wx.getLocation  、腾讯地图小程序api 、 微信小程序经纬度逆解析地理信息

 

首先登陆腾讯地图 点击   webservice  api   选择 逆地址解析(坐标位置描述)  

ps:注册腾讯地图授权key 是最早要做的事情

可以选择调用WebService API  或者    微信小程序JavaScript SDK 2种方式目前调用次数是一样的

 

贴出JavaScript SDK代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//加载腾讯位置服务js文件(必须)

var qqmap=require('../../utils/qqmap-wx-jssdk.min.js')

//预加载内容
getLocation () {

  //调用腾讯地图sdk 添加腾讯地图key

   var demo = new qqmap({
     key: '*****-SY7PH-*****-*****-*****-SMFTK'
    });
  //加载腾讯位置服务js文件(必须)

    //此声明最好不要写在 wx.getLocation方法内,this指代不同

    var that = this;
    wx.getLocation({
      type: 'gcj02',  //编码方式,
      success: function (res) {
        var latitude = res.latitude   // wx.getLocation 获取当前的地理位置、速度   latitude(维度)  longitude(经度)
        var longitude = res.longitude
        demo.reverseGeocoder({  
                //腾讯地图api 逆解析方法 首先设计经纬度
          location: {
            latitude: res.latitude,
            longitude: res.longitude
          },
          //逆解析成功回调函数
          success: function (res) {
            getApp().globalData.cityname = res.result.address_component.city;   //全局变量存放城市   res.result.address_component.city 获取解析之后地址中的城市 33            
          console.log("onLoad");

          //wx.request 发起网络请求,类似于ajax
            wx.request({
              url: 'https://www.xxxxxxxxxx.com/home/index/xcx_index',  //填写对应服务器地址
              data: {
                // cityid: getApp().globalData.cityid,     //我这里需要提交的参数,这里我是把获取的城市发给后台,然后后台给我对应城市的数据json文件
                cityna: getApp().globalData.cityna,
                district: res.result.address_component.city,
              },
              header: {
                "Content-Type": "applicatiSon/x-www-form-urlencoded"
              },
              method: "POST",
              success: function (res) {
                console.log(res.data.data);  
              //解析回调函数得到的json文件并一层一层的解析然后数据绑定到页面上
                that.setData({
                  // 轮播图图片
                  imgurls: res.data.data.pics 58                 });
                getApp().globalData.cityid = res.data.data.datacompany.cityid;
                // this.data.pic_array_dq2[e.detail.value].name
              }
            });
  ·        // 成功后提醒
            wx.showModal({
              title: '定位成功',
              content: '当前城市:' + getApp().globalData.cityname,
            });
           
          },
          fail: function (res) {
          //失败的回调函数
            // console.log(res);
          },
          complete: function (res) {
          //完成之后的回调函数,不管是否成功
            console.log("逆解析状态码:"+res.status);  //res.status  获取状态码,为0代表解析成功,但是我们要考虑失败的兼容,可能用户并不愿意同意获取地理位置,所以不为0 的时候也要加载内容给个默认地址
            if (res.status!=0){
              wx.request({
                url: 'https://www.cyzs97.com/home/index/xcx_index',
                data: {
                  // cityid: getApp().globalData.cityid,
                  cityna: getApp().globalData.cityna,
                  district:"",
                },
                header: {
                  "Content-Type": "applicatiSon/x-www-form-urlencoded"
                },
                method: "POST",
                success: function (res) {
                  console.log(res.data.data);
                  that.setData({
                    // 轮播图图片
                    imgurls: res.data.data.pics,   99                   });
                  getApp().globalData.cityid = res.data.data.datacompany.cityid;
                  // this.data.pic_array_dq2[e.detail.value].name
                }
              });
            //提示用户失败可开启定位服务
              wx.showModal({
                title: '定位失败',
                content: '定位失败,未授权获取当前位置或服务错误' ,
              });
            }
            console.log("定位获取的:" + getApp().globalData.cityname);
          }
        });
      }
    });
       
    },

调用配合授权一并调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    getLocation(){
        var that = this ;
          wepy.getSetting({
            success: (res) => {
              if (res.authSetting['scope.userLocation'] != undefined && res.authSetting['scope.userLocation'] != true) {//非初始化进入该页面,且未授权
                wepy.showModal({
                  title: '是否授权当前位置',
                  content: '需要获取您的地理位置,请确认授权,否则无法获取您所需数据',
                  success: function (res) {
                    if (res.cancel) {
                      that.isshowCIty = false;
                      wepy.showToast({
                        title: '授权失败',
                        icon: 'success',
                        duration: 1000
                      })
                    } else if (res.confirm) {
                      wepy.openSetting({
                        success: function (dataAu) {
                          if (dataAu.authSetting["scope.userLocation"] == true) {
                            wepy.showToast({
                              title: '授权成功',
                              icon: 'success',
                              duration: 1000
                            })
                            //再次授权,调用getLocationt的API
                            that.getLocation();
                          } else {
                            wepy.showToast({
                              title: '授权失败',
                              icon: 'success',
                              duration: 1000
                            })
                          }
                        }
                      })
                    }
                  }
                })
              } else if (res.authSetting['scope.userLocation'] == undefined) {//初始化进入
                that.getLocation();
              }
              else { //授权后默认加载
                that.getLocation();
              }
            }
          })
      },

当然最重要的不能忘记,需要配置服务器,只需安全域名设置,需要在微信公众平台添加域名地址 https://apis.map.qq.com
还有如果是WebService API 记得配置授权里面配置白名单添加你服务器的ip地址~~~切记~

[微信小程序] 微信小程序经纬度逆解析地理位置