方法一:4级地址选择器(基于elementui   Cascader 级联选择器) 推荐

效果图:

组件源码:

<template>
<div class="select-city" ref="selectCity">
<el-cascader
:options="options2"
@change="change"
v-model="selCity"
:props="props"
></el-cascader>
</div> </template> <style>
.select-city .el-input{
width: 350px;
}
</style> <script>
import addressData from 'common/json/class4new.json'
export default {
props: {
value: {
required: true
},
getCityName: { }
},
data() {
return {
options2: addressData,
props: {
label: 'name',
value: 'id',
children: 'children'
},
selCity: []
}
},
watch: {
value (val) {
this.init()
}
},
created() {
// 组件刚载入并不会触发watch value
},
methods: {
init() {
let el = this.$refs.selectCity
if (!this.value) {
if (this.selCity.length) {
this.selCity = []
el.getElementsByClassName('el-cascader__label')[0].innerHTML = ''
el.getElementsByClassName('el-input__inner')[0].setAttribute('placeholder', '请选择')
}
} else {
if (this.selCity.length===0 || this.selCity[3] !== this.value) {
this.selCity[0] = this.value.substr(0, 2) + '0000'
this.selCity[1] = this.value.substr(0, 4) + '00000000'
this.selCity[2] = this.value.substr(0, 6) + '000000'
this.selCity[3] = this.value
let name = this.getNode().join('<span>/</span>')
el.getElementsByClassName('el-cascader__label')[0].innerHTML = name
el.getElementsByClassName('el-input__inner')[0].setAttribute('placeholder', '')
}
}
},
change(val) {
// 只有选完了,才会将数据返回给父组件
this.$emit('input', val[3])
this.returnCityName()
},
returnCityName() {
if (typeof this.getCityName === 'function') {
this.getCityName(this.getNode().join(''))
}
},
getNode() {
let name = []
this.options2.filter(v => {
if (name[0]) return
if (v.id===this.selCity[0]) {
name.push(v.name)
v.children.filter(v => {
if (name[1]>0) return
if (v.id===this.selCity[1]) {
name.push(v.name)
v.children.filter(v => {
if (name[2]>0) return
if (v.id===this.selCity[2]) {
name.push(v.name)
v.children.filter(v => {
if (name[3]>0) return
if (v.id===this.selCity[3]) {
name.push(v.name)
return false
}
})
}
})
}
})
}
})
return name
}
}
}
</script>

方法二:4级地址选择器(基于elementui  select选择器 )

适用环境: PC

开发过程中遇到的问题:

1. 自定义组件如何做到双向数据绑定

2. 自定义组件在刚加载完毕,会执行一次created和mounted,当组件上绑定的v-model变化时候,也就是做编辑的时候,触发的watch监听的value方法

3.这个程序刚好是一个自循环,一旦更新了地址组件绑定的值立刻就触发this.$emit,把执行结果返回至父组件。这边需要visible-change(下拉框出现/隐藏时触发, 出现则为 true,隐藏则为 false),来组件地址组件数据的初始化,导致向父组件传递错误数据

小小的程序,把我折腾了好几天,仔细想想,两个2原因:1.缺少自己写组件的经历导致对vue的很多api不熟悉  2.缺乏独自面对困难的恒心

效果图:

地址组件代码:

<style>
.block .el-select{display: block;}
.block .el-select{margin-bottom: 20px}
</style> <template>
<div>
<div :class="{block: block}">
<el-select v-model="proviceCode" popper-class="tab-select" placeholder="请选择省" @change="proviceChange" @visible-change="vChange($event, 'provice')">
<el-option
v-for="(item, index) in provice"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-select v-model="cityCode" popper-class="tab-select" placeholder="请选择市" @change="cityChange" @visible-change="vChange($event, 'city')">
<el-option
v-for="(item, index) in city"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-select v-model="areaCode" popper-class="tab-select" placeholder="请选择区或县" @change="areaChange" @visible-change="vChange($event, 'area')">
<el-option
v-for="(item, index) in area"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-select v-model="villageCode" popper-class="tab-select" placeholder="请选择乡" @change="villageChange" @visible-change="vChange($event, 'village')">
<el-option
v-for="(item, index) in village"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<input type="hidden" :value="value">
</div>
</div>
</template> <script>
import address from 'common/json/class4new.json'
export default {
props: {
block: {
type: Boolean,
default: false
},
value: {
required: false
}
},
data() {
return {
provice: address,
city: [],
area: [],
village: [],
proviceCode: '',
cityCode: '',
areaCode: '',
villageCode: '',
isOpen: {
provice: false,
city: false,
area: false,
village: false
}
}
},
watch: {
value (val) {
if (val.code !== this.villageCode) {
this.init()
}
}
},
created() {
this.villageCode = this.value.code
this.init()
},
mounted () {
this.$root.eventHub.$on("reset-addressSelect", () => {
this.city = []
this.area = []
this.village = []
this.proviceCode = ''
this.cityCode = ''
this.areaCode = ''
this.villageCode = ''
})
},
methods: {
vChange(val, type) {
this.isOpen[type] = val
},
init() {
let code = this.value.code;
if (code) {
let v = code.toString()
this.proviceCode = v.substr(0,2) + '0000'
this.cityCode = v.substr(0,4)+'00000000'
this.areaCode = v.substr(0,6)+'000000'
this.villageCode = v
this.proviceChange(this.proviceCode).then(_ => {
this.cityChange(this.cityCode).then(_ => {
this.areaChange(this.areaCode)
})
})
} else {
this.city = []
this.area = []
this.village = []
this.proviceCode = ''
this.cityCode = ''
this.areaCode = ''
this.villageCode = ''
}
},
proviceChange(id) {
return new Promise((resolve, reject) => {
if (this.isOpen.provice) {
this.city = []
this.area = []
this.village = []
this.cityCode = ''
this.areaCode = ''
this.villageCode = ''
}
this.provice.filter(v => {
if (v.id === id) {
this.city = v.children
resolve()
return false
}
})
})
},
cityChange(id) {
return new Promise((resolve, reject) => {
if (this.isOpen.city) {
this.area = []
this.village = []
this.areaCode = ''
this.villageCode = ''
}
this.city.filter(v => {
if (v.id === id) {
this.area = v.children
resolve()
return false
}
})
})
},
areaChange(id) {
return new Promise((resolve, reject) => {
if (this.isOpen.area) {
this.village = []
this.villageCode = ''
}
this.area.filter(v => {
if (v.id === id) {
this.village = v.children
resolve()
return false
}
})
})
},
villageChange(id) {
var text = []
this.provice.filter(v => {
if (v.id === this.proviceCode) {
text.push(v.name)
return false
}
})
this.city.filter(v => {
if (v.id === this.cityCode) {
text.push(v.name)
return false
}
})
this.area.filter(v => {
if (v.id === this.areaCode) {
text.push(v.name)
return false
}
})
this.village.filter(v => {
if (v.id === id) {
text.push(v.name)
return false
}
})
this.$emit('input', {
text: text.join(''),
code: id
})
}
}
}
</script>

vue手动制作地址选择器的更多相关文章

  1. Windows 7 封装篇(一)【母盘定制】[手动制作]定制合适的系统母盘

    Windows 7 封装篇(一)[母盘定制][手动制作]定制合适的系统母盘 http://www.win10u.com/article/html/10.html Windows 7 封装篇(一)[母盘 ...

  2. Vue省市区三级联选择器V-Distpicker的使用

    Vue省市区三级联选择器V-Distpicker的使用 最近用的Vue+Element UI时,有些地方需要用到省市区三联选择器,网上安装并尝试了多种类似的插件,但都因为无法正常实现或是没有眼缘而弃用 ...

  3. 突破css选择器的局限,实现一个css地址选择器?

    首先看一个效果,注意地址栏的变化 然后思考一下,用css如何实现? css选择器的局限 选择器是css中的一大特色,用于选择需要添加样式的元素. 选择器的种类有很多,比如 元素选择器 p {color ...

  4. 通用js地址选择器

    用js实现通用的地址选择器,省份,城市,地区自动关联更新 点击下面查看详细代码: http://runjs.cn/code/s8sqkhcv 关键地址库代码: var addr_arr = new A ...

  5. WPF Excel导出加个手动修改地址

    http://blog.csdn.net/sanjiawan/article/details/6818921 以上是CSDN上的WPF Excel导入导出,我看到有人提问怎么能够手动选择地址,正好用到 ...

  6. 使用Vue.js制作仿Metronic高级表格(一)静态设计

    Metronic高级表格是Metonic框架中自行实现的表格,其底层是Datatables.本教程将主要使用Vue实现交互部分,使用Bootstrap做样式库.jQuery做部分用户交互(弹窗). 使 ...

  7. 定制一个类似地址选择器的view

    代码地址如下:http://www.demodashi.com/demo/12832.html 前言: 这几天也是闲来无事,看看有什么和Scroller相关的控件需要巩固下,原因很简单,前几天看到相关 ...

  8. CVE 2019 0708 安装重启之后 可能造成 手动IP地址丢失.

    1. 最近两天发现 更新了微软的CVE 2019-0708的补丁之后 之前设置的手动ip地址会变成 自动获取, 造成ip地址丢失.. 我昨天遇到两个, 今天同事又遇到一个.微软做补丁也不走心啊..

  9. HTML中使用Vue+Dhtmlxgantt制作任务进度图

    HTML中使用Vue+Dhtmlxgantt制作任务进度图 Dhtmlxgantt官网: https://dhtmlx.com/docs/products/dhtmlxGantt/ 参考文章 甘特图配 ...

随机推荐

  1. hdu_3466(01背包)

    其实,就是让C商品的q不等于p,其他都相同,这时,你就会发现如果要买C商品的话,肯定得先买C商品,因为买C商品的代价最大.所以,我们可以按照qi-pi的顺序来确定大顺序.这里我们还可以用更严谨的方式来 ...

  2. (65)CRC32校验C语言版本

    #include<iostream> # include <stdio.h> # include <string.h> typedef unsigned int u ...

  3. webpack插件之webpack-dev-server

    webpack插件之webpack-dev-server webpack插件 自动化 webpack-dev-server  现在只需要使用 npm run build指令就可以自动打包,并自动处理好 ...

  4. leetcode-mid-backtracking-17. Letter Combinations of a Phone Number

    mycode  68.26% class Solution(object): def letterCombinations(self, digits): """ :typ ...

  5. ORACLE同义词使用

    多用户协同开发中,可以屏蔽对象的名字及其持有者.如果没有同义词,当操作其他用户的表时,必须通过user名.object名的形式,采用了Oracle同义词之后就可以隐蔽掉user名, 当然这里要注意的是 ...

  6. 一元回归1_基础(python代码实现)

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003&u ...

  7. python检测编码

    # -*- coding: utf-8 -*- import chardet import urllib #可根据需要,选择不同的数据 TestData = urllib.urlopen('http: ...

  8. CircleCI 前端自动部署

    概述 现在很多前端库都用到了 CircleCI 进行自动部署,比如Vue,React,作为一个前端我觉得还是有必要实操一下 CircleCI 的,总体来说还是挺简单的,我把过程和体会记录下来,供以后开 ...

  9. vs2010 setup 打包 安装 BAT批处理实现自动安装软件功能

    CLS@echo offECHO.ECHO 安装 Diskeeper 7.0.428ECHO 请稍等...start /wait %systemdrive%\install\Applications\ ...

  10. Python基本语法_基本数据类型_数值型详解

    目录 目录 软件环境 Python变量调用的过程 数值型 删除一个数值类型对象 布尔型 Bool 标准整型 Int 长整型 双精度浮点型 Float 复数 数值类型对象的内建功能函数 absNumbe ...