uniapp小程序分享统一封装:Mixin接管onShareAppMessage避坑指南
小程序分享这个功能看着简单做起来全是坑。我在一个维护了将近一年的跨平台项目里光onShareAppMessage就见过十几种写法有的页面标题写死有的图片路径多加了个/有的分享参数漏掉了来源标记还有的页面复制了老代码但函数名拼错了导致右上角菜单压根不出现“转发”选项。后来我把这些逻辑全部收拢到一个统一分享 Mixin 里40 多个页面的分享行为从此只需要维护一份代码。这篇文章就完整记录一下这套方案的思路、代码和上线后踩过的坑希望能帮到还在每个页面里复制粘贴分享逻辑的人。这套方案适合正在用 uniapp 开发微信小程序、并且项目里页面数量已经多到开始让人头疼的开发者。无论你是 Vue2 还是 Vue3 的写法核心思路都通用用 mixin 把分享入口统一接管让页面只负责“告诉分享要放什么内容”而不是自己处理分享的完整逻辑。1. 为什么要把分享逻辑统一收拢到一个 Mixin1.1 复制粘贴式分享逻辑的四个致命伤先说痛点。很多人刚接触微信小程序分享时官方文档里给了onShareAppMessage的示例于是大家就在每个页面里照抄一份改改 title 和 path 就完事了。页面少的时候问题不大页面一多问题马上就来了。第一分享内容不一致。你很难保证 40 个页面的 title 风格统一有人写“某某小程序”有人写“某某平台”还有人直接留空微信就会默认显示“来自某某小程序”这种很没辨识度的文案。封面图更乱有人用默认截图有人传本地路径有人用外网https图片效果相差悬殊。第二路径和参数容易错。分享出去的path必须以/开头并且需要拼上?idxxfromxx这类参数。一旦拼错了 query或者漏掉了encodeURIComponent别人点开分享卡片就可能进错页面甚至直接白屏。这种问题在视觉上没法立刻发现只能等用户报障。第三函数名写错以后分享功能静默失效。微信小程序判定一个页面能不能转发就看页面实例上有没有onShareAppMessage这个生命周期。很多人在复制代码时把函数名改成onShareMessage或者写成了onShareAppMessage() {}却又把return丢掉了结果分享菜单还在但点转发时只有默认标题和截图。这种问题不打开开发者工具的控制台根本发现不了。第四修改成本极高。如果运营突然提出“所有分享图的角标要加上活动信息”你需要打开几十个页面逐个检查、逐个替换图片路径稍不留神就会漏掉一两个页面。分享逻辑分散在页面里本质上就是在给自己埋雷。1.2 Mixin 方案不只是在“省代码”Mixin 的全称是 Vue 的混入机制可以把一组公共配置、生命周期、方法注入到所有引用了它的页面组件中。用在分享场景里核心价值不是省几十行代码而是把“分享逻辑”从一个需要每个页面自行复制的行为变成一个默认已经存在的基础能力。你可以这样理解以前每个页面都需要自己回答“我要分享什么”而用 Mixin 之后全局已经给了一个默认答案页面只需要在特殊场景下回答“我要覆盖哪个字段”。这种“默认值 按需覆盖”的设计带来的直接好处就是新页面不需要关心分享细节老页面也方便统一改配置。在实际项目里我用这个方案把分享相关的代码量从每个页面十几行降到了零到三行。更重要的是严格的约定让分享行为有了唯一可查的入口排查问题的时候只需要看一个 mixin 文件。2. 先搞懂 onShareAppMessage 的运行机制再来写 Mixin2.1 微信小程序的分享回调是怎么触发的onShareAppMessage是微信小程序页面生命周期中的一个方法当用户点击右上角菜单里的“转发”按钮或者点击页面里button open-typeshare按钮时微信会主动调用这个方法并要求它返回一个对象这个对象就是分享卡片的完整内容。onShareAppMessage() { return { title: 分享标题, path: /pages/index/index?id123, imageUrl: /static/share.png, } }返回对象里有三个核心字段title分享卡片的标题最长限制大概在 30 个字符左右超出的部分会被截断。path好友点击卡片后进入的页面路径必须以/开头可以带 query 参数。imageUrl分享卡片封面图支持本地路径和网络路径网络路径必须是https而且域名需要在小程序后台配置到合法域名里。这三个字段里任何一个缺失微信都会用默认值顶上。默认标题通常就是小程序名称默认封面则是页面截图。所以很多项目里“分享出去一片空白截图”的问题本质上就是imageUrl没有配好。2.2 Mixin 为什么能统一接管Vue 选项合并规则很多人在最开始会有一个疑问onShareAppMessage是微信小程序的页面生命周期它又不是 Vue 的生命周期写在 mixin 里真的能生效吗这里需要理解 uniapp 的编译模型。uniapp 会在编译阶段把页面的 Vue 实例转换为微信小程序的 Page 配置页面实例上所有能被框架识别的生命周期钩子都会被收集并映射到微信小程序的 Page 构造函数里。当 mixin 被合并到页面实例后框架去读取这个页面实例时自然也能看到 mixin 里提供的onShareAppMessage。那如果页面自己也定义了onShareAppMessage到底以哪个为准这就要说 Vue 的选项合并规则了。Vue 对 mixin 和组件实例里的同名选项有一套明确的合并策略生命周期钩子会被合并成一个数组mixin 里的钩子先执行组件自己的钩子后执行data里的字段以组件实例优先mixin 里的同名 data 会被覆盖methods等对象类型选项组件实例里的同名方法会覆盖 mixin 里的方法。这里有一个隐藏在里面的坑onShareAppMessage虽然并不是 Vue 的生命周期但 uniapp 会按类似生命周期的规则去处理它。如果 mixin 和页面里都写了onShareAppMessage页面里的实现可能会覆盖 mixin 里的实现导致你辛苦做的统一逻辑被某几个页面悄悄“劫持”了。后面我会讲怎么避免这个问题。2.3 uniapp 里一个容易被忽略的编译细节还有一个非常容易踩的坑是onShareAppMessage不是你在页面的methods里随便定义一个函数就能生效的。在 uniapp 页面中onShareAppMessage必须出现在页面的顶层选项里跟data、onLoad平级而不是放在methods里。这一点很多从 Vue 传统写法转过来的人会搞混。mixin 之所以好用就是因为它正好可以把onShareAppMessage放在顶层通过 mixins 合并进页面顶层。如果把它放进methods微信端是收不到分享回调的因为框架根本不会把methods里的方法当成页面生命周期来处理。理解了这一层后面写出来的 mixin 才会真正有效。3. 完整代码实现从目录设计到页面接入3.1 目录结构与默认配置的规划先规划好文件位置。我习惯在src/mixins目录下单独建一个share.js专门放分享相关的混入逻辑。如果一个项目里同时有业务主端和管理端也可以拆成share.js和shareAdmin.js但通常情况下一个统一的share.js就够了。src ├── mixins │ └── share.js ├── pages │ ├── index │ │ └── index.vue │ └── detail │ └── detail.vue ├── static │ └── share-default.png └── main.jsstatic目录下我建议放一张默认分享图命名规则统一比如share-default.png。这张图会被大量页面用作默认封面所以最好设计成通用的品牌风格图尺寸控制在 750x750 左右在小程序分享卡片上显示效果最稳定。3.2 Mixin 核心代码一套默认分享 页面个性化钩子下面直接给出我在项目里用的版本。这个 mixin 的思路是默认提供一个完整的onShareAppMessage在每次分享时先读取页面上可能存在的getShareConfig()方法如果页面定义了这个方法就用它返回的内容覆盖默认值否则完全使用默认配置。// src/mixins/share.js // 这里的配置可以作为常量集中管理方便后续统一修改 const DEFAULT_TITLE 这是你的小程序品牌名 const DEFAULT_IMAGE_URL /static/share-default.png export default { onShareAppMessage() { // 1. 先用默认配置兜底 let shareData { title: DEFAULT_TITLE, imageUrl: DEFAULT_IMAGE_URL, path: , } // 2. 如果页面里定义了 getShareConfig说明页面有自定义需求 if (typeof this.getShareConfig function) { const custom this.getShareConfig() || {} shareData Object.assign({}, shareData, custom) } // 3. 如果页面没有显式传 path就自动取当前页面路径加上参数 if (!shareData.path) { shareData.path this.buildDefaultSharePath() } // 4. 最后兜底path 必须被正确拼出来否则分享出去也没法打开 if (!shareData.path) { shareData.path /pages/index/index } return shareData }, methods: { /** * 基于当前页面栈自动生成分享路径 * 思路拿到当前页面的 route 和 options拼出完整 path */ buildDefaultSharePath() { const pages getCurrentPages() if (!pages || pages.length 0) { return /pages/index/index } const currentPage pages[pages.length - 1] // route 字段就是类似 pages/index/index 的路径 let route currentPage.route || currentPage.__route__ || route route.startsWith(/) ? route : /${route} // 拿到当前页面的参数对象 const options currentPage.options || (currentPage.$page currentPage.$page.options) || {} // 过滤并编码参数 const queryString this.buildShareQuery(options) return ${route}${queryString} }, /** * 把参数对象转成 query 字符串 * 注意这里必须 encodeURIComponent否则特殊字符会导致路径损坏 */ buildShareQuery(options) { if (!options) return const parts [] for (const key in options) { if (Object.prototype.hasOwnProperty.call(options, key)) { const value options[key] // 跳过空值和复杂对象 if (value undefined || value null || value ) { continue } if (typeof value object) { continue } parts.push(${key}${encodeURIComponent(value)}) } } return parts.length 0 ? ?${parts.join()} : }, }, }这段代码有意识地处理了几个关键细节。第一getCurrentPages()拿到的页面实例上route可能带pages/前缀也可能带/pages/我统一做了开头补/的处理。第二当前页面的options是页面加载时从 query 解析出来的参数列表也可能是$page.options所以兼容了两种情况。第三参数过滤掉了空值和对象类型避免把[object Object]拼进分享链接。3.3 页面接入的三种方式与推荐做法页面接入我实际验证过几种方式各有适用场景。第一种是局部 mixin。在每个页面的script块里手动引入这是最稳定、最可控的方式推荐在实际项目里优先使用。// src/pages/index/index.vue script import shareMixin from /mixins/share.js export default { mixins: [shareMixin], data() { return {} }, } /script这种方式的好处是显式、安全。每个页面是否具备分享能力一眼就能看出来不会因为全局混入而影响其他非页面组件。代码上只多了一行 import 和一行 mixins成本极低。第二种是常见的局部覆盖。如果某个页面想发一套完全不同的分享文案不用去修改 mixin只要在页面里定义一个getShareConfig()方法即可export default { mixins: [shareMixin], methods: { getShareConfig() { return { title: 这个页面的专属分享标题, path: /pages/detail/detail?id9527fromdetail, imageUrl: /static/share-detail.png, } }, }, }mixin 里的onShareAppMessage在每次被微信触发时都会先检查当前页面实例上有没有getShareConfig所以页面的自定义配置是灵活的、动态的并且不用再关心函数名这些底层逻辑。第三种是全局注册。在main.js里执行Vue.mixin(shareMixin)理论上所有页面都能自动获得分享能力确实省事但我个人不太建议这么干。全局 mixin 会影响所有 Vue 组件包括页面的子组件。虽然大多数情况下子组件不会触发分享逻辑但在页面数特别多、组件命名容易冲突的项目里全局混入迟早会给你带来意外麻烦。与其去约束“公共组件不能命名冲突”不如用显式的局部 mixin把影响范围控制在页面级。Vue3 的项目里mixin 仍然可以使用语法和 Vue2 保持一致。如果你用的 uniapp 在 Vue3 模式下遇到 mixin 不生效的问题优先检查main.js里是否用createSSRApp正确创建了应用实例以及 mixin 文件是否被正确 import。大多数情况下Vue3 下的 mixin 机制与 Vue2 没有本质区别。3.4 分享 path 的拼接细节分享 path 是整个分享逻辑里最容易出错的地方我把常见场景单独拎出来说清楚。第一个是 tabBar 页面。微信小程序里 tabBar 页面默认不能带 query 分享如果你试图让分享路径变成/pages/index/index?fromshare好友点开后会直接落到 tabBar 页面的默认状态参数很可能丢失。遇到这种情况建议不要直接分享 tabBar 页面链接而是分享一个中转页由中转页读参数后再uni.redirectTo或uni.switchTab跳转到目标 tabBar 页这样参数才能完整传递。第二个是参数编码。分享链接里的中文、空格、、、#等字符都会破坏 URL 结构。我在实际项目里遇到过用户昵称里有#导致分享路径被截断点开卡片进入错误页面的情况。所以在拼接 query 时永远要记得用encodeURIComponent。上面的代码里已经做了如果你的业务需要自己在页面里拼 path也一定不要跳过这一步。第三个是默认分享路径的取舍。有些页面不需要带参数分享比如首页、活动落地页分享出去一个干净的链接反而更利于传播。如果当前页面的options里没有任何有效参数buildShareQuery会返回空字符串最终分享路径就是一个干净的页面 path这正好符合预期。如果页面预期一定要带fromshare这样的来源标记就需要在页面自己的getShareConfig里显式返回 path而不是依赖自动拼接。4. 上线实战中的常见问题与排查技巧4.1 页面右上角菜单没有“转发”按钮这是我被问得最多的问题。理论上页面里只要存在onShareAppMessage生命周期微信右上角菜单就会出现“转发”但实际项目中经常出现页面落到了真机上菜单里却没有转发项的情况。排查第一步先在开发者工具的控制台里看看当前页面是否真的挂载了分享回调。可以在页面的onLoad里加一行日志onLoad() { console.log(share hook exists:, typeof this.onShareAppMessage) }如果输出是function说明分享回调已经挂到页面实例上转发菜单不显示大概率是基础库或者真机缓存问题。如果输出是undefined那就要查 mixin 是否合并成功。常见原因是 mixin 文件路径写错、文件名大小写不一致或者页面组件在export default里没有正确声明mixins。还有一种情况需要注意uniapp 的某些编译版本对 mixin 里的生命周期识别不稳定尤其是从旧版本 HBuilderX 升级上来的老项目。如果做了各种排查还没解决可以在页面顶层临时写一个“兜底转发函数”让微信确保识别到分享入口// 页面内兜底写法配合 mixin 使用 onShareAppMessage() { return this.getDefaultShareMessage() }对应的mixin 里额外暴露一个getDefaultShareMessage方法把核心分享逻辑放进去。这样即使 mixin 里的onShareAppMessage没有被某些编译版本识别页面里的兜底函数也能指挥到同一套逻辑。这个技巧我后来在几个老项目里都当成保底方案用稳定可靠。4.2 Mixin 和页面里的分享配置“打架”到底谁覆盖谁前面已经说过 Vue 的合并规则页面实例的优先级高于 mixin。所以如果某个页面自己在顶层写了onShareAppMessage并返回了一套内容它就会把 mixin 里的分享逻辑覆盖掉。这个特性本身不是问题真正的坑在于很多人以为“页面里写了onShareAppMessage会先执行 mixin 的再执行自己的”于是拿两个返回值拼一下却发现最终分享出去的只有页面自己的内容。我在实际项目中就遇到过这种情况运营要求所有页面统一分享标题但有十几个页面历史遗留了自己写的onShareAppMessage结果这十几个页面的标题还是旧的。我的解决办法很简单约定所有页面都不要自己写onShareAppMessage统一走getShareConfig()。这样分享入口永远只有一个mixin 是绝对主导方页面只负责提供它想提供的配置字段。如果发现某个页面还在手写onShareAppMessage基本可以直接认定是历史遗留需要清理掉。4.3 分享卡片图片不显示或只显示默认截图分享封面图的问题非常常见表现通常是转发到聊天后卡片上要么是一张令人迷惑的页面截图要么是一张空白图。先说截图问题。微信在onShareAppMessage返回对象里检测不到imageUrl时会自动截取当前页面可视区域作为分享封面。这个默认行为虽然不至于让分享完全失效但截图质量完全不可控尤其页面里有弹窗、半透明遮罩的时候截图效果会很奇怪。所以统一 mixin 里必须给出默认imageUrl。再说图片加载失败。本地路径写法上最容易犯的错是漏了开头的/写成static/share-default.png而不是/static/share-default.png。微信要求本地路径必须是绝对路径。如果你用的是网络图片必须是https://开头的地址并且要确保该域名已经加入微信公众平台后台的下载合法域名。这一步遗漏的后果很隐蔽开发调试时图片正常但真机分享到别人手机上就加载失败。另外还有一个容易忽视的细节封面图尺寸和体积。微信对分享封面图没有硬性大小限制但我在实践中发现超过 300KB 的图片在高压缩后会明显失真而尺寸过小的图片比如 300x300在卡片上会被拉伸得模糊。统一在 mixin 里放一张 750x750、体积尽量控制在 100KB 以内的品牌图是最省心的方案。4.4 分享数据依赖异步请求时的兜底方案有些业务页面需要根据接口数据生成分享标题和图片。比如商品页的分享标题是“商品名 价格”封面图是商品主图。这时候有些新手会试图在onShareAppMessage里直接发一个异步请求这几乎是一条死路因为onShareAppMessage是同步回调微信只接受同步返回的分享数据不会等你接口返回。我踩过几次这个坑以后最终形成了自己的处理套路进页面先在onLoad里发起数据请求请求回来以后把分享需要用到的字段存到当前页面的data上。onShareAppMessage触发时同步读取这些已经准备好的字段。如果接口还没返回就用默认配置兜底。export default { mixins: [shareMixin], data() { return { productName: , productImage: , productId: , } }, onLoad(query) { if (query query.id) { this.fetchProductInfo(query.id) } }, methods: { async fetchProductInfo(id) { const info await this.$api.getProductDetail(id) this.productName info.name this.productImage info.image this.productId info.id }, getShareConfig() { return { title: this.productName ? ${this.productName}赶紧来看看 : , imageUrl: this.productImage || , path: this.productId ? /pages/product/product?id${this.productId}fromshare : , } }, }, }这个方案的核心思想是数据要提前准备好分享时才不慌。如果用户刚进页面立刻点分享分享出去的可能是默认标题但只要用户停留一两秒再点分享出去的就已经是最新商品信息了。这个体验虽然没法做到 100% 精确但在绝大多数业务场景下已经足够。4.5 页面参数被丢掉导致分享出去的链接打开错误页面这个坑属于“看起来完全正常但实际踩到就会很奇怪”的类型。我遇到过有人分享一个/pages/list/list?keyword夏季新款page1的链接好友点开以后页面收到的keyword变成了夏季新款的乱码或者直接被截断。排查到最后发现是分享路径在拼接时没有对参数做编码处理。问题的本质是微信分享过程中URL 会被多次解析和透传。如果参数里有中文、特殊符号、空格没有编码的字符串非常容易被截断或者丢失。统一 mixin 里已经用encodeURIComponent处理了大部分场景但如果你在页面的getShareConfig里自己拼 path务必养成习惯所有参数值都先经过一次编码接收方在代码里再用decodeURIComponent解码或者直接使用框架自动解析好的 query 对象。另外一个容易被忽略的是有些页面的options里会带一些无用参数比如fromshare这种渠道标记本身就不应该再传给下一层页面。如果不加过滤就把所有参数原样拼进分享链接会形成参数层层叠加链接越来越长也容易被截断。我在buildShareQuery里只过滤掉了空值和对象实际业务中你可以根据自己的需求再加一个白名单比如只允许保留id、type、from三个参数。5. 踩坑记录与我的最终落地建议5.1 哪些页面不适合用这套统一 Mixin虽然是“统一分享”但也不是所有页面都适合用同一套默认配置。我在项目里遇到过三个比较典型的例外。第一类是内容详情页。比如文章详情、商品详情这类页面的分享标题必须是内容本身的标题封面图也应该是内容主图。这种情况下页面必须实现getShareConfig方法从列表数据里取出标题和图片动态返回。第二类是活动专题页。活动页的分享要求通常很严格活动标题、活动海报、分享文案都有专门的运营设计。统一 mixin 的默认配置在这里基本帮不上忙反而可能因为标题被自动替换成品牌名而引发运营投诉。所以活动页我建议直接自己在getShareConfig里返回完整配置甚至可以在页面内禁用默认逻辑。第三类是内部工具页面。比如表单提交页、登录页这些页面本身不具备传播价值分享出去甚至会暴露一些敏感信息。对于这类页面我建议在getShareConfig里返回false或者直接调用wx.hideShareMenu()隐藏转发菜单。你可以在 mixin 里增加一个判断如果页面指定了disableShare: true就主动调用hideShareMenu。5.2 给 Mixin 增加一个“策略开关”实现页面级灵活控制为了处理上面的例外场景我建议在 mixin 里加一个简单的策略开关。设计思路是页面可以在自己的配置对象里声明shareDisabledmixin 在onShareAppMessage触发时先判断这个字段如果为真就直接返回undefined并隐藏转发菜单。// mixin 增加的部分 onShareAppMessage() { if (this.shareDisabled) { // 页面主动声明不参与分享隐藏转发菜单 wx.hideShareMenu({ menus: [shareAppMessage, shareTimeline], }) return undefined } // 原有逻辑继续…… }页面里只需要这样声明export default { mixins: [shareMixin], data() { return { shareDisabled: true, } }, }这个设计的好处是默认情况下所有页面都具备分享能力少数不需要分享的页面通过一个字段就能关掉。如果你顺手想把这个逻辑做成通用的还可以让onShareTimeline朋友圈分享也走同一套配置微信小程序的基础库在onShareTimeline支持上跟onShareAppMessage略有差异但思路一致可以做进同一个 mixin 里统一维护。5.3 Button 分享与菜单分享的联动细节除了右上角菜单很多页面底部会放一个显眼的“分享给好友”按钮。微信实现这个按钮非常简单直接用一个button open-typeshare就行。这个按钮触发分享时走的也是同一个onShareAppMessage所以 mixin 里的逻辑对它同样生效。唯一需要注意的坑是button open-typeshare真正触发分享的时机是在用户点击按钮并出现微信的分享面板之后。如果业务需要在用户点击的瞬间执行一些埋点或页面统计可以在按钮上同时监听tap或者使用sharesuccess事件来确认分享是否成功。这些事件和onShareAppMessage之间没有冲突但要注意不要在tap里做同步的uni.showToast之类的交互因为分享面板弹出时 toast 会被顶掉。5.4 埋点与渠道参数的统一注入分享功能上线后运营一定会问“这些分享进来了多少人来自哪个页面”。这时候统一 mixin 的价值就体现出来了。你可以在buildShareQuery里自动拼上一个渠道参数比如fromshare或者channelxxx所有分享出去的链接都会自动带上这个标记落地页再根据 query 上报来源。具体实现很简单在buildDefaultSharePath得出来的 query 后面再追加一个固定参数buildShareQuery(options) { const parts [] // 原有逻辑…… // 统一注入来源标记 parts.push(fromshare) return parts.length 0 ? ?${parts.join()} : }不过要注意如果页面自己的getShareConfig返回了自定义 path那这条 path 里也要带上渠道参数否则统计会漏。我的建议是渠道参数这件事尽量不要放在页面的getShareConfig里而是统一在 mixin 的收尾阶段做一次强制拼接保证渠道标记一定存在。写在最后这套统一分享 Mixin 的方案我已经在两个完整的小程序项目里验证过其中一个页面数超过 40 个另一个是 Vue3 Composition API 的新项目。代码本身并不复杂真正有价值的是“默认配置 页面按需覆盖”这套约定。我在实际维护中最大的体会是分享逻辑统一之后业务方不需要理解微信分享的实现细节只需要回答“这个页面想分享什么内容”剩下的框架层逻辑全部由 mixin 兜底。如果你准备在项目里落地这套方案我强烈建议在动手之前先做一次全页面排查把所有手写的onShareAppMessage全部找出来统一改成getShareConfig方式。否则新旧两套逻辑混在一起线上分享数据会出现各种莫名其妙的不一致。另外分享默认图、默认标题这类配置建议放到一个独立的config.js里维护方便运营同学后续自行修改而不必每一改动都重新发包。分享这件事看起来只是一个小功能但统一之后对项目的长期维护是实打实省了大把时间。

相关新闻

四小时学会OpenCV+Qt:从环境配置到显示第一张图片

四小时学会OpenCV+Qt:从环境配置到显示第一张图片

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 2:48:56 阅读更多 →
Patter Dashboard 与指标体系完整指南:5 步实时监控 AI 通话延迟、成本与转录

Patter Dashboard 与指标体系完整指南:5 步实时监控 AI 通话延迟、成本与转录

【免费下载链接】Patter Open-source voice-AI SDK. The Vapi/Retell alternative for builders who want to own the stack. Give your AI agent a phone number in 4 lines — Python and TypeScript, MIT licensed, Twilio, Telnyx, and Plivo. 项目地址: https:…

2026/10/16 2:48:56 阅读更多 →
AI小说生成本地部署零基础上手:从配置到出第一章只要10分钟

AI小说生成本地部署零基础上手:从配置到出第一章只要10分钟

AI小说生成本地部署零基础上手:从配置到出第一章只要10分钟 【免费下载链接】AI_NovelGenerator 使用ai生成多章节的长篇小说,自动衔接上下文、伏笔 项目地址: https://gitcode.com/GitHub_Trending/ai/AI_NovelGenerator AI_NovelGenerator 是一…

2026/10/16 2:47:56 阅读更多 →

最新新闻

面试复盘总漏关键信息?2026年7款面试复盘工具实测横评与选型指南

面试复盘总漏关键信息?2026年7款面试复盘工具实测横评与选型指南

面试这件事,最怕的不是当场答不上来,而是聊完就忘。面试官回忆不起候选人提到的项目细节,求职者想不起面试官反复追问的那个点,HR 手里只剩下几行潦草笔记。于是"复盘"两个字,常常变成凭印象打分。印象一旦失…

2026/10/16 3:35:06 阅读更多 →
IIEM实践:MATLAB自适应二重积分与奇异主部抽取解决积分方程近奇异问题

IIEM实践:MATLAB自适应二重积分与奇异主部抽取解决积分方程近奇异问题

简介:面向电磁散射建模与遥感定量反演研究者,这份开源代码实现了Hsieh等人(1997)改进的积分方程模型(IEM),用于粗糙表面后向散射系数计算。原始MATLAB版本来自Ulaby与Long(2014&…

2026/10/16 3:35:05 阅读更多 →
Nacos 2.5.0 麒麟 ARM 与达梦数据库适配编译实战指南

Nacos 2.5.0 麒麟 ARM 与达梦数据库适配编译实战指南

简介:面向国产化替代场景,这是一份Nacos 2.5.0在Linux环境下适配达梦数据库与麒麟ARM系统的完整编译产物及配套脚本,主要面向需要将微服务基础设施落地到国产软硬件栈的研发、运维与架构人员,解决服务发现、配置管理组件在国产数据…

2026/10/16 3:35:05 阅读更多 →
PowerBI数据清洗实操:用PowerQuery告别脏数据,提升模型稳定性

PowerBI数据清洗实操:用PowerQuery告别脏数据,提升模型稳定性

在PowerBI项目里,PowerQuery的数据清洗操作是我最看重的一步,也是最容易被新人跳过去的一步。很多同学把原始数据拖进模型就开始建表关系、写度量值,结果报表做到一半被脏数据反复绊倒:日期明明是文本、金额带符号、同一家门店在数…

2026/10/16 3:35:05 阅读更多 →
SpringBoot集成Elasticsearch实战:从倒排索引到搜索高亮

SpringBoot集成Elasticsearch实战:从倒排索引到搜索高亮

1. 搜索引擎ES到底能解决什么问题先说个我自己的经历。早两年我参与过一个内容管理系统的改造,数据库里存了上百万条文章数据,业务方提的需求越来越离谱:标题要支持模糊搜索、正文要高亮命中词、还要按某个字段做聚合统计。刚开始用MySQL的LI…

2026/10/16 3:35:05 阅读更多 →
VSCode配置C++开发环境:MinGW-w64编译器与调试全攻略

VSCode配置C++开发环境:MinGW-w64编译器与调试全攻略

1. 项目背后的核心问题:VSCode的"C环境配置"才是真正的门槛先说一个很多新手搞错的地方:VSCode本身不是编译器。它只是一个编辑器,负责高亮代码、提示语法、帮助你编辑文件;而把Hello World变成能运行的程序&#xff0c…

2026/10/16 3:34:05 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →