Laravel中基于单数据库表实现Ajax动态联动下拉框
嘿,我来帮你搞定Laravel里的下拉框联动!针对你的Location表(包含country、state、city字段),我分几个清晰的步骤给你拆解,保证能快速实现需求:
1. 先搞定模型和基础配置
首先确认你有对应的Location模型,如果还没有,直接用Artisan命令生成:
php artisan make:model Location
然后在模型里设置可填充字段,方便后续操作:
// app/Models/Location.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Location extends Model { protected $fillable = ['country', 'state', 'city']; }
2. 配置路由
打开routes/web.php,添加两个核心路由:一个用来展示表单页面,另外两个是异步获取联动数据的接口:
// 展示带联动下拉框的表单页面 Route::get('/location-selector', [LocationController::class, 'index']); // 根据选中的国家获取对应的州列表 Route::get('/fetch-states/{country}', [LocationController::class, 'fetchStates']); // 根据选中的州获取对应的城市列表 Route::get('/fetch-cities/{state}', [LocationController::class, 'fetchCities']);
3. 编写控制器逻辑
先生成控制器:
php artisan make:controller LocationController
然后在控制器里实现三个方法,分别负责渲染页面和返回异步数据:
// app/Http/Controllers/LocationController.php namespace App\Http\Controllers; use App\Models\Location; use Illuminate\Http\Request; class LocationController extends Controller { // 渲染表单页面,先把所有唯一的国家列表查出来 public function index() { $countries = Location::select('country') ->distinct() ->orderBy('country') ->get(); return view('location-selector', compact('countries')); } // 根据国家获取对应的州(去重排序) public function fetchStates($country) { $states = Location::select('state') ->where('country', $country) ->distinct() ->orderBy('state') ->get(); return response()->json($states); } // 根据州获取对应的城市(去重排序) public function fetchCities($state) { $cities = Location::select('city') ->where('state', $state) ->distinct() ->orderBy('city') ->get(); return response()->json($cities); } }
4. 编写Blade视图(前端联动逻辑)
创建resources/views/location-selector.blade.php,这里我们用jQuery来实现异步联动(你也可以换成Axios或者原生JS,逻辑一致):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Location Dropdown联动</title> <!-- 引入jQuery,也可以用你项目里已有的版本 --> <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script> </head> <body> <div style="padding: 20px;"> <h3>选择你的位置</h3> <div style="margin: 10px 0;"> <label>国家:</label> <select id="country-select" style="padding: 5px;"> <option value="">请选择国家</option> @foreach($countries as $country) <option value="{{ $country->country }}">{{ $country->country }}</option> @endforeach </select> </div> <div style="margin: 10px 0;"> <label>州/省:</label> <select id="state-select" style="padding: 5px;" disabled> <option value="">请先选择国家</option> </select> </div> <div style="margin: 10px 0;"> <label>城市:</label> <select id="city-select" style="padding: 5px;" disabled> <option value="">请先选择州/省</option> </select> </div> </div> <script> // 国家选择变化时,加载对应州列表 $('#country-select').on('change', function() { const selectedCountry = $(this).val(); if (selectedCountry) { $.ajax({ url: `/fetch-states/${selectedCountry}`, method: 'GET', dataType: 'json', success: function(response) { // 清空州下拉框,添加默认选项 $('#state-select').empty().append('<option value="">请选择州/省</option>'); // 清空城市下拉框并禁用 $('#city-select').empty().append('<option value="">请先选择州/省</option>').prop('disabled', true); // 遍历返回的州数据,添加到下拉框 response.forEach(state => { $('#state-select').append(`<option value="${state.state}">${state.state}</option>`); }); // 启用州下拉框 $('#state-select').prop('disabled', false); } }); } else { // 没选国家时,重置州和城市下拉框 $('#state-select').empty().append('<option value="">请先选择国家</option>').prop('disabled', true); $('#city-select').empty().append('<option value="">请先选择州/省</option>').prop('disabled', true); } }); // 州选择变化时,加载对应城市列表 $('#state-select').on('change', function() { const selectedState = $(this).val(); if (selectedState) { $.ajax({ url: `/fetch-cities/${selectedState}`, method: 'GET', dataType: 'json', success: function(response) { // 清空城市下拉框,添加默认选项 $('#city-select').empty().append('<option value="">请选择城市</option>'); // 遍历返回的城市数据,添加到下拉框 response.forEach(city => { $('#city-select').append(`<option value="${city.city}">${city.city}</option>`); }); // 启用城市下拉框 $('#city-select').prop('disabled', false); } }); } else { // 没选州时,重置城市下拉框 $('#city-select').empty().append('<option value="">请先选择州/省</option>').prop('disabled', true); } }); </script> </body> </html>
几个小提示
- 记得给Location表的
country和state字段加索引,这样大数据量下查询会更快 - 测试前确保你的Location表里有足够的测试数据(比如不同国家、对应州和城市的记录)
- 如果你的项目已经用了Axios,把jQuery的ajax换成Axios调用就行,逻辑完全一样
内容的提问来源于stack exchange,提问作者Diumanuel
相关产品推荐
相关产品推荐

