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/ 参考文章 甘特图配 ...
随机推荐
- NOIP游(GUNCU)记
小学奥数不会做 状压DP打不出 一脸懵逼 本来抱着一个拿省一的心态去考的,结果DAY1刚开始就爆炸了. T1居然想了半个小时多没思路,然后打了个表,可能是应为太紧张了吧,居然打了表之后还没有看出规律来 ...
- ModelSerializer 使用知识点_serializer.save(project=obj) #外键一定要作为实例传入save函数,否则无法新增成功
1.有两个模型如下 A.project class Project(models.Model): """ 项目表 """ id = mode ...
- 微信小程序访问后台出现 对应的服务器证书无效。控制台输入 showRequestInfo() 可以获取更详细信息。
检查微信开发者平台配置 https 服务端 nginx 配置 ssl 协议是否有效 在开发者工具中可以使用(详情 > 不校验合法域名.web-view(业务域名).TLS 版本以及 HTTPS ...
- 【TIL】today i learned
20191115 JSON解析网站 https://www.json.cn/ 方便简洁,左侧放JSON表达式,右侧自动解析 联系英文盲打网站 https://www.keybr.com/ 字母 ...
- 从头开始学习Vuex
一.前言 当我们的应用遇到多个组件共享状态时,会需要多个组件依赖于同一状态抑或是来自不同视图的行为需要变更同一状态.以前的解决办法: a.将数据以及操作数据的行为都定义在父组件; b.将数据以及操作数 ...
- iOS SDK开发之 .a静态库
查看.framework静态库的生成及使用单击此处 注:这篇教程将只使用一小部分Objective-C代码,本文主要讲解从开始到应用的详细步骤.环境:xcode 9.2下面我们开始操作: 第一步:创建 ...
- fiddler之模拟请求超时和弱网模式
在针对手机端测试时,很多情况下我们需要测试响应超时和弱网情况的响应情况.此时可以使用fiddler提供的断点和弱网功能进行测试. 1.请求超时 设置断点,是请求响应超时.查看请求结果. Rules-- ...
- RESR API (一)之Requests
Requests 如果您正在做基于REST的Web服务,您应该忽略request.POST. - Malcom Tredinnick,Django开发团队 REST框架的Request类扩展了标准的H ...
- golang error (slice of unaddressable value)
使用 Golang 将生成的 md5 转化为 string 的过程出现如下编译错误: 错误解析: 值得注意的一点是 func Sum(data []byte) [Size]byte 这个函数返回的 ...
- Gradle原理动画讲解(五)
Gradle原理动画讲解