最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

基于elementUI使用v-model实现经纬度输入的vue组件

来源:动视网 责编:小采 时间:2020-11-27 21:57:11
文档

基于elementUI使用v-model实现经纬度输入的vue组件

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

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

    模板

    一个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>

    实现

    props: 父组件传入的参数 value ,验证合法性 经度绝对值小于180,纬度绝对值小于90,数组长度为2

    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',这里要注意

    model: { 
     prop: 'value',
     event: 'input'
    },

    v-model实现: 使用this.$emit(event,arg)修改父组件的数据

    /**
     * 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);
    },

    Coordinates组件完整代码

    <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', ]
     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) {
     var degree = parseInt(d_data);
     var min = parseInt((d_data - degree) * 60);
     var 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) {
     var 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:{{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: [12.34, -45.67],
     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>

    效果

    修改子组件值 父组件的value会改变,修改父组件的value,子组件会自动修改, [change value] 按钮 可以修改value [refresh] 按钮 通过ref获取度分秒格式的经纬度

    总结

    以上所述是小编给大家介绍的基于elementUI使用v-model实现经纬度输入的vue组件,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

    文档

    基于elementUI使用v-model实现经纬度输入的vue组件

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

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top