How to perform form area selection and cascade linkage in Vue

How to perform form area selection and cascade linkage in Vue

It is a common requirement to implement form region selection and cascading linkage in Vue. Users often need to fill in regional information, and a simple selection box often cannot meet the complex regional data structure. The following will introduce how to use Vue to implement form region selection and cascade linkage.

Insert image description here

1. Data preparation

First, we need to prepare regional data. Regional data is generally organized in a tree structure, for example:

[
  {
    
    
    "id": 1,
    "name": "中国",
    "children": [
      {
    
    
        "id": 11,
        "name": "北京",
        "children": [
          {
    
    
            "id": 111,
            "name": "东城区"
          },
          {
    
    
            "id": 112,
            "name": "西城区"
          },
          // 其他区县
        ]
      },
      {
    
    
        "id": 12,
        "name": "上海",
        "children": [
          {
    
    
            "id": 121,
            "name": "黄浦区"
          },
          {
    
    
            "id": 122,
            "name": "徐汇区"
          },
          // 其他区县
        ]
      },
      // 其他省份或直辖市
    ]
  },
  // 其他国家
]

We can save this data in a JSON file and get it in Vue through methods such as Ajax or Axios.

2. Vue components

Next, we create a Vue component for form area selection and cascading linkage.

<template>
  <div>
    <select v-model="selectedCountry" @change="onCountryChange">
      <option v-for="country in countries" :key="country.id" :value="country.id">{
   
   { country.name }}</option>
    </select>

    <select v-model="selectedProvince" @change="onProvinceChange">
      <option v-for="province in provinces" :key="province.id" :value="province.id">{
   
   { province.name }}</option>
    </select>

    <select v-model="selectedDistrict">
      <option v-for="district in districts" :key="district.id" :value="district.id">{
   
   { district.name }}</option>
    </select>
  </div>
</template>

<script>
export default {
      
      
  data() {
      
      
    return {
      
      
      countries: [],
      provinces: [],
      districts: [],
      selectedCountry: null,
      selectedProvince: null,
      selectedDistrict: null
    };
  },
  mounted() {
      
      
    // 获取地区数据并初始化第一个下拉框
    this.fetchCountries();
  },
  methods: {
      
      
    fetchCountries() {
      
      
      // 通过Ajax或Axios等方法获取地区数据,并赋值给countries
      // 这里为了简化示例,直接使用静态数据
      this.countries = [
        {
      
      
          "id": 1,
          "name": "中国"
        },
        // 其他国家
      ];
    },
    fetchProvinces(countryId) {
      
      
      // 根据countryId获取相应省份数据,并赋值给provinces
      // 这里为了简化示例,直接使用静态数据
      this.provinces = [
        {
      
      
          "id": 11,
          "name": "北京"
        },
        // 其他省份
      ];
    },
    fetchDistricts(provinceId) {
      
      
      // 根据provinceId获取相应区县数据,并赋值给districts
      // 这里为了简化示例,直接使用静态数据
      this.districts = [
        {
      
      
          "id": 111,
          "name": "东城区"
        },
        // 其他区县
      ];
    },
    onCountryChange() {
      
      
      // 当国家选择框改变时,重新获取对应的省份数据,并重置选中的省份和区县
      this.fetchProvinces(this.selectedCountry);
      this.selectedProvince = null;
      this.selectedDistrict = null;
    },
    onProvinceChange() {
      
      
      // 当省份选择框改变时,重新获取对应的区县数据,并重置选中的区县
      this.fetchDistricts(this.selectedProvince);
      this.selectedDistrict = null;
    }
  }
};
</script>

In the above code, we define a Vue component that contains three drop-down boxes for selecting countries, provinces, and districts. Through the v-model directive, we bind the selected values ​​of these three drop-down boxes, namely selectedCountry,, selectedProvinceand selectedDistrict. When selecting a country and province, the corresponding onCountryChangeand onProvinceChangemethod is triggered, the corresponding province and district and county data are reacquired based on the selected country and province, and the options of the drop-down box are updated.

3. Use components

Finally, we use the region selection component we just created in the parent component.

<template>
  <div>
    <h2>表单地区选择与级联联动</h2>
    <area-select></area-select>
  </div>
</template>

<script>
import AreaSelect from './AreaSelect.vue';

export default {
      
      
  components: {
      
      
    AreaSelect
  }
};
</script>

In this way, we have implemented a simple Vue form region selection and cascade linkage function. Users can select countries, provinces, and districts and counties through the drop-down boxes, realizing linked selection of three-level regions. According to actual needs, we can further expand and beautify the data and styles.

4. Optimization

We can also add some optimizations and improvements to the implementation of the above Vue form region selection and cascade linkage functions to make the user experience better.

1. Default prompt options

In the above code, when the user opens the form, the dropdown box is empty and has no default options. We can add a prompt option to let the user know what content needs to be selected. For example, you can add a "Please select" option at the top of each drop-down box.

<select v-model="selectedCountry" @change="onCountryChange">
  <option value="" disabled selected>请选择国家</option>
  <option v-for="country in countries" :key="country.id" :value="country.id">{
   
   { country.name }}</option>
</select>

<select v-model="selectedProvince" @change="onProvinceChange">
  <option value="" disabled selected>请选择省份</option>
  <option v-for="province in provinces" :key="province.id" :value="province.id">{
   
   { province.name }}</option>
</select>

<select v-model="selectedDistrict">
  <option value="" disabled selected>请选择区县</option>
  <option v-for="district in districts" :key="district.id" :value="district.id">{
   
   { district.name }}</option>
</select>

2. Get data asynchronously

In actual applications, obtaining regional data is often asynchronous and may need to be obtained from the server through network requests. In order to better handle asynchronous data, you can use Vue's asyncand awaitkeywords in combination with mountedhook functions to obtain data.

export default {
    
    
  // ...其他代码...
  async mounted() {
    
    
    // 异步获取地区数据
    await this.fetchCountries();
  },
  methods: {
    
    
    async fetchCountries() {
    
    
      try {
    
    
        // 模拟异步请求数据
        const response = await axios.get('/api/countries'); // 假设有一个API来获取国家数据
        this.countries = response.data;
      } catch (error) {
    
    
        console.error('Failed to fetch countries:', error);
      }
    },
    // ...其他方法...
  }
};

3. Optimize cascade linkage

In most cases, we can simplify user selection and make cascade linkage more intelligent. When the user selects the country and province, we can automatically select a default district or county, or provide several common options for the user to choose from based on actual needs.

async onProvinceChange() {
    
    
  // 当省份选择框改变时,重新获取对应的区县数据,并选择一个默认区县
  await this.fetchDistricts(this.selectedProvince);

  // 根据实际需求选择默认区县或者常见选项
  if (this.districts.length > 0) {
    
    
    this.selectedDistrict = this.districts[0].id; // 默认选择第一个区县
  } else {
    
    
    // 没有区县数据时,给出一些常见选项
    this.districts = [
      {
    
     id: 0, name: '其他区县1' },
      {
    
     id: 1, name: '其他区县2' },
      // 其他选项
    ];
    this.selectedDistrict = this.districts[0].id; // 默认选择第一个区县
  }
}

4. Data persistence

If the user needs to save data during the form filling process and be able to restore the selection state after the page is refreshed, we can use localStorageor sessionStorageto implement persistent storage of data.

In the component's beforeDestroyhook function, save the selected country, province, and district to localStorage:

beforeDestroy() {
    
    
  localStorage.setItem('selectedCountry', this.selectedCountry);
  localStorage.setItem('selectedProvince', this.selectedProvince);
  localStorage.setItem('selectedDistrict', this.selectedDistrict);
}

In the component's mountedhook function, read the previously saved options localStoragefrom it :

mounted() {
    
    
  // 异步获取地区数据
  await this.fetchCountries();

  // 从localStorage中读取之前保存的选项
  this.selectedCountry = localStorage.getItem('selectedCountry');
  this.selectedProvince = localStorage.getItem('selectedProvince');
  this.selectedDistrict = localStorage.getItem('selectedDistrict');
}

This way, the region the user selects when filling out the form will be retained across page refreshes.

In summary, through the above optimizations and improvements, we can achieve more intelligent, smooth and user-friendly Vue form region selection and cascade linkage functions. According to actual needs, we can further expand the functions and add search functions, multi-level linkage, etc. to meet the needs of more complex scenarios.

Guess you like

Origin blog.csdn.net/JasonXu94/article/details/131937934