在运营小程序推广活动时,我们经常遇到这样的需求:同一个活动页面,需要根据不同的推广渠道展示不同的内容。比如你是某连锁奶茶店的运营,想在大学城搞"开学季第二杯半价"活动,需要给A校区发带"校区=A"参数的二维码,给B校区发带"校区=B"的二维码。这时候如果给每个校区单独开发页面,不仅效率低下,后期维护更是噩梦。
我去年帮一个连锁健身房做小程序时就踩过这个坑。最初给每家分店都单独做了页面,结果活动规则变动时要改20多个页面,差点没被开发同事打死。后来改用二维码传参方案,维护成本直接降了90%。
二维码动态传参的核心优势在于:
首先登录微信公众平台,在左侧菜单找到"开发->开发管理",页面最下方有个"扫普通链接二维码打开小程序"的选项。这里有个坑要注意:必须先用管理员账号扫码验证才能开启功能。
开启后会看到"添加规则"按钮,点击进入配置页面。这里有几个关键字段容易填错:
https://yourdomain.com/activitypages/activity/index提示:测试链接可以用
https://yourdomain.com/activity?test=1这样的带参链接,方便调试
配置完成后,微信会给你一个固定格式的跳转链接,形如:
code复制https://wxaurl.cn/xxxxx?q=https://yourdomain.com/activity
我们需要在这个链接后面拼接参数。假设要传递活动ID和用户ID:
javascript复制const baseUrl = 'https://wxaurl.cn/xxxxx?q=https://yourdomain.com/activity';
const params = `?activity_id=2023summer&user_id=12345`;
const finalUrl = baseUrl + encodeURIComponent(params);
实测发现三个编码细节要注意:
encodeURIComponent编码在uniapp中,我们通过页面的onLoad生命周期获取参数。这里有个常见误区:很多人以为直接取options就能拿到参数,其实需要先解码:
javascript复制onLoad(options) {
// 打印原始参数对象
console.log('原始参数:', options);
// 关键步骤:解码q参数
const decodedUrl = decodeURIComponent(options.q || '');
if (!decodedUrl) return;
// 提取查询参数
const params = this.parseUrlParams(decodedUrl);
console.log('解析后的参数:', params);
// 使用参数
if (params.activity_id) {
this.loadActivityData(params.activity_id);
}
}
分享一个我优化过的参数解析函数,解决了三个常见问题:
javascript复制methods: {
parseUrlParams(url) {
let queryString = '';
// 处理同时包含?和#的情况
if (url.includes('?')) {
queryString = url.split('?')[1];
if (queryString.includes('#')) {
queryString = queryString.split('#')[0];
}
} else if (url.includes('#')) {
queryString = url.split('#')[1];
}
const params = {};
queryString.split('&').forEach(pair => {
const [key, value] = pair.split('=');
if (key) {
// 处理数组参数如a[]=1&a[]=2
if (key.endsWith('[]')) {
const realKey = key.slice(0, -2);
params[realKey] = params[realKey] || [];
params[realKey].push(decodeURIComponent(value || ''));
} else {
params[key] = decodeURIComponent(value || '');
}
}
});
return params;
}
}
开发阶段最容易卡在调试环节。推荐我的调试三板斧:
q=编码后的URL遇到参数获取不到时,可以按这个检查清单排查:
去年我们小程序就遭遇过二维码参数被篡改的攻击。分享几个防护经验:
javascript复制// 生成签名
const crypto = require('crypto');
function signParams(params, secret) {
const str = Object.keys(params)
.sort()
.map(k => `${k}=${params[k]}`)
.join('&');
return crypto.createHash('md5').update(str + secret).digest('hex');
}
// 验证签名
function verifyParams(params, secret) {
const clientSign = params.sign;
delete params.sign;
return clientSign === signParams(params, secret);
}
对于需要根据参数动态路由的场景,可以在app.vue的onLaunch里处理:
javascript复制onLaunch: function(options) {
if (options.query && options.query.q) {
const params = this.parseUrlParams(decodeURIComponent(options.query.q));
if (params.redirect) {
uni.redirectTo({ url: params.redirect });
}
}
}
使用uniapp的二维码生成插件可以实现在小程序内生成带参二维码:
javascript复制const QRCode = uni.requireNativePlugin('QRCode');
QRCode.generate({
content: 'https://yourdomain.com/activity?from=miniProgram',
size: 200,
success: (res) => {
this.qrPath = res.path;
}
});
这种方案特别适合线下门店场景,店员可以直接在小程序内生成带自己工号的二维码,方便统计业绩。