省市区联动,又是一个常见的组件。一般来说,通过 select 元素的 onchange 事件来实现,难度不大。而如今换作 Vue 框架下,该如何实现呢?这正事我们接下来要探讨的,——但先请容我说,甚至比旧方法更简单!——这就是来自数据驱动——MVVM 的威力!

什么是数据驱动呢?往大的说,可以很大(fei hua),且不同场景或上下文之下有微妙差别的解释——而就本文一说,其概念所映射的实物便是 JSON。一旦观察到数据有任何异样(或说变动),所关联的 UI 也会实时地跟着改!却无须程序员给出半句 DOM 代码。于是我们这里,连过去所依靠 onchange 事件都不用写了。

我看过一些联动组件,虽然使用了 Vue.js 写就组件但是依旧绑定 DOM 的 change 事件,其实那大可不必,——使用数据驱动的话既优雅又简单。笔者的这个组件,总行数不超过 70 行。

在这里插入图片描述

在线例子:https://framework.ajaxjs.com/demo/form/China-area.html
源码在:https://gitee.com/sp42_admin/ajaxjs/blob/master/aj-ts/src/form/china-area.ts,约第 257 行,组件名称:aj-china-area。

使用方法

依赖 JS 文件:<script src="${ajaxjs_ui_output}/lib/China_AREA_full.js"></script>
直接使用: <aj-china-area></aj-china-area>
设置值:

<aj-china-area province-code="${info.locationProvince}" city-code="${info.locationCity}" district-code="${info.locationDistrict}">
</aj-china-area>

属性值:

属性含义类型是否必填,默认值
provinceCode省份代码Stringn
cityCode市代码Stringn
districtCode区代码Stringn

在这里插入图片描述
对于上图这种样式,加入下面的 CSS。

.aj-china-area span{
	clear: left;
    display: block;
    float: left;
    width: 60px;
}

存储在数据库的是 id,类型一般是 int。怎么在前台显示最终文字呢?这里用 JS 实现。

<script>
	document.write(China_AREA[86][${current.locationProvince}]);
	document.write(China_AREA[${current.locationProvince}][${current.locationCity}]);
	document.write(China_AREA[${current.locationCity}][${current.locationDistrict}])
</script>

数据来源

既然是省市区数据,必然有一数据提供之。我们选择 github 上提供中国行政区域数据:
https://github.com/dwqs/area-data
在这里插入图片描述
其 k/v 规律很容易找,就是一开始是 86 中国,然后找到省的 key,把 key 放到 China_AREA Hash 运算得到是所有的“市”,最后如此反复找到“区”。读者可自行理解一下该结构。

实现联动

首先第一个 select,显示的是所有的“省”,这个好办,就是将
addressData[86] 集合显示出来。Vue 的 v-for 模板指令除了可以遍历数组之外,还能遍历对象也就是 json。在这里插入图片描述
怎么产生联动呢?当用户选择了下拉框内的一项,选择了一个“省”,那么同时就会在 Vue 帮助下修改了 data 数据的 province 项,这是在 v-model 这里声明的,
在这里插入图片描述
又因,“市”的下拉框,其数据源是绑定 citys 的,这个 citys 并非一个 JSON 数据而是一个 JS 方法,我们称为“计算方法(computed)”,目的是经过一系列的逻辑后返回的结果才是数据源。为什么那样?因为逻辑如果一行不能写完,而要在标签上写完多行,不是不可以,但维护和编写(转义够麻烦的)足够痛苦的,故干脆弄一个 JS 方法,你自己去写好了。Vue computed 项表示这里的方法是计算方法,可以在模板中引用执行,同样 v-for 也可以。
在这里插入图片描述
于是,市的数据改了,区的数据也跟着改,所谓“联动”即可体现出来了。

进一步完善

选择了某个省之后,再选择另外一个省,市不能显示默认的第一个“请选择”,如下图,
在这里插入图片描述
我们把这个小问题解决了,思路是,只要上一级数据变动了,下一级就恢复默认“请选择”,这时 Vue 的 watch 监视特性正好可派上用场。
在这里插入图片描述
通过 v-modeloption value 的值是与数据 data.city/district 一一对应的,于是只要将数据设为 “” 即可令到 option 自动匹配并选中,加上 selected 属性。

props/data 区别与联系

Vue 规定 props 是组件的属性,一般输入用,之后不会发生变化,而 data 是允许经常可变的——这是它们之间的区别。故两者用途不太一样,有时候需要联合一起使用,即 props 可作为 data 的初始输入数据,——只要它们的名字不一样就好:
在这里插入图片描述
当然,也可以在 props 定义 default 默认值,而不是像我 || '' 那般操作。

各位亲,简单的联动组件说到这里,有任何问题建议或者意见欢迎于下方留言:)

Logo

前往低代码交流专区

更多推荐