You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel项目如何实现无刷新切换搜索城市的天气展示功能?

Laravel无刷新更新天气组件实现方案

1. 后端接口适配

1.1 新增专属查询路由

在routes/api.php中添加登录用户才能访问的天气查询路由:

use App\Http\Controllers\WeatherController;

Route::get('/weather/search', [WeatherController::class, 'search'])->middleware('auth');

1.2 实现查询控制器

新建WeatherController处理查询逻辑,避免和首页路由耦合:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class WeatherController extends Controller
{
    public function search(Request $request)
    {
        // 参数校验
        $validated = $request->validate([
            'city' => 'required|string|max:50'
        ]);
        
        $apiKey = config('services.api.key');
        // 调用第三方天气API
        $weatherResponse = Http::get("你的天气API地址", [
            'q' => $validated['city'],
            'appid' => $apiKey,
            // 其他所需参数
        ]);
        
        // 异常处理
        if (!$weatherResponse->successful()) {
            return response()->json(['msg' => '天气查询失败,请检查城市名是否正确'], 400);
        }
        
        return response()->json($weatherResponse->json());
    }
}

注意:你原首页控制器中存在变量拼写错误,传递给视图的weatherRespons少了末尾的e,需修正为weatherResponse,否则视图会报变量未定义错误。

2. 前端视图调整

推荐用Laravel生态默认适配的AlpineJS实现状态管理,无需额外引入依赖,修改首页视图代码如下:

@guest
    <h1>login/register to show your city weather</h1>
@else
    <!-- 用Alpine管理天气数据状态 -->
    <div x-data="{
        weather: @js($weatherResponse),
        searchCity: ''
    }">
        <!-- 新增搜索表单 -->
        <div class="search-box">
            <input type="text" x-model="searchCity" placeholder="输入城市名">
            <button @click.prevent="
                fetch('/api/weather/search?city=' + encodeURIComponent(searchCity))
                .then(res => {
                    if (!res.ok) throw new Error('查询失败')
                    return res.json()
                })
                .then(data => {
                    weather = data
                    searchCity = ''
                })
                .catch(err => alert(err.message))
            ">查询天气</button>
        </div>

        <h1 x-text="`Weather in ${weather.city}`">Weather in {{ $weatherResponse['city'] }}</h1>
        <!-- 把天气组件套入可更新的容器,动态传递属性 -->
        <div id="weather-container">
            <x-weather :weatherResponse="$weatherResponse" />
        </div>
    </div>
@endguest

如果你的x-weather是静态Blade组件,需要把组件内部的模板也适配Alpine的响应式数据,或者在拿到接口返回的新数据后,手动替换#weather-container的HTML内容即可。

3. 可选优化项

  • 给搜索按钮加防抖逻辑,避免用户频繁点击触发重复请求
  • 接口侧增加缓存,相同城市的查询结果10分钟内复用,减少第三方API调用频次
  • 优化错误提示样式,替代原生alert弹窗,提升用户体验
  • 可将用户最近搜索的城市存在浏览器sessionStorage中,页面刷新后优先展示搜索记录,不会修改users表中用户绑定的默认城市

内容的提问来源于stack exchange,提问作者OsG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:27:00