vue手动制作地址选择器
方法一: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手动制作地址选择器的更多相关文章
- Windows 7 封装篇(一)【母盘定制】[手动制作]定制合适的系统母盘
Windows 7 封装篇(一)[母盘定制][手动制作]定制合适的系统母盘 http://www.win10u.com/article/html/10.html Windows 7 封装篇(一)[母盘 ...
- Vue省市区三级联选择器V-Distpicker的使用
Vue省市区三级联选择器V-Distpicker的使用 最近用的Vue+Element UI时,有些地方需要用到省市区三联选择器,网上安装并尝试了多种类似的插件,但都因为无法正常实现或是没有眼缘而弃用 ...
- 突破css选择器的局限,实现一个css地址选择器?
首先看一个效果,注意地址栏的变化 然后思考一下,用css如何实现? css选择器的局限 选择器是css中的一大特色,用于选择需要添加样式的元素. 选择器的种类有很多,比如 元素选择器 p {color ...
- 通用js地址选择器
用js实现通用的地址选择器,省份,城市,地区自动关联更新 点击下面查看详细代码: http://runjs.cn/code/s8sqkhcv 关键地址库代码: var addr_arr = new A ...
- WPF Excel导出加个手动修改地址
http://blog.csdn.net/sanjiawan/article/details/6818921 以上是CSDN上的WPF Excel导入导出,我看到有人提问怎么能够手动选择地址,正好用到 ...
- 使用Vue.js制作仿Metronic高级表格(一)静态设计
Metronic高级表格是Metonic框架中自行实现的表格,其底层是Datatables.本教程将主要使用Vue实现交互部分,使用Bootstrap做样式库.jQuery做部分用户交互(弹窗). 使 ...
- 定制一个类似地址选择器的view
代码地址如下:http://www.demodashi.com/demo/12832.html 前言: 这几天也是闲来无事,看看有什么和Scroller相关的控件需要巩固下,原因很简单,前几天看到相关 ...
- CVE 2019 0708 安装重启之后 可能造成 手动IP地址丢失.
1. 最近两天发现 更新了微软的CVE 2019-0708的补丁之后 之前设置的手动ip地址会变成 自动获取, 造成ip地址丢失.. 我昨天遇到两个, 今天同事又遇到一个.微软做补丁也不走心啊..
- HTML中使用Vue+Dhtmlxgantt制作任务进度图
HTML中使用Vue+Dhtmlxgantt制作任务进度图 Dhtmlxgantt官网: https://dhtmlx.com/docs/products/dhtmlxGantt/ 参考文章 甘特图配 ...
随机推荐
- 【BZOJ1098】办公楼biu(补图,bfs,链表)
题意:有n个点m条边,要求将点尽可能多的分成若干个部分,使得若两个点不在同一个部分则他们之间必定有边 n<=1e5,m<=2e6 思路:From https://blog.csdn.net ...
- Linux基本命令使用(一)
1.head -n 文件 可以查看文件前n行 tail -n 文件 可以查看文件的后n行 tail -f 文件 可以实时查看文件,比如日志在更新,就可以实时显示最后几行 ...
- (62)通信协议之一protobuf
Protobuf协议特点分析 KingKa.吴永聪 1.protobuf是什么? protobuf(Google Protocol Buffers)是Google提供的一个具有高效的协议数据交换格式 ...
- sqli-lab(14)
POST型的 双注入 0X01随便测试一下 在password输入"会报错 "#就不报错了 那么应该是“”的闭合 但是没有回显的值 只有报错的信息 那我们是不是该考虑从报错的语句 ...
- [CSP-S模拟测试]:格式化(贪心)
题目传送门(内部题105) 输入格式 每组数据第一行一个正整数$n$,表示硬盘块数,接下来$n$行,每行两个正整数,第一个正整数为硬盘格式化前的容量,第二个正整数为格式化之后的容量. 输出格式 对每组 ...
- 关于spotlight_on_oracle的配置及操作
Spotlight是一个强有力的Oracle数据库实时性能诊断工具,提供了一个直观的.可视化的数据库活动展现.Spotlight可视化展现性能瓶颈,一旦某个指标超出可接受的阀值的话.而且,通过下钻功能 ...
- mysq远程连接报错,host..
在本机登入mysql后,更改"mysql"数据库里的"user"表里的"host"项,从"localhost"改为'%' ...
- 如何设置linux bash终端的字符显示内容和颜色?
通常linux有1-6个字符终端 tty, 有1个图形终端. 通常用 ctrl+alt+f1 到f6是字符终端, ctrl+alt+f7为图形终端, 但是, 也有不一样的, 如: fedora的4.0 ...
- mysql 批量删表
Select CONCAT( 'drop table ', table_name, ';' ) FROM information_schema.tables Where table_name LIKE ...
- Apache监控调优
apache是一款对静态资源处理得比较好的中间件,但是对动态请求处理得不是很好,tomcat则正好相反. apache运用得比较多得工作模式主要是Prefork和Worker两种模式 1.Prefor ...
