it编程 > 编程语言 > Javascript

基于Vue+Node.js实现埋点功能全流程

11人参与 2025-04-24 Javascript

要实现用户访问量统计和模块点击统计功能,可以采用以下方案:

一、前端(vue)实现

1. 安装必要的依赖

npm install axios --save  # 用于发送请求
npm install js-cookie --save  # 用于识别用户

2. 创建埋点工具类 (tracker.js)

import axios from 'axios';
import cookies from 'js-cookie';

const tracker = {
  // 初始化用户id(如果不存在)
  inituserid() {
    let userid = cookies.get('user_id');
    if (!userid) {
      userid = 'user_' + math.random().tostring(36).substr(2, 9);
      cookies.set('user_id', userid, { expires: 365 });
    }
    return userid;
  },

  // 发送页面访问埋点
  trackpageview() {
    const userid = this.inituserid();
    const data = {
      userid: userid,
      eventtype: 'pageview',
      pageurl: window.location.href,
      timestamp: new date().toisostring()
    };
    this.senddata(data);
  },

  // 发送模块点击埋点
  trackmoduleclick(modulename) {
    const userid = this.inituserid();
    const data = {
      userid: userid,
      eventtype: 'module_click',
      modulename: modulename,
      timestamp: new date().toisostring()
    };
    this.senddata(data);
  },

  // 发送数据到后端
  senddata(data) {
    axios.post('/api/track', data)
      .catch(error => {
        console.error('tracking error:', error);
      });
  }
};

export default tracker;

3. 在vue应用中使用

全局埋点 (main.js)

import tracker from './utils/tracker';
import router from './router';

// 页面访问埋点
router.aftereach((to, from) => {
  tracker.trackpageview();
});

// 挂载到vue原型,方便组件内使用
vue.prototype.$tracker = tracker;

组件内模块点击埋点

<template>
  <div>
    <button @click="handleclick('module1')">模块1</button>
    <button @click="handleclick('module2')">模块2</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleclick(modulename) {
      // 业务逻辑...
      
      // 埋点
      this.$tracker.trackmoduleclick(modulename);
    }
  }
}
</script>

二、后端(node.js)实现

1. 创建数据库表

假设使用mysql:

create table tracking_events (
  id int auto_increment primary key,
  user_id varchar(255),
  event_type varchar(50),
  page_url varchar(500),
  module_name varchar(100),
  created_at timestamp default current_timestamp
);

create table daily_stats (
  id int auto_increment primary key,
  date date unique,
  total_visits int default 0,
  unique_visitors int default 0,
  created_at timestamp default current_timestamp,
  updated_at timestamp default current_timestamp on update current_timestamp
);

create table module_stats (
  id int auto_increment primary key,
  module_name varchar(100) unique,
  click_count int default 0,
  created_at timestamp default current_timestamp,
  updated_at timestamp default current_timestamp on update current_timestamp
);

2. node.js 后端接口 (express示例)

const express = require('express');
const bodyparser = require('body-parser');
const mysql = require('mysql2/promise');
const app = express();

// 数据库连接配置
const pool = mysql.createpool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'tracking_db',
  waitforconnections: true,
  connectionlimit: 10,
  queuelimit: 0
});

app.use(bodyparser.json());

// 埋点数据接收接口
app.post('/api/track', async (req, res) => {
  try {
    const { userid, eventtype, pageurl, modulename } = req.body;
    
    // 1. 记录原始事件
    await pool.query(
      'insert into tracking_events (user_id, event_type, page_url, module_name) values (?, ?, ?, ?)',
      [userid, eventtype, pageurl, modulename]
    );
    
    // 2. 如果是页面访问,更新每日统计
    if (eventtype === 'pageview') {
      await updatedailystats(userid);
    }
    
    // 3. 如果是模块点击,更新模块统计
    if (eventtype === 'module_click' && modulename) {
      await updatemodulestats(modulename);
    }
    
    res.status(200).send('ok');
  } catch (error) {
    console.error('tracking error:', error);
    res.status(500).send('internal server error');
  }
});

// 更新每日统计
async function updatedailystats(userid) {
  const today = new date().toisostring().split('t')[0];
  
  // 检查今天是否已有记录
  const [rows] = await pool.query('select * from daily_stats where date = ?', [today]);
  
  if (rows.length === 0) {
    // 新的一天,创建新记录
    await pool.query(
      'insert into daily_stats (date, total_visits, unique_visitors) values (?, 1, 1)',
      [today]
    );
  } else {
    // 更新现有记录
    // 检查用户今天是否已经访问过
    const [visits] = await pool.query(
      'select count(distinct user_id) as user_visited from tracking_events ' +
      'where event_type = "pageview" and date(created_at) = ? and user_id = ?',
      [today, userid]
    );
    
    const isnewvisitor = visits[0].user_visited === 0;
    
    await pool.query(
      'update daily_stats set total_visits = total_visits + 1, ' +
      'unique_visitors = unique_visitors + ? where date = ?',
      [isnewvisitor ? 1 : 0, today]
    );
  }
}

// 更新模块统计
async function updatemodulestats(modulename) {
  await pool.query(
    'insert into module_stats (module_name, click_count) values (?, 1) ' +
    'on duplicate key update click_count = click_count + 1',
    [modulename]
  );
}

// 获取统计数据的接口
app.get('/api/stats', async (req, res) => {
  try {
    // 总访问量
    const [totalvisits] = await pool.query('select sum(total_visits) as total from daily_stats');
    
    // 今日访问量
    const today = new date().toisostring().split('t')[0];
    const [todaystats] = await pool.query('select * from daily_stats where date = ?', [today]);
    
    // 热门模块
    const [popularmodules] = await pool.query(
      'select module_name, click_count from module_stats order by click_count desc limit 5'
    );
    
    res.json({
      totalvisits: totalvisits[0].total || 0,
      todayvisits: todaystats[0] ? todaystats[0].total_visits : 0,
      todayuniquevisitors: todaystats[0] ? todaystats[0].unique_visitors : 0,
      popularmodules: popularmodules
    });
  } catch (error) {
    console.error('error fetching stats:', error);
    res.status(500).send('internal server error');
  }
});

const port = 3000;
app.listen(port, () => {
  console.log(`server running on port ${port}`);
});

三、数据可视化

可以创建一个管理后台页面来展示这些统计数据:

<template>
  <div class="stats-dashboard">
    <h1>网站访问统计</h1>
    
    <div class="stats-grid">
      <div class="stat-card">
        <h3>总访问量</h3>
        <p class="stat-value">{{ stats.totalvisits }}</p>
      </div>
      
      <div class="stat-card">
        <h3>今日访问量</h3>
        <p class="stat-value">{{ stats.todayvisits }}</p>
      </div>
      
      <div class="stat-card">
        <h3>今日独立访客</h3>
        <p class="stat-value">{{ stats.todayuniquevisitors }}</p>
      </div>
    </div>
    
    <div class="popular-modules">
      <h2>热门模块</h2>
      <ul>
        <li v-for="(module, index) in stats.popularmodules" :key="index">
          {{ module.module_name }}: {{ module.click_count }} 次点击
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      stats: {
        totalvisits: 0,
        todayvisits: 0,
        todayuniquevisitors: 0,
        popularmodules: []
      }
    };
  },
  mounted() {
    this.fetchstats();
  },
  methods: {
    async fetchstats() {
      try {
        const response = await axios.get('/api/stats');
        this.stats = response.data;
      } catch (error) {
        console.error('error fetching stats:', error);
      }
    }
  }
};
</script>

<style>
.stats-dashboard {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background: #f5f5f5;
  padding: 20px;
  border-radius: 8px;
  text-align: center;
}

.stat-value {
  font-size: 24px;
  font-weight: bold;
  margin: 10px 0 0;
}

.popular-modules ul {
  list-style: none;
  padding: 0;
}

.popular-modules li {
  padding: 10px;
  background: #f0f0f0;
  margin-bottom: 5px;
  border-radius: 4px;
}
</style>

四、优化建议

这个方案提供了完整的从前端埋点到后端存储再到数据展示的全流程实现,你可以根据实际需求进行调整和扩展。

以上就是基于vue+node.js实现埋点功能全流程的详细内容,更多关于vue+node.js埋点功能的资料请关注代码网其它相关文章!

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

NodeJS的使用与NPM包管理器详解

04-24

React中控制子组件显示隐藏的两种方式及对比详解

04-24

JavaScript 获取 URL 中参数值的方法

04-24

uni-app实现热更新的详细操作步骤

04-24

前端发布缓存导致白屏几种解决方案总结

04-24

前端实现视频文件动画帧图片提取完整教程

04-24

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论