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/ 参考文章 甘特图配 ...
随机推荐
- D. Treasure Island
D. Treasure Island dfs大法好== 写半天bfs疯狂MLE dfs标记掉路上的一些点 然后再跑一遍dfs #include<bits/stdc++.h> using n ...
- 测试常用命令之awk篇
awk/gawk 1,内置变量 FILENAME:输入文件名称 FNR:当前数据文件中的数据行数 NF:数据文件中的字段总数 NR:已处理的输入数据行数目 FS:输入数据段分隔符 RS:输入数据行分隔 ...
- crontab定时调度shell脚本
本人最近要用crontab做一个定时调度任务,调一个启动脚本去执行jar包,并给main方法传一个日期参数. Linux系统:CentOS7 输入: crontab -e 在里面编写: SHELL=/ ...
- json根据一个值返回对象,filter方法使用
d = { "student":[ { "count":1000, "stuList":[ ...
- angular 语法的应用
angular.js 一个js框架 , 是三大主流框架之一:( vue react angular ): 原先的开发:前端和后台,利用 Ajax 进行交互, 但是框架却提出了一种开发模式:mvc 这 ...
- oracle em启动问题
这种情况出现的可能性是(1)主机IP地址改变,(2)主机名改变,(3)移植到全新的主机,(4)监听程序未启动,5)oracle服务也检查一下 关于orcl的启动: emctl start dbcons ...
- centos下面配置key登录
centos下需要配置使用key登录,并且要禁止root登录 下面的操作都是用root来设置的 1.添加新用户 例如用户名leisiyuan useradd leisiyuan 2.设置密码 pass ...
- 在SOUI3.0中使用数值动画
上一篇介绍了插值动画,插值动画是直接作用于窗口对象的. 数值动画则可以作用于任何对象. SOUI内置了3种数值类型的动画,分别是SIntAnimator, SFloatAnimator, SColor ...
- JWT原理和使用
jwt JSON Web Tokens,是一种开发的行业标准RFC 7519,用于安全的表示双方之间的声明.目前,jwt广泛的用在系统的用户认证方面,特别是前后端分离项目. 1.jwt认证流程 在项目 ...
- 8.k8s.认证与访问控制
#K8S认证与访问控制(RBAC) 用户证书创建 #k8s认证 #主要认证 方式 http token.https证书 k8s不提供用户管理,API Server把客户端证书的CN字段作为User,把 ...
