zoukankan      html  css  js  c++  java
  • 基于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;
             fit-content;
            display: inline-flex;
        }
        .item:nth-of-type(1) {
            border-right: 1px solid @color-border;
        }
        .el-input {
             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

  • 相关阅读:
    Java-集合类源码List篇(二)
    规范输入
    Java 构造方法
    c语言函数实现交换两个数的值
    2015北京宇信易诚科技面试题
    Java中的访问控制
    2015大连华信校园招聘面试题--堆栈
    2015大连华信面试题OSI七层模型
    2015大连华信面试题二叉树、遍历
    2015大连华信面试题MVC框架
  • 原文地址:https://www.cnblogs.com/midnight-visitor/p/11151454.html
Copyright © 2011-2022 走看看