基于elementUI使用v-model实现经纬度输入的vue组件
- 绑定一个 [12.34,-45.67] (东经西经,南纬北纬 正负表示) 形式的经纬度数组,能够按度分秒进行编辑,效果如下所示,点击东经,北纬可切换。
- 经纬度的 度转度分秒
- 能够获取度分秒格式数据

Coordinates组件实现 Coordinates.vue
模板:一个span显示东经西经,三个输入框输入度分秒
<template>
<div class="coordinates">
<!-- 经度 -->
<div class="item">
<span class="itude"
@click="itudeChange(true)">{{ longFlag | longitudeName }}</span>
<el-input v-model.number="longitude[0]"
@change="change(true,0)"
size="mini">
<i slot="suffix">°</i>
</el-input>
<el-input v-model.number="longitude[1]"
@change="change(true,1)"
size="mini">
<i slot="suffix">′</i>
</el-input>
<el-input v-model.number="longitude[2]"
@change="change(true,2)"
size="mini">
<i slot="suffix">″</i>
</el-input>
</div>
<!-- 纬度 -->
<div class="item">
<span class="itude"
@click="itudeChange(false)">{{ latFlag | latitudeName }}</span>
<el-input v-model.number="latitude[0]"
@change="change(false,0)"
size="mini">
<i slot="suffix">°</i>
</el-input>
<el-input v-model.number="latitude[1]"
@change="change(false,1)"
size="mini">
<i slot="suffix">′</i>
</el-input>
<el-input v-model.number="latitude[2]"
@change="change(false,2)"
size="mini">
<i slot="suffix">″</i>
</el-input>
</div>
</div>
</template>
<script>
require('math');
export default {
name: 'Coordinates',
props: {
value: { //绑定的 value
type: Array,
require: true,
validator: function (value) {
let len = value.length > 0 && value.length === 2;
let isvalid = Math.abs(value[0]) < 180 && Math.abs(value[1]) < 90;
return len && isvalid
},
default: function () {
return []
}
}
},
// model: { // prop为 value 时不用实现 model 但是this.$emit(event,arg) 传入的event需要为 'input'
// prop: 'value',
// event: 'returnBack'
// },
data () {
return {
longitude: [], // 经度
latitude: [], // 纬度
longFlag: '+', //表示东经西经
latFlag: '+', //表示南纬北纬
}
},
created: function () {
this.initData();
},
filters: {
longitudeName (value) {
return value === '+' ? "东经" : "西经"
},
latitudeName (value) {
return value === '+' ? "南纬" : "北纬"
}
},
watch: {
/**
* 监测父组件绑定的value
*/
value () {
this.initData();
}
},
computed: {
// 转换为 东经 XXX°XX′XX″ 格式
// 返回一个经纬度的数组
formatString () {
let longitude = (this.longFlag === '+' ? "东经 " : "西经 ") + this.longitude[0] + '°' + this.longitude[1] + '′' + this.longitude[2] + '″';
let latitude = (this.latFlag === '+' ? "南纬 " : "北纬 ") + this.latitude[0] + '°' + this.latitude[1] + '′' + this.latitude[2] + '″';
return [longitude, latitude]
}
},
methods: {
/**
* 东经西经,南纬北纬 change事件
*/
itudeChange (flag) {
flag ? (this.longFlag = (this.longFlag === '+' ? '-' : '+')) : (this.latFlag = (this.latFlag === '+' ? '-' : '+'))
this.returnBackFn()
},
/**
* 初始化数据,父组件修改绑定的value时调用
*/
initData () {
this.longitude = this.D2Dms(Math.abs(this.value[0]));
this.latitude = this.D2Dms(Math.abs(this.value[1]));
this.longFlag = this.value[0] < 0 ? '-' : '+';
this.latFlag = this.value[1] < 0 ? '-' : '+'
},
/**
* 输入框change事件,数据合法性验证
*/
change (flag, index) {
let name = '', max = 0;
flag ? [name, max] = ['longitude', 179] : [name, max] = ['latitude', 89];
index ? max = 59 : null;
let value = parseInt(this[name][index], 10);
if (isNaN(value)) {
value = 0;
}
value = value < 0 ? 0 : value;
value = value > max ? max : value;
this.$set(this[name], index, value);
this.returnBackFn()
},
/**
* v-model 绑定事件 双向绑定实现
*/
returnBackFn () {
let longitude = parseFloat(this.longFlag + this.Dms2D(this.longitude));
let latitude = parseFloat(this.latFlag + this.Dms2D(this.latitude));
let array = [longitude, latitude];
this.$emit('input', array);
},
/**
* 度转度分秒
*/
D2Dms (d_data = 0) {
let degree = parseInt(d_data);
let min = parseInt((d_data - degree) * 60);
let sec = parseInt((d_data - degree) * 3600 - min * 60);
return [degree, min, sec];
},
/**
* 度分秒转度
*/
Dms2D (dms_data = [0, 0, 0]) {
let d = parseFloat(dms_data[0]);
let m = parseFloat(dms_data[1]);
let s = parseFloat(dms_data[2]);
return this.keepFourDecimal(d + m / 60 + s / 60 / 60);
},
/**
* 保留四位小数,小于四位精度可能丢失
*/
keepFourDecimal (num) {
let result = parseFloat(num);
if (isNaN(result)) {
return 0;
}
result = Math.round(num * 10000) / 10000;
return result;
}
},
}
</script>
<style lang="less" scoped>
@color-border: #9e9e9e;
@height: 28px;
.coordinates {
border: 1px solid @color-border;
width: fit-content;
display: inline-flex;
}
.item:nth-of-type(1) {
border-right: 1px solid @color-border;
}
.el-input {
width: 40px;
}
.itude {
height: @height;
line-height: @height;
display: inline-block;
padding-left: 5px;
cursor: pointer;
user-select: none;
}
i {
font-size: 18px;
color: gray;
}
</style>
<style lang="less">
.el-input__inner {
text-align: center;
border: none;
border-radius: unset;
}
.el-input--suffix .el-input__inner {
padding: 0;
}
</style>
测试代码 index.vue
<template>
<div id="example">
<Coordinates ref="coordinates"
v-model="value"></Coordinates>
<el-button @click="changeValue"
type="primary">
change value
</el-button>
<br>
<span>浮点数格式:{{value.toString()}}</span>
<br>
<span>度分秒格式:{{formatString.toString()}}</span>
<el-button @click="refresh"
type="primary">
refresh
</el-button>
</div>
</template>
<script>
import Coordinates from '@/components/Coordinates'
export default {
name: 'index',
components: {
Coordinates
},
data () {
return {
value: [116.3881,-39.9075],
formatString: []
}
},
mounted () {
this.refresh ()
},
methods: {
changeValue () {
this.$set(this.value, 0, (this.value[0] + 2) >= 180 ? 0 : (this.value[0] + 2))
this.$set(this.value, 1, (this.value[1] + 2) >= 90 ? 0 : (this.value[1] + 2))
setTimeout(() => {
refresh ()
}, 10);
},
refresh () {
// 获取度分秒格式
this.formatString = this.$refs.coordinates.formatString
}
}
}
</script>
<style lang="less" scoped>
#example {
padding: 20px;
}
.el-button {
margin: 20px;
}
span {
font-size: 17px;
}
</style>
综上,如有疑问请留言
借鉴:https://www.jb51.net/article/161080.htm
基于elementUI使用v-model实现经纬度输入的vue组件的更多相关文章
- 基于Element-UI的el-table,input框输入实现排序功能
最终效果如下 实现要求: 如果输入的内容不是非负整数,那么提示报错,并且将值变为输入前的内容: 如果输入正确,则当输入的内容发生改变并且失去焦点以后,触发事件,重新获取列表: 实现思路 使用原生的in ...
- ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则
原文:ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则 对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象, ...
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...
- 【转】基于LDA的Topic Model变形
转载自wentingtu 基于LDA的Topic Model变形最近几年来,随着LDA的产生和发展,涌现出了一批搞Topic Model的牛人.我主要关注了下面这位大牛和他的学生:David M. B ...
- 基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案
基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案 两个月前做C++课设的时候,电脑编译器编译结果出现了中文乱码,寻求了百度和大神们,都没有解决这个问题,百度上一堆解释是对编译器 ...
- 基于LDA的Topic Model变形
转载于: 转:基于LDA的Topic Model变形 最近有想用LDA理论的变形来解决问题,调研中.... 基于LDA的Topic Model变形 基于LDA的Topic Model变形最近几年来,随 ...
- 基于element-ui的多选下拉框和tag标签的二次封装
前言: 今年这大半年我主要负责公司的后台教务管理的开发,这个管理系统目前主要是给公司的内部人员去配置公司的核心项目(例如:熊猫小课)的所有数据,例如课程的配置.课程期数的配置.课程版本的配置.活动的配 ...
- 使用Vue CLI 3将基于element-ui二次封装的组件发布到npm
前言:之前在网上找的好多都是基于vue-cli 2.x的,而使用vue-cli 3的文章比较少,Vue CLI 3 中文文档,所以我在自己尝试的时候把几篇文章结合了一下,调出来了我想要的模式,也就是V ...
- 基于ElementUI,设置流体高度时,固定列与底部有间隙
基于ElementUI,设置流体高度时,固定列与底部有间隙问题,如下图: 解决办法: 1.fixed流体的高度设置为100% 2.将fixed的滚动内容的最大高度设置为none,bottom为 ...
随机推荐
- 消息中间件之zookper安装部署
消息中间件之zookper安装部署jdk可以在官网或者网上下载[root@q tools]# chmod 755 jdk-8u40-linux-x64.rpm [root@q tools]# rpm ...
- 深入理解TCP建立和关闭连接
建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...
- 如何用hugo 搭建博客
1,Hugo 简介 搭建个人博客有很多开源的博客框架,我们要介绍的框架叫作Hugo.Hugo 是一个基于Go 语言的框架,可以快速方便的创建自己的博客. Hugo 支持Markdown 语法,我们可以 ...
- 已有项目接入git远程仓库
1.项目根目录初始化git仓库 git init 2.将本地项目与远程仓库关联(首先得在远程创建一个代码仓库) git remote add origin 远程仓库地址 诺,仓库地址就是这个玩意 3. ...
- ELK收集日志到mysql数据库
场景需求 在使用ELK对日志进行收集的时候,如果需要对数据进行存档,可以考虑使用数据库的方式.为了便于查询,可以同时写一份数据到Elasticsearch 中. 环境准备 CentOS7系统: 192 ...
- Vector shrink 请求容器降低其容量和size匹配 shrink_to_fit();
一.先从size 和capacity 说起 resize(),设置大小(size); reserve(),设置容量(capacity); size()是分配容器的内存大小,而capacity()只是设 ...
- Codeforce 1311A Add Odd or Subtract Even
Add Odd or Subtract Even time limit per test2 seconds memory limit per test256 megabytes inputstanda ...
- App 自动化环境搭建
1.安装 Appium-desktop 工具 下载地址:https://github.com/appium/appium-desktop/releases 2.安装 Android 环境 安装 JDK ...
- Element upload组件上传图片与回显图片
场景:新增商品时需要添加商品主图,新增成功之后可编辑 上传图片: <el-form-item label="专区logo:" style="height:160px ...
- 解决Vue中文本输入框v-model双向绑定后数据不显示的问题
前言 项目中遇到一个问题就是在Vue中双向绑定对象属性时,手动赋值属性后输入框的数据不实时更新的问题. <FormItem label="地址" prop="eve ...