You need to enable JavaScript to run this app. Laravel + Vue 如何基于eloquent-viewable实现文章访问量统计
优惠活动
大模型
产品
解决方案
定价
更多

Laravel + Vue 如何基于eloquent-viewable实现文章访问量统计

可落地方案说明

你之前用的eloquent-viewable包完全适配Laravel+Vue的前后端分离架构,不需要完全重写计数逻辑,只需要调整触发计数的时机即可,整体改造成本非常低。

1. 复用原有包的基础配置

  • 之前在纯Laravel项目里配好的内容全部保留:Article模型引入的Viewable trait、views表的数据库结构、$article->views()的查询逻辑都不需要改动
  • 移除app/Http/Kernel.php中挂在全局路由组下、由eloquent-viewable包提供的自动记录中间件——这个中间件原本是给服务端渲染场景用的,前后端分离场景下如果不删掉,会导致列表请求、鉴权请求等非文章详情的接口访问都被误计为文章浏览量,数据完全失真

注意:如果之前项目里开启了包的IP/Session去重规则,需要给前端的axios实例配置withCredentials: true,让跨域请求能正常携带Laravel的Session Cookie,否则去重逻辑会失效,同一用户每次打开文章都会被计为新的访问。

2. 后端新增独立的访问上报接口

不要把计数逻辑混在文章详情的GET查询接口里,否则会出现前端命中浏览器缓存、或者预取资源时根本不发GET请求导致的漏计数问题。

  • 在routes/api.php中新增独立的POST上报路由,搭配Laravel自带的限流中间件防止刷量:
use App\Http\Controllers\ArticleController;

Route::post('/articles/{article}/increment-view', [ArticleController::class, 'incrementView'])
    ->middleware('throttle:10,1');
  • 对应控制器的方法逻辑非常简单,直接调用eloquent-viewable包自带的记录方法即可:
public function incrementView(Article $article)
{
    // 自动处理去重、访问来源记录,和纯Laravel项目里的逻辑完全一致
    $article->view();

    return response()->json([
        'code' => 0,
        'data' => [
            'total_views' => $article->views()
        ]
    ]);
}

为什么要单独拆接口?因为GET类的详情接口很容易被浏览器、CDN、前端预取逻辑缓存,把计数逻辑放在这里会出现计数不准的问题;独立的POST接口不会被缓存,能保证计数触发的准确性。

3. 前端Vue端接入触发逻辑

  • 直接在文章详情页的组件生命周期钩子中调用上报接口即可,不要阻塞页面主渲染流程:
// Vue3 示例代码
import { onMounted } from 'vue'
import axios from 'axios'

const props = defineProps({
  articleId: Number
})

onMounted(() => {
  // 异步上报,不影响页面加载速度
  axios.post(`/api/articles/${props.articleId}/increment-view`)
})
  • 可选优化:如果站点用户量大,可以把axios请求替换为navigator.sendBeacon发送上报,这个方法专门用于埋点场景,就算用户中途路由跳转、关闭页面,请求也能稳定送达,不会被浏览器主动取消:
// 替换axios调用为sendBeacon
navigator.sendBeacon(`/api/articles/${props.articleId}/increment-view`)
  • 可以搭配本地SessionStorage做简单的会话级去重:同一个用户在同一次浏览会话里反复打开同一篇文章,不重复发上报请求,减少无效接口压力。

极简替代方案(不想依赖第三方包时)

如果你的计数逻辑不需要去重、不需要记录访问来源,只需要简单的累加计数:

  • 给articles表加一个views_count无符号整数字段,默认值为0
  • 上报接口的逻辑直接改成:
public function incrementView(Article $article)
{
    Article::where('id', $article->id)->increment('views_count');
    return response()->json(['code' => 0, 'data' => ['total_views' => $article->views_count]]);
}

这种方案没有任何第三方依赖,逻辑更简单,只是缺少包自带的精细化统计能力,适合需求非常简单的小型站点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 07:15:03