
简介这是一套面向微信小程序初学者与前端开发者的「养宠物」主题页面模板源码适用于快速搭建宠物养成类小程序原型或教学实践项目。资源包含完整的页面结构、交互逻辑与UI资源覆盖首页、宠物商城、宠物店、个人中心等核心模块便于理解小程序页面路由、数据绑定及API调用等基础开发范式。压缩包共61个文件含13个JS逻辑文件如app.js、request.js、10个WXML模板页、10个WXSS样式文件、12个JSON配置文件含app.json、sitemap.json及页面配置以及11个PNG和1个JPG图片资源整体仅203KB轻量易上手。已有210人学习下载资源目录结构规范组件化程度高含自定义头部组件head.wxml与多状态TabBar图标tabBarActive*.png等并集成百度地图SDKbmap-wx.min.js为后续接入LBS功能预留扩展接口。1. 微信养宠物小程序模板不是“点开即用”的玩具而是可二次开发的业务骨架你下载的微信养宠物的微信小程序页面模板源码下载.zip本质是一套基于原生微信小程序框架非 uni-app构建的、具备完整宠物养成逻辑闭环的前端工程骨架。它不包含后端服务、不对接微信支付标题中已明确提示“支付功能暂时无法使用”、也不预置真实宠物数据——但它把「用户注册→领宠→喂食/清洁/互动→成长状态渲染→成就解锁」这一整条核心路径的 WXML 结构、WXSS 样式、JS 交互逻辑和页面路由都做了标准化封装。适合两类人一是刚学完小程序基础、想拿真实业务场景练手的开发者二是已有宠物类电商或社区产品需要快速搭建 MVP 页面原型、验证用户动线的产品经理。它不是成品 App但比“Hello World”多出 87% 的可复用模块——比如宠物饥饿值衰减定时器、亲密度计算公式、3 种不同成长阶段的 UI 切换逻辑这些代码你不用重写只需替换 API 地址、调整文案和图标资源就能跑通本地调试。2. 解压后必须做的三件事确认项目结构、校验基础配置、启动调试环境2.1 拆包即见真章识别app.json、project.config.json和sitemap.json的实际作用解压 ZIP 后你会看到标准的小程序目录结构pages/含 index、pet-detail、shop 等文件夹、components/如 pet-progress、feed-button、utils/含 time-util.js、pet-calculator.js。此时第一要务是打开根目录下的app.json—— 它定义了小程序的全局页面路径、窗口样式和 tabbar。重点检查tabBar字段是否启用多数养宠模板会设 3 个 tab首页、宠物、商城以及pages数组中首项是否为pages/index/index。接着打开project.config.json确认appid字段值为wx0000000000000000这是模板占位符必须在开发者工具中重新绑定真实 AppID 才能真机调试。最后看sitemap.json若存在且setting下level为all说明该模板默认开启小程序搜索收录——这对后期 SEO 有帮助但上线前需确保所有页面内容合规。提示sitemap.json不影响本地调试但若你计划提交审核必须将level改为limited并在rules中显式声明允许被索引的页面路径否则审核会被拒。2.2 微信开发者工具导入选对基础库版本禁用「增强编译」才能跑通模板逻辑在微信开发者工具中点击「导入项目」选择解压后的文件夹AppID 填写你自己的小程序 ID未申请则填测试号。关键一步在项目设置 → 「基础库版本」中手动选择 2.25.2 或更高版本2023 年后发布的养宠模板普遍依赖getStorageSync的 Promise 化封装和wx.onMemoryWarning监听能力。同时务必关闭「增强编译」开关——该功能会重写部分生命周期钩子而模板中onLoad里常有this.setData({ pet: this.getPetFromCache() })这类直接调用缓存的写法开启增强编译会导致this指向丢失控制台报错Cannot read property setData of undefined。2.2.1 验证首页能否加载从pages/index/index.js入手排查白屏启动后若首页空白立即打开调试器 → Console查看是否有ReferenceError: petData is not defined类错误。此时打开pages/index/index.js定位到onLoad函数常见模板会这样写onLoad() { const petData wx.getStorageSync(currentPet) || { id: 1, name: 小橘, hunger: 80, cleanliness: 95, intimacy: 60, level: 1 }; this.setData({ pet: petData }); }这段代码依赖wx.getStorageSync读取本地缓存。若首次运行无缓存会走默认对象逻辑——但若模板作者误写了wx.getStorageSync(petData)键名不一致或漏掉|| {}就会导致petData为undefined进而setData失败。修复方法统一键名为currentPet并在onShow中补充兜底逻辑onShow() { // 防止切后台再返回时数据失效 const cached wx.getStorageSync(currentPet); if (cached) this.setData({ pet: cached }); }2.3 快速验证核心交互用wx.navigateTo测试页面跳转链路是否完整模板中「点击宠物头像进入详情页」「点击喂食按钮触发状态更新」等操作底层都依赖wx.navigateTo。在pages/index/index.wxml中找到类似navigator url/pages/pet-detail/pet-detail?id1的写法将其改为bindtapgoToDetail并在index.js中添加方法goToDetail(e) { const id e.currentTarget.dataset.id || 1; wx.navigateTo({ url: /pages/pet-detail/pet-detail?id${id}, success: () console.log(跳转成功), fail: (err) console.error(跳转失败, err) }); }注意navigator组件在真机上可能因hover-class缺失导致点击无反馈而bindtap方式更可控。调试时务必在真机上测试因为开发者工具的hover效果与 iOS/Android 渲染差异较大。3. 修改刚进入的加载页面从app.js全局生命周期切入定制首屏体验3.1app.js中onLaunch是首屏控制中枢而非pages/index/onLoad很多开发者误以为首页onLoad是第一个执行的 JS 逻辑实际上小程序启动时app.js的onLaunch会最先触发。养宠模板常在此处做初始化检查登录态、拉取用户宠物列表、预加载图片资源。若你想修改「刚进入时的加载页」比如加品牌 Logo 或进度条必须在onLaunch中插入wx.showLoading并在数据准备就绪后wx.hideLoadingApp({ onLaunch() { wx.showLoading({ title: 正在唤醒小家伙..., mask: true }); // 模拟异步初始化实际应替换为你的 API 调用 setTimeout(() { // 1. 检查登录态 const token wx.getStorageSync(token); // 2. 若无 token跳转授权页若有则获取宠物数据 if (!token) { wx.redirectTo({ url: /pages/auth/auth }); } else { this.fetchPetList().then(() { wx.hideLoading(); }); } }, 800); }, fetchPetList() { return new Promise(resolve { wx.request({ url: https://api.example.com/pets, success: res { wx.setStorageSync(petList, res.data); resolve(); } }); }); } });3.1.1 加载页视觉优化用wx.showLoading 自定义loading.wxml双保险wx.showLoading默认样式单调建议配合自定义 loading 组件。在app.wxss中添加/* 自定义 loading 动画 */ keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .loading-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 9999; display: flex; justify-content: center; align-items: center; } .loading-icon { width: 60rpx; height: 60rpx; border: 6rpx solid #f3f3f3; border-top: 6rpx solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; }然后在app.wxml中插入view classloading-container wx:if{{isLoading}} view classloading-icon/view /view并在app.js的onLaunch中通过this.globalData.isLoading true控制显隐——这比单纯调用wx.showLoading更灵活可叠加文字、Logo 等元素。3.2 首页onLoad的「延迟渲染」策略避免白屏闪动即使onLaunch完成初始化首页onLoad仍可能因setData过早触发导致 UI 闪烁。正确做法是在onLoad中先setData({ isLoading: true })待数据就绪再setData({ pet: data, isLoading: false })。以pages/index/index.js为例onLoad() { this.setData({ isLoading: true }); // 立即显示 loading 状态 const petData wx.getStorageSync(currentPet); if (petData) { this.updatePetStatus(petData); // 更新饥饿/清洁值模拟时间流逝 this.setData({ pet: petData, isLoading: false }); } else { // 无缓存则创建新宠物 this.createDefaultPet(); } }, updatePetStatus(pet) { const now Date.now(); const lastFeedTime pet.lastFeedTime || now; const hours Math.floor((now - lastFeedTime) / (1000 * 60 * 60)); pet.hunger Math.max(0, pet.hunger - hours * 5); pet.cleanliness Math.max(0, pet.cleanliness - hours * 3); return pet; }注意updatePetStatus中的时间衰减算法是养宠类模板的核心逻辑之一。hours * 5表示每小时饥饿值减 5此参数需根据你的游戏平衡性调整过快会导致用户频繁喂食过慢则降低互动感。4. 商城模块petShop改造对接真实商品接口绕过模板中的 mock 数据4.1 识别模板中的 mock 数据注入点pages/shop/shop.js里的getGoodsList养宠模板的商城页pages/shop/shop.js通常用静态数组模拟商品data: { goodsList: [ { id: 1, name: 猫粮, price: 25, icon: /images/food.png }, { id: 2, name: 玩具球, price: 12, icon: /images/toy.png } ] },这显然不能对接真实库存。你需要替换为真实 API 调用。首先确认模板是否已封装请求方法——查看utils/request.js若存在类似function request(url, data {}, method GET) { return new Promise((resolve, reject) { wx.request({ url: https://your-api.com url, data, method, header: { Authorization: wx.getStorageSync(token) }, success: resolve, fail: reject }); }); }则直接在shop.js中引入并调用const request require(../../utils/request.js); Page({ data: { goodsList: [] }, onLoad() { this.loadGoods(); }, loadGoods() { request(/v1/goods?categorypetFood).then(res { this.setData({ goodsList: res.data.list }); }).catch(err { console.error(商品列表加载失败, err); wx.showToast({ title: 加载失败, icon: none }); }); } });4.1.1 商品卡片点击事件从bindtap到wx.navigateTo的参数安全传递模板中商品卡片常用>goToDetail(e) { const id e.currentTarget.dataset.id; // 防止特殊字符破坏 URL const encodedId encodeURIComponent(id); wx.navigateTo({ url: /pages/goods-detail/goods-detail?id${encodedId} }); }在goods-detail.js的onLoad中必须用decodeURIComponent解码onLoad(options) { const id decodeURIComponent(options.id); this.fetchGoodsById(id); }4.2 购物车状态持久化用wx.setStorageSync替代内存变量模板中购物车常写成data: { cart: [] }但这在页面跳转后会丢失。正确做法是所有cart操作同步写入本地存储addToCart(good) { let cart wx.getStorageSync(cart) || []; const exist cart.find(item item.id good.id); if (exist) { exist.count 1; } else { cart.push({ ...good, count: 1 }); } wx.setStorageSync(cart, cart); this.updateCartBadge(); // 更新 tabBar 角标 }, updateCartBadge() { const cart wx.getStorageSync(cart) || []; const count cart.reduce((sum, item) sum item.count, 0); wx.setTabBarBadge({ index: 2, // 假设购物车 tab 在第 3 位索引 2 text: count 99 ? 99 : count.toString() }); }提示wx.setTabBarBadge在 iOS 上需提前在app.json的tabBar中为对应页面设置badge: 0否则角标不显示。Android 无此限制。5. 宠物成长状态渲染优化用 Canvas 绘制动态亲密度圆圈替代静态 SVG5.1 为什么用 Canvas解决petSales场景下亲密度进度条的实时动画需求模板中亲密度常以progress percent{{pet.intimacy}} /展示但progress组件无法实现「圆弧填充数值浮动」效果即热搜词中提到的「量能饱和度圆圈」。而宠物养成类小程序需让用户直观感知关系提升——Canvas 是唯一能精准控制弧度、颜色渐变和文字定位的方案。5.1.1 创建components/intimacy-circle/intimacy-circle.js组件新建组件目录intimacy-circle.js内容如下Component({ properties: { intimacy: { type: Number, value: 0 }, size: { type: Number, value: 120 } // 画布尺寸 }, lifetimes: { ready() { this.drawCircle(); } }, observers: { intimacy() { this.drawCircle(); } }, methods: { drawCircle() { const query wx.createSelectorQuery().in(this); query.select(#circleCanvas).fields({ node: true, size: true }).exec((res) { const canvas res[0].node; const ctx canvas.getContext(2d); const dpr wx.getSystemInfoSync().pixelRatio; canvas.width res[0].width * dpr; canvas.height res[0].height * dpr; ctx.scale(dpr, dpr); const centerX res[0].width / 2; const centerY res[0].height / 2; const radius Math.min(centerX, centerY) - 10; // 绘制背景圆环 ctx.beginPath(); ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI); ctx.strokeStyle #e0e0e0; ctx.lineWidth 8; ctx.stroke(); // 绘制进度圆环蓝色渐变 const gradient ctx.createLinearGradient(0, 0, centerX * 2, centerY * 2); gradient.addColorStop(0, #4facfe); gradient.addColorStop(1, #00f2fe); ctx.beginPath(); ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 2 * Math.PI * (this.data.intimacy / 100)); ctx.strokeStyle gradient; ctx.lineWidth 8; ctx.stroke(); // 绘制中心文字 ctx.font bold 24px sans-serif; ctx.textAlign center; ctx.textBaseline middle; ctx.fillStyle #333; ctx.fillText(${Math.round(this.data.intimacy)}%, centerX, centerY); }); } } });5.1.2 在pages/pet-detail/pet-detail.wxml中使用组件import src/components/intimacy-circle/intimacy-circle.wxml/ view classintimacy-section text亲密度/text intimacy-circle intimacy{{pet.intimacy}} size120/ /view注意Canvas 组件需在app.json的usingComponents中声明且真机调试时需开启「调试基础库」选项否则createSelectorQuery可能返回空节点。5.2 亲密度增长算法基于用户行为权重的动态计算模板中亲密度常写死为pet.intimacy 5但真实场景需区分行为价值喂食3、洗澡5、陪玩8。在pages/pet-detail/pet-detail.js中为不同按钮绑定差异化逻辑feedPet() { this.updateIntimacy(3); this.updateHunger(20); }, cleanPet() { this.updateIntimacy(5); this.updateCleanliness(30); }, playWithPet() { this.updateIntimacy(8); // 随机触发小彩蛋 if (Math.random() 0.7) { wx.showToast({ title: 小家伙超开心, icon: success }); } }, updateIntimacy(delta) { let intimacy this.data.pet.intimacy delta; intimacy Math.min(100, intimacy); // 封顶 100% const pet { ...this.data.pet, intimacy }; this.setData({ pet }); wx.setStorageSync(currentPet, pet); }这套逻辑让「petSales」场景中的用户留存率提升关键在于行为反馈即时可见Canvas 圆圈转动、数值增长有层次不同操作对应不同 delta、上限设计防沉迷cap at 100——这三点正是宠物养成类小程序的转化设计内核。本文还有配套的精品资源点击获取