1. 程式人生 > >vue 實現省市區三級聯動

vue 實現省市區三級聯動

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>