vue 實現省市區三級聯動
阿新 • • 發佈:2019-01-08
1. 省市區資料表
溫馨提示:該資料表未按 eslint 語法編寫,因此會報錯。事先將 eslint 關閉問題即可解決。
關閉方法:
找到 build>webpack.base.conf.js>module.exports>module>rules
刪除以下程式碼:
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter' )
}
},
2. 選擇城市元件程式碼
<template>
<div class="city-select">
<select v-model="selectedProvince" name="province" class="select">
<option disabled value="">請選擇省</option>
<option v-for="(item, index) in provinces"
v-if="item.level === 1"
:value="item">
{{ item.name }}
</option>
</select>
<select v-model="selectedCity" name="city" class="select">
<option disabled value="">請選擇市</option>
<option
v-for="(item, index) in cities"
:value="item">
{{ item.name }}
</option>
</select>
<select v-model="selectedBlock" name="block" class="select">
<option disabled value="">請選擇區</option>
<option
v-for="(item, index) in blocks"
:value="item">
{{ item.name }}
</option>
</select>
</div>
</template>
<script>
/**
* 省 市 區/縣城 三聯動選擇器
*/
import provinces from './provinces.js'
export default {
name: 'app',
created () {
},
watch: {
selectedProvince (newVal, oldVal) {
// 港澳臺資料只有一級,特殊處理
if (newVal.sheng === '71' || newVal.sheng === '81' || newVal.sheng === '82') {
this.cities = [newVal]
this.blocks = [newVal]
} else {
this.cities = this.provinces.filter(item => {
if (item.level === 2 && item.sheng && newVal.sheng === item.sheng) {
return true
}
})
}
var _this = this
// 此時在渲染DOM,渲染結束之後再選中第一個
this.$nextTick(() => {
_this.selectedCity = _this.cities[0]
_this.$emit('input', _this.info)
})
},
selectedBlock () {
var _this = this
this.$nextTick(() => {
_this.$emit('input', _this.info)
})
},
selectedCity (newVal) {
// 選擇了一個市,要選擇區了 di是城市的代表,sheng
if (newVal.sheng === '71' || newVal.sheng === '81' || newVal.sheng === '82') {
this.blocks = [newVal]
this.cities = [newVal]
} else {
this.blocks = this.provinces.filter(item => {
if (item.level === 3 && item.sheng && item.sheng === newVal.sheng && item.di === newVal.di && item.name !== '市轄區') {
return true
}
})
}
var _this = this
this.$nextTick(() => {
_this.selectedBlock = _this.blocks[0]
// 觸發與 v-model相關的 input事件
_this.$emit('input', _this.info)
})
}
},
computed: {
info () {
return {
province: this.selectedProvince,
city: this.selectedCity,
block: this.selectedBlock
}
}
},
data () {
return {
selectedProvince: '',
selectedCity: '',
selectedBlock: '',
cities: 0,
provinces,
blocks: 0
}
}
}
</script>
<style scoped>
.city-select{
display: -webkit-flex;
display: flex;
justify-content: space-between;
width: 416px;
}
.select{
height: 48px;
border: 1px solid #ccc;
border-radius: 2px;
padding-left: 16px;
padding-right: 46px;
position: relative;
}
.select-icon{
display: inline-block;
width: 40px;
height: 48px;
background: #f2f2f2;
position: absolute;
top: 0;
right: 0;
border: 1px solid #d7d7d7;
}
</style>
3. 父級元件程式碼
<template>
<div>
<select-city v-model="cityInfo" class="select-city" @input="chooseAddress"></select-city>
</div>
</template>
<script>
import SelectCity from './selectCity'
export default {
components: {
SelectCity
},
data () {
return {
}
},
methods: {
// info 為子元件傳遞過來的引數
chooseAddress (info) {
console.log('info', info)
this.cityInfo = info
},
},
computed: {
//cityName 為選擇的省市區名稱
cityName() {
const names = [];
this.cityInfo.province && names.push(this.cityInfo.province.name + ' ')
this.cityInfo.city && names.push(this.cityInfo.city.name + ' ')
this.cityInfo.block && names.push(this.cityInfo.block.name + ' ')
return names.join('')
}
}
}
</script>