- 【流量主求助贴】接近200W用户的小程序,广告收益差点不够服务器费用,真就这么离大谱?
我是一个人开发者,业余时间开发了小程序,还不容易积攒了200多万的用户。 但是现在就很为难了。先请教官方或者运营大神,如何提高收入?! 以前,开发云还是免费,那是一天不到1k用户,小程序广告也就加了两个,每月也能收到接近1K块钱的广告费,那时候,就幻想要有1w用户每天,是不是就有1W的收益。没想到现在都已经4W用户每天,比之前都翻了40倍!但是,收入还是1k不到。真的蓝瘦香菇!! 小程序是个人的,只有流量主的广告收入,开发云服务器费用居然快要超过流量主的广告收益,现在,都不知道要怎么样做商业化? 广告收益: 广告单价一直降,有最高的14块钱降到不到1块钱,直接降到14倍。 19年 eCPM:6.04 元 20年 eCPM:14.82元 21年 eCPM:6.95 元 22年 eCPM:1.78元 23年 eCPM:0.98 元 [图片] [图片] [图片] [图片] [图片] 小程序状况: [图片] 上个月云开发费用 (主要是调用量超太多了,在开发云收费后,已经特意做了代码优化,在之前的基础上已经减了50%,现在,只剩必要的调用量) [图片] 顶配套餐(团队版) 999 元每月 资源包 :400 + 400 + 1500 (购买了三次调用量) 10月份总费用 3299 ,广告收益 4300,收入还是1K多。 这两年,明明发布了很多版本,付出了不少努力,用户量也翻了好几倍,但是,实际结果是收入还不如两年前一样。心生无力!!!
2023-11-06 - 省钱有道之 云开发环境共享小结
#前言 最近为了节省一点小程序的运营成本,一些没啥流量的小程序如果每个月也要19块略微有些肉疼(主要还是穷),研究了一下云环境共享,在这里简单做一下总结。 [图片] 这里有官方的小程序环境共享文档需提前了解一下,具体共享步骤按官方文档操作即可。 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/resource-sharing/introduce.html #注意点 共享环境有几个注意点大致如下: 1、必须是相同主体 2、开通了云开发环境的小程序可以共享给同主体的小程序、公众号,被共享方无需开通云开发环境 3、一个云开发环境最多可以共享给10个小程序/公众号 4、共享后双发均可主动解除 5、按官方文档要求,资源方需有云函数cloudbase_auth,测试时发现没有这个云函数其实也能正常运行,可能我验证的场景还不够多 6、云能力初始化的方式不同,资源方按传统的云环境初始化方式即可,也就是 wx.cloud.init({ env: env.activeEnv, traceUser: true }); 而调用方的初始化方式有所不同 const cloud = new wx.cloud.Cloud({ //资源方AppID resourceAppid, //资源方环境ID resourceEnv, }) // 跨账号调用,必须等待 init 完成 // init 过程中,资源方小程序对应环境下的 cloudbase_auth 函数会被调用,并需返回协议字段(见下)来确认允许访问、并可自定义安全规则 const initRes = await cloud.init(); 后续调用资源方的云函数就用这个cloud就行了:cloud.callFunction({...}); 7、调用方有操作到云存储文件的api也需要用6步骤中的cloud 8、云存储fileId需要用cloud.getTempFileURL转换成临时/永久链接,否则在调用方无法展示 9、一些api的云调用方式也有变化,需指明具体的appid。比如A小程序授权给了B小程序,想给B小程序推送客服消息需要写成 await cloud.openapi({appid:B小程序appid}).customerServiceMessage.send({...}); 10、获取调用方的appid/openid/unionid也有所不同 // 跨账号调用时,由此拿到来源方小程序/公众号 AppID console.log(wxContext.FROM_APPID) // 跨账号调用时,由此拿到来源方小程序/公众号的用户 OpenID console.log(wxContext.FROM_OPENID) // 跨账号调用、且满足 unionid 获取条件时,由此拿到同主体下的用户 UnionID console.log(wxContext.FROM_UNIONID) #适配 基于以上注意点,开始进行适配,由于我是一套代码部署N个小程序,然后一个云环境共享给其他小程序,希望通过配置决定哪个小程序作为资源方,哪些作为调用方 首先是云开发环境的初始化: 1、env.js 环境配置: //云开发环境 const cloudBase = { //使用共享云环境资源,资源方=false,调用方=true useShareResource: false, //资源方AppID resourceAppid: "wx9d2xxxxxxxx0088", //资源方环境ID resourceEnv: "prod-9gxqvi3qb3c257ef", //云环境ID prod: "prod-9gxqvi3qb3c257ef" } 2、api.js 操作模块 const env = require('../env.js'); let cloud; /** * 初始化云能力 * @returns {Promise} */ const wxCloudInit = async function () { const {cloudBase} = env; if (!wx.cloud) { console.error('请使用 2.2.3 或以上的基础库以使用云能力') } else if (cloudBase.useShareResource) { const {resourceAppid, resourceEnv} = cloudBase; // 声明新的 cloud 实例 cloud = new wx.cloud.Cloud({ //资源方AppID resourceAppid, //资源方环境ID resourceEnv, }) // 跨账号调用,必须等待 init 完成 // init 过程中,资源方小程序对应环境下的 cloudbase_auth 函数会被调用,并需返回协议字段(见下)来确认允许访问、并可自定义安全规则 const initRes = await cloud.init(); console.log("初始化云能力完毕:", initRes, "资源方appid:", resourceAppid, "资源方环境ID:", resourceEnv); } else { wx.cloud.init({ env: env.activeEnv, traceUser: true }); console.log("初始化云能力完毕,当前环境:", env.activeEnv); cloud = wx.cloud; } this.cloud = cloud; } /** * 云函数调用 * @param name * @param data * @param success * @param fail * @param complete */ const callCloudFunction = function (name, data, success, fail, complete) { //执行云函数 cloud.callFunction({ // 云函数名称 name: name, // 传给云函数的参数 data: Object.assign({}, data, {env: env.activeEnv}) }).then(res => { typeof success == 'function' && success(res); }).catch(res => { typeof fail == 'function' && fail(res); }).then(res => { typeof complete == 'function' && complete(res); }); }; 3、在app.js中初始化云环境,后续有用到wx.cloud的都需要改成api.cloud const api = require('utils/api.js'); App({ onLaunch: async function (options) { await api.wxCloudInit(); } }); 其次是资源方的获取用户信息调整 每次都要判断wxContext.FROM_OPENID是否为空,不为空则是调用方的用户信息,为空则是资源方的用户信息,略微繁琐,干脆封装了一个npm包wx-server-inherit-sdk,改造了一下getWxContext函数,源码如下,引入这个包后也就可以不用引入官方的wx-server-sdk const cloud = require('wx-server-sdk'); // 保存原始getWXContext方法到另一个变量 const originalGetWXContext = cloud.getWXContext; cloud.getWXContext = function () { //调用原始getWXContext方法 const wxContext = originalGetWXContext.call(this); const {FROM_APPID, FROM_OPENID} = wxContext; //云开发环境共享时获取到的APPID会替换成源方APPID if (FROM_APPID) { Object.assign(wxContext, {APPID: FROM_APPID}); } //云开发环境共享时获取到的OPENID会替换成源方OPENID if (FROM_OPENID) { Object.assign(wxContext, {OPENID: FROM_OPENID}); } return wxContext; } module.exports = cloud; 到此也就大功告成。为了省钱也是够折腾的[哭笑]
2023-08-28 - 小程序涉及iOS虚拟支付修改指引
近期,开发者社区几乎隔三差五就被“如何整改虚拟支付”霸占。社区君在大家的强烈诉求下,特地整理了大家审核过程中经常遇到的问题。 问题1 虚拟支付到底是什么? 虚拟支付是指购买非实物商品。比如:VIP会员、充值、课程、音视频等虚拟产品。 问题2 为什么关闭了虚拟支付功能,还是不能过审? 部分开发者在提审时,仅在后台关闭了支付接口,但在前端仍保留购买/支付/订阅等功能或按钮,在iOS端的界面也都会有类似“订阅课程、开通VIP”等标识,这类呈现货架价格、提示购买的行为将被禁止。 比如: [图片] 这类展示货架(价格标签)的,将被拒绝 问题3 为什么已经去掉了引导关注公众号,还是不能过审? 请勿试图引导用户到微信公众号、H5、App或是任何外链进行付费。任何为用户提供前往支付流程的路径/文案,都将被拒绝。 比如: [图片] 这类通过【客服消息】-【个人微信号】,完成购买行为,将会被拒绝 [图片] 这类引导到H5,完成购买的行为,将会被拒绝 [图片] 这类引导到公众号,完成购买的行为,将会被拒绝 以下提供3种修改示例,仅供参考。 1、关闭iOS付费通道。 以小程序【腾讯视频】为例,iOS端关闭会员卡开通渠道,原【开通VIP】按钮,现仅显示【你还不是会员】,不再提供会员开通服务。比如: [图片] 2、所有付费内容均更改为免费。 以小程序【有道精品课】为例,iOS端将所有付费内容更改为免费,原【付费解锁】,现已完全免费使用。比如: [图片] 3、前端直接拦截提示不可服务。 以小程序【网易公开课精品】、【腾讯视频VIP】为例,iOS端点击订阅、开通VIP服务,前端直接拦截提示不可服务。但,如果页面呈现货架价格,提示购买行为的(如问题2),将会被拒绝。比如: [图片]
2018-08-17 - 小程序app.onLaunch与page.onLoad异步问题的最佳实践
场景: 在小程序中大家应该都有这样的场景,在onLaunch里用wx.login静默登录拿到code,再用code去发送请求获取token、用户信息等,整个过程都是异步的,然后我们在业务页面里onLoad去用的时候异步请求还没回来,导致没拿到想要的数据,以往要么监听是否拿到,要么自己封装一套回调,总之都挺麻烦,每个页面都要写一堆无关当前页面的逻辑。 直接上终极解决方案,公司内部已接入两年很稳定: 1.可完美解决异步问题 2.不污染原生生命周期,与onLoad等钩子共存 3.使用方便 4.可灵活定制异步钩子 5.采用监听模式实现,接入无需修改以前相关逻辑 6.支持各种小程序和vue架构 。。。 //为了简洁明了的展示使用场景,以下有部分是伪代码,请勿直接粘贴使用,具体使用代码看Github文档 //app.js //globalData提出来声明 let globalData = { // 是否已拿到token token: '', // 用户信息 userInfo: { userId: '', head: '' } } //注册自定义钩子 import CustomHook from 'spa-custom-hooks'; CustomHook.install({ 'Login':{ name:'Login', watchKey: 'token', onUpdate(token){ //有token则触发此钩子 return !!token; } }, 'User':{ name:'User', watchKey: 'userInfo', onUpdate(user){ //获取到userinfo里的userId则触发此钩子 return !!user.userId; } } }, globalData) // 正常走初始化逻辑 App({ globalData, onLaunch() { //发起异步登录拿token login((token)=>{ this.globalData.token = token //使用token拿用户信息 getUser((user)=>{ this.globalData.user = user }) }) } }) //关键点来了 //Page.js,业务页面使用 Page({ onLoadLogin() { //拿到token啦,可以使用token发起请求了 const token = getApp().globalData.token }, onLoadUser() { //拿到用户信息啦 const userInfo = getApp().globalData.userInfo }, onReadyUser() { //页面初次渲染完毕 && 拿到用户信息,可以把头像渲染在canvas上面啦 const userInfo = getApp().globalData.userInfo // 获取canvas上下文 const ctx = getCanvasContext2d() ctx.drawImage(userInfo.head,0,0,100,100) }, onShowUser() { //页面每次显示 && 拿到用户信息,我要在页面每次显示的时候根据userInfo走不同的逻辑 const userInfo = getApp().globalData.userInfo switch(userInfo.sex){ case 0: // 走女生逻辑 break case 1: // 走男生逻辑 break } } }) 具体文档和Demo见↓ Github:https://github.com/1977474741/spa-custom-hooks 祝大家用的愉快,记得star哦
2023-04-23 - taiwindcss在小程序中的应用
css 工程化思想有很多(sass,less,css-in-js…),基于原子类书写思想的 taiwindcss(以下用 tw 代替)风头很盛,去年底 tw3 上线,搭配新的引擎让[代码]just-in-time[代码]模式平稳落地。 tw 的思想和好处这里不在赘述,官网介绍的很清楚(tw2 中文官网)。 这里主要描述下如何在小程序中使用tw书写样式。 题外话:很难想象前端最佳实践到来的那一天,但 css 最佳实现或许已初见苗头… tw书写小程序 tw3 是即时(实时)生成类样式。tw 会根据您的配置文件,匹配您指定文件中包含的关键字,自动生成对应配置的样式。 在小程序中,只需要在 app.wxss 中引入 tw 生成的样式文件(记得组件中配置 addGlobalClass:true),就不必在书写组件时,关心 wxss 文件了。 base类 base类好比预设一些样式 (由于官方默认配置基于web端,小程序中只能自己定义了) [代码] /* wxss */ page { height: 100%; line-height: 1.2; -webkit-text-size-adjust: 100%; font-family: "fontFamily.sans", ui-sans-serif, system-ui" } [class], view, image, ::before, ::after{ box-sizing: border-box; border-width: 0; border-style: solid; border-color: currentColor; } /* variables */ page{ --color-primary:#22c55e; --color-primary-dark: #16a34a; /* ... */ } @media (prefers-color-scheme: dark) { page { --color-primary:#ef4444; --color-primary-dark: #dc2626; /* ... */ } } [代码] utilities(工具类) tw 中最核心的思想(工具类 css,也有叫原子化 css),大多数内部模块可以基于官方默认配置,有些还需要自定义配置。 Demo1 [代码] <view> <text class="text-red text-40 ml-10 px-20 "> 我的字体颜色是红色,大小为40rpx,左外边距10rpx,内边距x轴20rpx</text > </view> <!-- wxss新增 .text-red{ color:red }, .text-40{ font-size: 40rpx }, .ml-10{ margin-left:10rpx } .px-20{ padding: 0 20rpx } --> [代码] components(组件类) 有时几个工具类样式会经常出现,我们可以把他们自定义为组件类(比如下面 Demo3 中的[代码]ellipsis[代码]类) Demo2 [代码] <view> <button class="bg-primary hover_bg-primary-dark inline-block w-100 h-60 whitespace-nowrap overflow-hidden overflow-ellipsis" > 工具类写法--按钮1 </button> </view> <view> <button class="btn ellipsis">组件类写法--按钮2</button> </view> <!-- wxss新增 .bg-primary{ color:var(--color-primary) } .hover_bg-primary-dark:hover{ color:var(--color-primary-dark) } .inline-block { display: inline-block; } .w-100 { width: 100rpx; } .h-60 { height: 60rpx; } .whitespace-nowrap{ white-space: nowrap; } .overflow-hidden{ overflow: hidden; } .overflow-ellipsis{ text-overflow: ellipsis; } .btn{ // 组件类 color:var(--color-primary); display: inline-block; width: 100rpx; height: 60rpx; } .btn:hover{ // 组件类 color:var(--color-primary-dark); } .ellipsis { // 组件类 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } --> [代码] 不必纠结这么多工具类样式很难记,因为这些类都基于原生样式且可以自定义的,搭配官方插件 Tailwind CSS IntelliSense还可以得到代码提示(小程序编辑器也支持)。 先写这么多,不知道是否有人关注tw在小程序中的应用,下篇预期发具体核心类编译配置,如果您感兴趣请点赞支持。
2022-01-29 - 在小程序中愉快的使用 Tailwind CSS 吧!
[图片] 在小程序中愉快的使用 Tailwind CSS 吧! 把 [代码]tailwindcss JIT[代码] 思想带入小程序开发吧! 在小程序中愉快的使用 Tailwind CSS 吧! Usage uni-app (vue2/3) uni-app for vite (vue3) Taro v3 (React/vue2/3) remax (react) rax (react) 原生小程序(webpack5 mina) Options 配置项 使用 arbitrary values Q&A 1. 我在 [代码]js[代码] 里写了 [代码]tailwindcss[代码] 的任意值,为什么没有生效? 2. 一些像 [代码]disabled:opacity-50[代码] 这类的 [代码]tailwindcss[代码] 前缀不生效? 3. 和原生组件一起使用注意事项 4. 编译到 h5 注意事项 Related projects 模板 template 预设 tailwindcss preset Bugs & Issues 笔者之前写了一个 tailwindcss-miniprogram-preset,可是那个方案不能兼容最广泛的 [代码]Just in time[代码] 引擎,在写法上也有些变体。 于是笔者又写了一个 [代码]weapp-tailwindcss-webpack-plugin[代码],这是一个 [代码]plugin[代码] 合集,包含 [代码]webpack/vite plugin[代码],它会同时处理类 [代码]wxml[代码] 和 [代码]wxss[代码] 文件,从而我们开发者,不需要更改任何代码,就能让 [代码]jit[代码] 引擎兼容微信小程序。 此方案可兼容 [代码]tailwindcss v2/v3[代码],[代码]webpack v4/v5[代码],[代码]postcss v7/v8[代码]。 随着 [代码]@vue/cli-service[代码] v5 版本的发布,uni-app 到时候也会转为 [代码]webpack5[代码] + [代码]postcss8[代码] 的组合,到时候,我会升级一下 [代码]uni-app[代码] 的示例,让它从 [代码]tailwindcss v2 jit[代码] 升级到 [代码]tailwindcss v3 jit[代码] Usage uni-app (vue2/3) 使用方式 | Demo 项目 uni-app for vite (vue3) 使用方式 | Demo 项目 Taro v3 (React/vue2/3) 使用方式 | React Demo 项目 | vue2 Demo 项目 | vue3 Demo 项目 remax (react) 使用方式 | Demo 项目 rax (react) 使用方式 | Demo 项目 原生小程序(webpack5 mina) 使用方式 | Demo 项目 Options 配置项 配置项 类型 描述 [代码]htmlMatcher[代码] [代码](assetPath:string)=>boolean[代码] 匹配 [代码]wxml[代码]等等模板进行处理的方法 [代码]cssMatcher[代码] [代码](assetPath:string)=>boolean[代码] 匹配 [代码]wxss[代码]等等样式文件的方法 [代码]jsMatcher[代码] [代码](assetPath:string)=>boolean[代码] 匹配 [代码]js[代码]文件进行处理的方法,用于 [代码]react[代码] [代码]mainCssChunkMatcher[代码] [代码](assetPath:string)=>boolean[代码] 匹配 [代码]tailwindcss jit[代码] 生成的 [代码]css chunk[代码] 的方法 [代码]framework[代码] ([代码]Taro[代码] 特有) [代码]react[代码]|[代码]vue2[代码]|[代码]vue3[代码] 由于 [代码]Taro[代码] 不同框架的编译结果有所不同,需要显式声明框架类型 默认[代码]react[代码] [代码]customRuleCallback[代码] [代码](node: Postcss.Rule, options: Readonly<RequiredStyleHandlerOptions>) => void[代码] 可根据 Postcss walk 自由定制处理方案的 callback 方法 [代码]cssPreflight[代码] [代码]Record<string,string>[代码]| [代码]false[代码] 在所有 [代码]view[代码]节点添加的 [代码]css[代码] 预设,可根据情况自由的禁用原先的规则,或者添加新的规则。 详细用法如下: [代码]// default 默认: cssPreflight: { 'box-sizing': 'border-box', 'border-width': '0', 'border-style': 'solid', 'border-color': 'currentColor' } // result // box-sizing: border-box; // border-width: 0; // border-style: solid; // border-color: currentColor // case 禁用所有 cssPreflight: false // result // none // case 禁用单个属性 cssPreflight: { 'box-sizing': false } // border-width: 0; // border-style: solid; // border-color: currentColor // case 更改和添加单个属性 cssPreflight: { 'box-sizing': 'content-box', 'background': 'black' } // result // box-sizing: content-box; // border-width: 0; // border-style: solid; // border-color: currentColor; // background: black [代码] 使用 arbitrary values 详见 tailwindcss/using-arbitrary-values 章节 | Sample Q&A 1. 我在 [代码]js[代码] 里写了 [代码]tailwindcss[代码] 的任意值,为什么没有生效? 详见 issue#28 A: 因为这个插件,主要是针对, [代码]wxss[代码],[代码]wxml[代码] 和 [代码]jsx[代码] 进行转义的,[代码]js[代码] 里编写的 [代码]string[代码] 是不转义的。如果你有这样的需求可以这么写: [代码]import { replaceJs } from 'weapp-tailwindcss-webpack-plugin/replace' const cardsColor = reactive([ replaceJs('bg-[#4268EA] shadow-indigo-100'), replaceJs('bg-[#123456] shadow-blue-100') ]) [代码] 你不用担心把代码都打进来导致体积过大,我在 ‘weapp-tailwindcss-webpack-plugin/replace’ 中,只暴露了2个方法,代码体积 1k左右,esm格式。 2. 一些像 [代码]disabled:opacity-50[代码] 这类的 [代码]tailwindcss[代码] 前缀不生效? 详见 issue#33,小程序选择器的限制。 3. 和原生组件一起使用注意事项 假如出现原生组件引入报错的情况,可以参考 issue#35 ,忽略指定目录下的文件,跳过插件处理,比如 [代码]uni-app[代码] 中的 [代码]wxcomponents[代码]。 如何更改?在传入的配置项 [代码]cssMatcher[代码],[代码]htmlMatcher[代码] 这类中过滤指定目录或文件。 4. 编译到 h5 注意事项 有些用户通过 [代码]uni-app[代码] 等跨端框架,不止开发成各种小程序,也开发为 [代码]H5[代码],然而 [代码]tailwindcss[代码] 本身就兼容 [代码]H5[代码] 了。此时你需要更改配置,我们以 [代码]uni-app[代码] 为例: [代码]const isH5 = process.env.UNI_PLATFORM === 'h5'; // 然后在 h5 环境下把 webpack plugin 和 postcss for weapp 给禁用掉 // 我们以 uni-app-vue3-vite 这个 demo为例 // vite.config.ts import { defineConfig } from 'vite'; import uni from '@dcloudio/vite-plugin-uni'; import { ViteWeappTailwindcssPlugin as vwt } from 'weapp-tailwindcss-webpack-plugin'; // vite 插件配置 const vitePlugins = [uni()]; !isH5 && vitePlugins.push(vwt()); export default defineConfig({ plugins: vitePlugins }); // postcss 配置 // 假如不起作用,请使用内联postcss const isH5 = process.env.UNI_PLATFORM === 'h5'; const plugins = [require('autoprefixer')(), require('tailwindcss')()]; if (!isH5) { plugins.push( require('postcss-rem-to-responsive-pixel')({ rootValue: 32, propList: ['*'], transformUnit: 'rpx' }) ); plugins.push(require('weapp-tailwindcss-webpack-plugin/postcss')()); } module.exports = { plugins }; [代码] Related projects 模板 template uni-app-vite-vue3-tailwind-vscode-template uni-app-vue3-tailwind-vscode-template uni-app-vue2-tailwind-vscode-template weapp-native-mina-tailwindcss-template 预设 tailwindcss preset tailwindcss-miniprogram-preset Bugs & Issues 目前这个插件正在快速的开发中,如果遇到 [代码]Bug[代码] 或者想提出 [代码]Issue[代码] 欢迎提交到此处 <!-- ## 关于其他小程序 处理了其他小程序的: [代码]/.+\.(?:wx|ac|jx|tt|q|c)ss$/[代码] 样式文件和 [代码]/.+\.(?:(?:(?:wx|ax|jx|ks|tt|q)ml)|swan)$/[代码] 各种 [代码]xxml[代码] 和特殊的 [代码]swan[代码] -->
2022-05-16 - WeUI官方组件库:助力小程序高效设计与开发
原文来自「微信开发者」公众号。 本文主要介绍了WeUI官方组件库有什么,怎么用。 提起 WeUI,相信大家都不陌生,WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。 不过,对于 WeUI 样式库,开发者就有疑问了。 [图片] 1 有什么 我们来看看 WeUI 组件库到底有什么可用的 UI 组件呢?WeUI 样式库有的各个元素,WeUI 组件库是基于 WeUI 样式库做了组件化处理,开发者可以便捷的使用,无需考虑组件层面的逻辑问题。 2 怎么用 有了心动的组件之后,大家肯定想知道 WeUI 组件库是怎么使用的。 第一步:引用 要使用 WeUI,首先要把 WeUI 引入我们的小程序项目,引入 WeUI 的方式有以下两种,使用其中一种即可~ 方法一:通过 useExtendedLib 扩展库 的方式引入,这种方式引入的组件将不会计入代码包大小。(推荐👍) 方法二:可以通过 npm 方式下载构建,npm 包名为 weui-miniprogram。 与方法一不同,npm 引入的方式需要多操作一步,在 app.wxss 中引用 weui.wxss。 // app.wxss @import '/miniprogram_npm/weui-miniprogram/weui-wxss/dist/style/weui.wxss'; 第二步:使用 引入之后,我们就要开始来使用了,WeUI 组件库是基于小程序自定义组件构建的,所以使用是以自定义组件的形式来使用。 下面通过几个例子来感受下 WeUI 组件库的使用。 由于是自定义组件的形式,所以使用组件都需要在页面配置中引入,像这样: // page.json { "usingComponents": { "mp-half-screen-dialog": "weui-miniprogram/half-screen-dialog/half-screen-dialog", "mp-searchbar": "weui-miniprogram/searchbar/searchbar" } } 引入组件之后,就可以直接在 wxml 中使用了,当然,为了让开发者接入更加简便,我们也加入了做了一些常见的实用性功能。 半屏弹窗 小程序提供了 wx.showModal、wx.showToast 供开发者进行页面交互,在开发过程中,可能需要自定义按钮相关的内容,所以 WeUI 提供了半屏弹窗让开发者可以有更多的自定义空间。 我们来看下代码,使用很简单,直接使用 mp-half-screen-dialog,配置相关属性即可。 // page.wxml // page.js data配置 buttons: [ { type: 'default', className: '', text: '辅助操作', value: 0 }, { type: 'primary', className: '', text: '主操作', value: 1 } ] 来看下半屏弹窗的效果~ u1s1,这交互体验真的爱了😍 [图片] Form 表单校验 Form 表单这里,除了基础的的功能之外,WeUI 组件库还提供了表单校验的能力,通过 rules 规则的配置(支持长度、手机号码、电子邮件、url 链接地址等),轻松解决表单校验问题。 [图片] 左滑删除 相比 Web 端,手机端的操作按钮更多的是通过⬅️左滑等来实现,考虑到左滑删除的普遍性,WeUI 组件库也是支持的。 在 mp-slideview 组件中设置 buttons属性即可。 [图片] 搜索组件 同样是基本功能的搜索,WeUI 组件库也封装了搜索组件,开发者只需配置搜索结果即可拥有搜索功能~ [图片] 除了这些组件之外,WeUI 组件库还提供了很多实用的组件,包括基础的 icon、loading,表单的 uploader、cell 等等。 第三步:适配DarkMode 伴随客户端、小程序对 DarkMode 的支持,WeUI 组件库也同步适配 DarkMode 的模式,让 WeUI 组件库的使用同学可以快速适配 DarkMode。 在根结点(或组件的外层结点)增加属性 data-weui-theme="dark" ,即可把 WeUI 组件切换到 DarkMode 的表现,如: ... 3 体验WeUI 最后,如果想体验 WeUI 组件库的效果,欢迎扫码下方二维码进行小程序示例体验👏及接入使用,使用过程中如有建议或者疑问,欢迎到微信开放社区与我们交流。 [图片]
2022-03-24 - 小程序性能优化指南
开发者可通过开发者工具中的性能扫描工具提前发现代码中的可优化项: 1. 代码包不包含插件大小超过 1.5 M 【建议】小程序代码包单个包大小限制为2M。因此我们建议开发者在开发时,如果遇到单包体积大于1.5M的情况,可以采取分包的方式,把部分代码拆分到分包去,降低单个包的体积,提升小程序的加载速度。具体可以查看文档《使用分包》。 2. 引用插件大小超过 200 K 【知会】小程序插件的大小是会算进小程序代码包2M体积限制中的。因此当我们发现开发者引用的插件体积大于200K时,会对开发者予以提示,避免出现上传阶段提示代码包体积超限,但是不知道为何超限的问题。 3. 图片和音频资源大小超过 200 K 【建议】小程序代码包里可以存放一些必要的静态资源(如tabbar的icon等);但其他非必要的静态资源体积过大会影响小程序代码包加载速度。因此我们建议图片、音频等静态资源体积大小超过200K时,将它们上传到CDN,用URL引入会是个更好的选择。 4. 主包存在仅被其他分包依赖的JS 【建议】当主包里存在一些JS文件只会被分包使用(而主包自己不使用)时,我们建议把这些JS文件从主包中拆分出去,放到对应的分包里,从而优化主包的加载速度。 5. 主包存在仅被其他分包依赖的组件 【建议】当主包里存在一些组件只会被分包使用(而主包自己不使用)时,我们建议把这些组件从主包拆分出去,并且可以使用 分包异步化 这个特性加载这些组件,从而优化主包的加载速度。 6. 存在无使用的插件 【必须】如果有无使用的插件,请将其从 app.json 中去除。不然它会占用代码包体积,也会延迟代码包加载的时间。 7. 存在无使用的组件 【必须】如果在对应页面JSON的 `usingComponents` 里声明的组件但是没有使用,请将其从 `usingComponents` 里去除。 8. 未开启JS压缩 【必须】在工具「详情」-「本地设置」中开启「上传代码时自动压缩脚本文件」的设置 [图片] 9. 未开启WXML压缩 【必须】在工具「详情」-「本地设置」中开启「上传代码时自动压缩wxml文件」的设置 [图片] 10. 未开启WXSS压缩 【必须】在工具「详情」-「本地设置」中开启「上传代码时自动压缩样式文件」的设置 [图片] 11. 存在无依赖文件 【必须】在「代码质量」面板,点击「建议去除」后,可以打开代码依赖分析面板的「无依赖文件」页面,这里可以看到代码包里没有被用到的文件。请在代码包中去除这部分文件,减小体积并优化加载速度。 在本地开发的过程中,会自动过滤无依赖的文件,如果出现误过滤的情况,可以在 project.config.json 的 setting 字段中添加 ignoreDevUnusedFiles 为 false,也可以在 packOptions 的 include 字段中手动将被忽略的文件引入,同时欢迎发帖反馈误报的情况提交代码片段帮助我们完善此功能 注意:页面若为配置在 app.json 中,将被识别为无依赖文件 [图片] 12. 未开启组件懒注入(按需注入) 【必须】在 app.json 中加入 `"lazyCodeLoading": "requiredComponents"` 可以开启小程序组件按需注入特性。 其他优化内容,请点击学习《小程序性能优化实践》课程 [图片]
2023-02-17 - 云函数获取用户IP归属地
云函数获取当前用户IP归属地的极简代码: const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main = async () => { const wxContext = cloud.getWXContext() let opt = { uri: 'https://apis.map.qq.com/ws/location/v1/ip', qs: { ip: wxContext.CLIENTIP, key: 'HCDBZ-OHMA3-IMQ3R-*****-*****-YNBVU'//在这里获取这个key:https://lbs.qq.com }, json: true } return await rp(opt) } 10行代码,简单地实现了该功能。还不需要申请wx.getLocation接口。
2022-05-26 - 小程序云开发获取并保存用户IP属地
现在各大平台发表文章、评论等内容都显示出了用户的IP属地,现在来探讨一下小程序使用云开发怎么获取并保存用户IP属地。 1、获取到用户ip,这里演示使用云函数获取。 2、使用腾讯位置服务的WebService API的IP定位接口,获取归属地。 响应示例: { "status": 0, "message": "Success", "result": { "ip": "111.206.145.41", "location": { "lat": 39.90469, "lng": 116.40717 }, "ad_info": { "nation": "中国", "province": "北京市", "city": "北京市", "district": "", "adcode": 110000 } } } 演示代码: // 云函数入口文件 const cloud = require('wx-server-sdk') const axios = require('axios') cloud.init() // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); var ip = wxContext.CLIENTIP ? wxContext.CLIENTIP : wxContext.CLIENTIPV6; if (ip) { const res = await axios.get("https://apis.map.qq.com/ws/location/v1/ip", { params: { ip: ip, key: "xxx" // 使用腾讯WebService API:https://lbs.qq.com/service/webService/webServiceGuide/webServiceIp } }); return res; } return null; }
2022-05-11 - 云数据库数据导入要点
导入时,有时会报[代码]invalid character ']' looking for beginning of value[代码]等错误,应该是最后一个元素后面有逗号。要点有下面几条: 数据记录与记录之间,不使用逗号分隔,不使用[]汇总全部记录; 每条记录中数组[],对象{}最后一个元素后面不能加逗号; 所有属性名称,以及字符串的值,全部使用双引号 系统:win7 工具版本:1.05.2107090
2022-02-25 - 云托管征文活动火热进行中,参与即送200元代金券!更有Switch、Kindle等精美好礼
[图片] 很久很久以前,编程江湖就有一个流传至今的未解之谜:什么是世界上最好的编程语言?公元贰零贰贰年,后端技术江湖愈发风起云涌,一时间各路编程豪杰并起,用一身技术本领,演绎一出出拿手好戏,为自己心目中的最佳语言疯狂打Call。在不断地摸爬滚打后,人们不禁:是否有一招从天而降的功法,集各家编程语言之大成,融会贯通,让各路豪杰从眼花缭乱的技术选型中解放出来,在云上闯荡江湖更加轻松?少侠,请留步!欢迎体验腾讯云和微信团队联合推出的后端上云新姿势——微信云托管!汇集丰富开源模板一键部署,带你无需服务器,1分钟部署小程序/公众号/网站服务端。目前,已有数万个业务拥抱云托管,获得更加降本增效的开发生产模式。 [图片] 现在体验云托管,即可享受新用户三个月免费额度! 输出技术实践文章,还可额外获得价值 200 元的云托管代金券,人人有份! 征文主题微信云托管知识分享季 投稿时间长期有效 活动规则文章需要发布在微信开放社区;文章标题:文章的标题后需加后缀“ | 云托管征文”;文章发布后,需将文章链接附在本文的评论区下方;添加小助手微信号boqun1116,领取代金券:示例:一图读懂微信云托管丨云托管征文:https://cloud.tencent.com/developer/article/1842101奖项设置1、200元云托管代金券;优秀文章可任选腾讯视频VIP、QQ音乐VIP、QB、公仔等奖励;云开发公众号、技术社区等渠道署名宣传机会;微信云托管新功能优先体验;专家团队技术交流指导。彩蛋:优秀作者将受邀成为云托管布道师,赠送 Switch、Kindle、京东卡等精美礼品(具体奖品视贡献度而定)。 内容要求分享主题:围绕云托管功能,或针对项目的实践教程、功能介绍、使用心得等;分享形式:技术文章;文章必须为本人原创,不得有广告引流/洗稿/凑字数等行为。一经发现侵权,取消活动参与资格。了解微信云托管微信云托管是微信团队推出的 Serverless 后端项目托管服务,代替服务器,1分钟部署小程序/公众号后端服务。近期推出的「一键部署」功能,还支持通过 Node.js、PHP、Python、Java 和 Golang 等 5 种语言的示例模板,鼠标点一点,即可快速部署一个完整的后端服务,新用户也能轻松上手。 微信云托管官网(请在PC端访问以下地址) https://cloud.weixin.qq.com/ 微信云托管官方文档 https://developers.weixin.qq.com/miniprogram/dev/wxcloudrun/src/basic/intro.html 微信云托管系列教程 https://developers.weixin.qq.com/community/business/course/00068c2c0106c0667f5b01d015b80d 微信云托管专家1V1服务 https://cloud.tencent.com/act/pro/cloudrun *本活动最终解释权归云托管团队所有
2022-02-23 - ColorUI3.x 组件库 原生小程序版 MP CU
[图片] 介绍本项目为 [代码]colorUI3.x[代码] 微信小程序原生版。 [代码]colorUI3.x[代码] 默认只支持 [代码]uni-app[代码],本项目中 [代码]colorUI[代码] 框架为移植修改版。 [代码]colorUI3.x[代码] 地址: https://github.com/weilanwl/coloruiBeta 在线文档:https://mp.color-ui.com/ (主地址,挂在Github上的) 备用在线文档:https://mp-cu.izaizai.cn/ (防止Github抽风,挂在vercel.com上的,建议收藏下) 内置的vuex 渲染引擎参考了 wxMiniStore 项目。 准备配置需要先升级小程序开发工具到 [代码]2021-10-11[代码] 之后的版本, 然后,检查根目录下,[代码]project.config.json[代码] 配置文件内的 [代码]"setting"[代码] 节点下,是否配置了: "useCompilerPlugins": [ "sass" ] 如果没有配置,需要手动配置一下 由于小程序默认开启了 [代码]v2[代码] 的样式,在v2模式下,[代码]colorUI[代码] 部分样式会失效。 完整 [代码]colorUI[代码] 样式,需要在 [代码]app.json[代码] 文件内,删除 [代码]"style": "v2"[代码] 即可 "style": "v2" 框架配置您可单独设置一个 [代码]config.js[代码] 里面配置相关信息,然后暴露方法给 [代码]app.js[代码] 在全局引用 import { ColorUi } from './config' App({ ColorUi, //挂载到app上,此步骤必须要有! onLaunch() { } }) 然后在根目录的 [代码]app.scss[代码] 文件里引入相关框架的css文件。 @import './mp-cu/colorUI/scss/ui'; /* 实际项目中,可删除下面的相关文件和引用,因为图标太多,体积较大,可能你项目里并不需要这么多图标,建议自行添加需要的扩展icon图标引用。*/ /* @import './mp-sdk/icon/doc'; */ 更多相关内容,可访问:mp.color-ui.com/ 鸣谢感谢 【文晓港(ColorUI作者 / @weilanwl)】, 【胖虎(@bypanghu)】
2021-12-27 - 2022-03-07
- 答题小程序中完形填空的设计
离寒假结束还有一段时间,起 作为华南十八线小县城的一个高三英语老师,不管对学生还是老师,他们的寒假已经没有了, 作为普通社畜大年初七已经奔走在岗位了,我们也一样,初七学校已经安排在家远程授课,在科目校外培训严打的今天,学校老师的远程授课最近逐渐常规化了 除了正常授课之外,如何给学生布置一定的课外(课后)作业,这个问题其实,我在新冠爆发的20年就开始着手准备了 刚开始做 了一个很基本的能满足学生答题的小程序到现在持续打磨了二年了,其实也不算持续,仅仅是在每年的寒暑假重拾起来,每次都会有一定迭代 这个寒假也不例外,就是增加对了完形填空的支持 正常的题目都是 一个题目,一个活多个空 完形填空是, 一段信息在前,后面多个空在后,结构是不一样的,我对这块也迟迟没有落地,实现难度确实存在,但是主要的问题是我从内心觉得在手机上做完形填空那就是很反人类的一件事情 所以我的主动性很难调动起来 要不是学科主任的不断催我,我实在是没有这个机会去实现。 其实在之前我也调研过很多,基本上所有的答题小程序都不会支持对这种题型,但是我前几天看到了一个完美解决了 而且解决的 很有创新,他没有把完形填空作为一个全新题型,而是融合到了普通的填空题之中 就是将前面的一段话跟第一个空的标题结合在一起 [图片] 8 [图片] 体验了这个小程序,我的思路也就有了 1 [图片] 2 [图片] 3 [图片] 4 [图片] 5 [图片] 6 [图片] 7 答题小程序中完形填空的设计 除此之外,一般的论述题或者简答题都是同样的设计可以参考的
2022-02-11 - 单词天天斗 (毕业设计/实战小程序学习/微信小程序完整项目)
单词天天斗 (毕业设计/实战小程序学习/微信小程序完整项目) 介绍 小程序我们都很熟悉,它是一种不用下载安装就能使用的、基于微信容器的轻应用。并且微信小程序提供了云开发能力,即无需搭建服务器就可实现后端服务,提供了数据库、云存储、云函数等能力。 该项目基于「微信小程序」原生框架和「微信小程序云开发」实现单词对战类小程序,支持好友对战、随机匹配、人机对战三种不同模式的「对战模式」;另外提供「每日词汇」、「生词本」、「排行榜」、「设置」等功能,实现完整的业务闭环。 单词库包含从小学、初中、高中、四六级、考研、雅思等常需掌握的词汇,支持自定义词库,支持自定义拓展无限本单词书。 技术栈主要为微信小程序、云开发、TypeScript 等,从头搭建项目,基于 git 管理代码版本,使用 eslint 作为代码格式校验,并且组件化拆分页面,前端和云函数均采用 TypeScript。其中将大量实践小程序能力,比如用户信息获取、用户登录、全局状态管理、路由、wxs、npm 包、音频播放、震动、转发分享、动画、云数据库等。 项目提供完整设计稿,项目演示可查看微信小程序「单词天天斗」,扫码体验 ↓ [图片] 适宜人群 毕设参考:项目文档齐全、难度合适、技术广度大、业务闭环,含项目解析文档和教程,这是一个超级适合作为毕设学习的小程序项目。 私有化部署运营:无论你是想通过小程序变现,还是想给自己的「英语课程班级」增加一个支持词汇和单词书自定义的学习渠道,这个都是一个「企业级」的项目选择。 有小程序的前端开发经验,想尝试全栈开发,快速搭建全栈项目的同学。 掌握一定 JavaScript 语法基础,想通过一个精炼的实战案例,来整体地学习前端开发的同学。 想了解小程序开发知识的互联网从业人员。 对小程序开发感兴趣的 IT 技术爱好者。 想要开发一个「对战」类目的小程序,比如单词 PK,公务员考试题目 PK,诗词 PK,驾照考试 PK 等都可以参考该项目实现。 需求介绍 首页 [图片] 首页主要由用户信息展示、提示卡和单词书工具栏、核心功能入口区、底部栏几个模块组成,详细介绍如下: 用户信息展示:当用户已经授权过用户信息的情况下,展示用户授权的头像和昵称信息,如果用户还未授权,则展示昵称为「神秘学霸 (点击登录)」和默认头像,点击后可进行用户信息授权。另外需要展示用户的词力值,对战模式的对站局数和胜利局数。 工具栏:用户当前的「提示卡数目」和当前选择的「单词书的缩写」。点击提示卡后,弹窗提示提示卡的作用;点击单词书后,弹出单词书选择的浮窗列表,可以上滑无限加载,单词书顺序支持配置,单词书列表每项需要展示单词书的完整名称和缩写、词汇数量、选择人数。 核心功能入口:随机匹配、好友对战、每日词汇、生词本入口,当点击除了「生词本」外的其他项,若用户还未进行过用户信息授权,则拉起授权,授权后跳转至对应功能页,「好友对战」入口循环放大缩小动画。 底部栏:排行榜入口、关于&公告入口、建议反馈入口,点击后跳转至不同的功能页,建议反馈跳转页使用微信提供的feedback实现。 其他:整页背景图及设置入口,「设置」增加无限旋转动画,点击后跳转至「设置页」。新用户打开小程序后,增加「添加小程序」引导,点击弹窗后打开操作指南,当点击「我知道了」后,打开小程序不再弹窗引导。 对战模式 [图片] 单词对战模式主要由好友对战、随机匹配、人机对战三种不同的模式组成,详细介绍如下: 对战通用介绍 入口:在小程序首页可通过点击「好友对战」、「随机匹配」分别进入两种不同的模式,在「随机匹配」模式中可开始「人机对战」。 答题模式:对战模式使用根据单词选择单词释义的形式进行答题。 对局词汇数目:每一局对战的词汇数目可在「设置页」中进行设置,支持每局 8、10、12、15、20、30 个词汇进行对战,对战词汇数由对战创建者决定。 对局词汇分类:对战的单词书可通过首页「单词书」选择进行更换,对战的单词分类由对战创建者决定。 对战过程分数机制:对战过程中,当有任意一方选择后,显示该题答题者的得分情况,每道题满分 100 分,选择越快分数越高,选择正确最多获得 100 分,最少获得 1 分,选择错误扣除 10 分。 对战过程答题机制:每道题最长答题时间为 10 秒,当倒计时结束,如若用户还未答题,判定为该题答题错误。当双方都答题结束,切换下一题。 提示卡机制:答题过程中,用户可使用提示卡进行答题,当提示卡数目大于 0 时,点击提示卡则进行选择,得分机制和普通答题一致,但使用提示卡答题的单词需要自动加入生词本。 对战结束:每局对战结束后,需要显示该局的对战结果,包含:本局所有词汇选择结果、用户的选择得分、对战输赢情况。对战结束后根据本局分数计算增加相应的词力值,对战结束页可选择「分享战绩」、「再来一局」。 分享战绩:对战结束后,用户可分享本局对战结果给任意用户或群,用户点击分享结果可进入查看本局的对战结果,但不显示「分享战绩」和「再来一局」,换成显示「创建好友对战」和「返回首页」。 再来一局:对战结束后,对战创建者显示「再来一局」,对战加入者显示「等待创建对战房间」,当房主点击再来一局创建同上一局对战词汇分类和数目相同的对战,另外一个用户由「等待创建对战房间」变为「再来一局」,点击后可加入房间。 对战检测:当对战过程中,有任一用户退出对战则结束对战,提示「对方逃离」后立即进行结算。对战过程中,如果倒计时结束5秒了还没切换至下一题,则认为有用户连接中断,也同样显示「对方逃离」后进行对战结算。 对战过程其他功能:答题错误或者使用提示卡的单词自动加入用户生词本,题目切换时自动播放单词发音,对战过程中播放对战背景音乐,用户可随时开启和关闭。 好友对战 可通过首页「好友对战」创建好友对战房间,可将房间发送到个人或群聊,其他用户点击分享结果后,可点击「加入房间」进行对战加入,房间创建者「好友邀请」按钮变为「开始对战」,点击后双方开始对局。 随机匹配 随机匹配不强制每局的单词对战数目选择一样,只需单词书选择一致的用户就可以匹配到一起进行对战。 如果点击「随机匹配」后,没有已经创建好的随机匹配房间,则创建一个对战房间,等待匹配其他后面点击进入的用户。 如果 2 分钟后,还是没匹配到用户,则开始一局人机对战模式。 人机对战 可在随机匹配页面进入人机对战模式。 人机的用户数据随机抽取使用数据库中预设的用户数据作为头像和昵称展示。 人机选择的正确率为 75% ,人机的选择时间随机在 2 ~ 3 秒之间,在用户选择后 200 毫秒,如果人机还没选择,则人机立即进行答题,减少用户等待时间。 每日词汇 [图片] 答题模式:每日词汇可根据用户选择的单词书进行答题,根据单词选择单词释义。 生命值:每局答题拥有三条生命值,每答错一次则扣除一条生命值,但生命值没有后,可通过分享小程序获取一次复活机会,当机会完全没有后,显示再来一局。 答题分数排名机制:每答题正确一题,可获得一分,一局对战的分数进行叠加,对战结束时使用当前得分和自己的历史最高得分进行比较,如果高于历史最高得分,则记录分数和当前选择的单词书,用于「每日词汇」排行。 倒计时:每道答题时间限制为30秒,如果没有答题则判定为错误。 其他:答题过程中可以使用答题卡进行答题,可以点击「播放发音」选项进行该题单词发音。 其他 (生词本 - 排行榜 - 设置) [图片] 生词本 列表:显示用户在「对战模式」和「每日词汇」中答题错误和使用提示卡进行答题的单词,列表按照词汇加入时间进行排序,先显示最新加入的生词,列表可无限上拉加载。 列表中默认不显示生词的释义,可通过点击「单词」查看释义。 长按生词可切换「删除」生词和「播放单词发音」选项。 排行榜 排行榜支持按照「词力值」和「每日词汇最高分数」进行排序,均最多显示前20名的用户头像、昵称信息。 排行榜底部可根据当前排行榜类型显示自己的排名信息。 设置 对战词汇数目:可设置「对战模式」的每局对战词汇数量。 可设置「对战模式」和「每日词汇」答题过程中是否默认播放背景音乐、是否默认播放单词发音、错题时是否震动。 生词本:一键清空单词本所有数据。 用户信息:可在设置中更新用户的昵称和头像信息,支持自定义昵称和头像。 关于入口 && 微信联系方式。 技术栈 前端:微信小程序原生框架。 服务:微信小程序云开发。 编程语言:typeScript、JavaScript、CSS。 全局状态管理:一个基于微信小程序的mini全局状态管理库 wxMiniStore。 前端路由管理:The router for Wechat Miniprogram - wxapp-router 全局事件管理:Tiny 200 byte functional event emitter / pubsub - mitt 服务端路由、控制器等:轻量级原生实现,支持路由、控制器、Model 数据操作。 动画实现:小程序原生动画,css 动画。 文档 微信小程序云开发:手摸手开发单词对战小程序 (编写中) 基础知识:前端开发快速上手 基础知识:微信小程序开发快速上手 基础知识:微信小程序云开发快速上手 项目新建:小程序TypeScript云开发项目创建及项目工程化 首页样式:首页需求介绍及布局样式开发 首页开发:全局状态管理及登录的实现 首页交互:数据导入及首页数据渲染 首页功能:单词书的分页加载及选择 单词对战:对战需求介绍及全局路由管理 对战创建:用户信息获取及对战房间创建 对战加入:好友邀请及加入好友房间的实现 对战开始:对战过程的实现及题目切换 对战结算:对战结果展示及再来一局的实现 对战匹配:随机匹配的实现及匹配高并发处理 人机模式:人机对战的实现及全局事件管理 对战总结:对战模式其他优化及对战模式实现总结 每日词汇:需求介绍及布局样式开发 词汇选择:答题交互实现及题目切换 词汇结算:任务复活及再来一局的实现 生词本:生词本实现及页面级上拉分页加载实现 排行榜:词力值及每日词汇排行实现 其他页面:设置页及基于富文本的关于页实现 总结:独立开发之旅及项目复盘 附录:小程序调试技巧 附录:数据库设计 附录:小程序自动化脚本部署及源码下载 部署教程 在线文档 部署文档:http://words-pk-deploy.i7xy.cn/ 部署视频教程 部署视频教程 其他 联系我 微信:34805850 后台 [图片] 项目开源 github 单词天天斗:https://github.com/arleyGuoLei/wechat-app-words-pk gitee:https://gitee.com/arley66/wechat-app-words-pk
2022-04-05 - 虚拟业务指南请收好。
在小程序生态中,基于苹果运营规范,小程序内暂不支持iOS端虚拟支付业务。为此小编为大家整理了一份虚拟支付业务指南,希望大家在做虚拟业务时有所帮助: [视频] 那么,到底什么是虚拟支付业务呢? 虚拟支付业务是指购买非实物商品。比如:VIP会员、充值、录制课程、录制音频视频等虚拟产品。目前iOS端暂不支持虚拟支付业务。 我们常见iOS虚拟支付的不合规示例有哪些呢? 示例一 :小程序内存在付费购买虚拟内容或道具。商品多体现为提前编辑好的、录制好的虚拟商品。如录制视频课程、游戏道具。 整改建议 :建议去除小程序内所有付费购买虚拟服务,并根据提示修改相关内容及文案,文案可参照“由于相关规范,iOS功能暂不可用”。 [图片] 示例二 :付费解锁优质服务。多体现为提供虚拟商品的小程序可通过支付购买、开通虚拟会员等形式,体验小程序付费服务。比如:支付阅读章节小说、同城生活服务平台付费发帖/付费置顶等。 整改建议 :建议可以关闭iOS端虚拟支付通道,并将【马上充值】更改为【由于相关规范,iOS功能暂不可用】,并不再提供iOS端会员服务。 [图片] 示例三 :关闭iOS端虚拟支付功能后,虚拟商品页面仍然保留货架价格标签展示、购买/付费/订阅等功能或按钮。 整改建议 :建议去除小程序中的虚拟商品的价格展示,并更改为【免费】;并将【订阅 ¥128】更改为【由于相关规范,iOS功能暂不可用】,并不再提供iOS端虚拟商品购买服务。 [图片] 示例四 :关闭iOS端虚拟支付功能后,提供引导用户前往其他支付的路径/文案,完成虚拟支付闭环。 整 改建议 :建议去除iOS端小程序内引导用户前往其他支付路径/文案,并不再提供iOS端虚拟商品购买服务。 [图片] 示例五 :小程序含需要付费的虚拟商品,并设置限时免费的服务,限时免费结束后需付费才能继续提供服务。 整改建议 :建议将iOS端小程序中所有虚拟付费内容更改为免费,并不再提供iOS端虚拟商品购买服务。 [图片] 示例六 :关闭iOS端虚拟支付功能后,小程序中虚拟产品页面不可以含有付费性质的关键字(如:购买、已购、付费、支付等),包括但不限于功能按钮、功能页面、支付提示及任何商品介绍等。 整改建议 :建议将小程序iOS端虚拟产品页面中的文案/按钮/功能tab含有限制的关键字更改为【免费】或删除。并不再提供iOS端虚拟商品购买服务。 [图片] 如小程序内存在以上不合规的虚拟支付内容,请开发者重视并及时整改。对于首次违规的小程序,平台将下发站内信整改通知,并给予三天整改时间,请开发者按照提示在限期内完成整改。平台将会对到期未完成整改的小程序进行搜索策略调整,并在小程序功能使用上进行一定的限制,直到小程序完成内容整改。
2020-04-23 - 基于小程序云开的会务通小程序设计方案
功能介绍包括大会资讯,参会流程,特邀嘉宾,会场信息,专题论坛,交流沙龙等功能,采用腾讯提供的小程序云开发解决方案,无须服务器和域名 技术运用本项目使用微信小程序平台进行开发。 使用腾讯专门的小程序云开发技术,云资源包含云函数,数据库,带宽,存储空间,定时器等,资源配额价格低廉,无需域名和服务器即可搭建。 小程序本身的即用即走,适合小工具的使用场景,也适合快速开发迭代。 云开发技术采用腾讯内部链路,没有被黑客攻击的风险,安全性高且免维护。 资源承载力可根据业务发展需要随时弹性扩展。 预约管理:开始/截止时间/人数均可灵活设置,可以自定义客户预约填写的数据项 预约凭证:支持线下到场后校验签到/核销/二维码自助签到等多种方式详尽的 预约数据:支持预约名单数据导出Excel,打印 [图片] [图片] [图片] [图片] [图片]
2022-02-28 - 使用开发工具云开发存储下载次数为何一直在自动增加,无任何访问?
最开始只是看到这个现象,所以特意跟了一下,希望其他人也一起观察下,不然下次次数会消耗很快。 使用了云开发,当然也使用了存储,免费版的试用了下。 最开始存储只是上传了很少的几张图片,没感觉下载次数增加很快,有一天上传了大概10多张,不到20张图片,而且还是一样差不多的,不同的图片就三张而已,是通过云开发上传的。 这家伙,感觉下次次数那是蹭蹭网上涨,很快要到1000了。免费的才一月2000,不到一天就接近1000,几乎用了一半。 就打开开发工具,啥都不动,就一会看下那个下载次数变化,发现过一会就还是在涨,次数虽然不多,还是在上涨。 后面,索性把所有下载图片都换成同样的链接,也就是请求一张图片,缓存配置也都是几天的,之前是2小时,并非很短时间,继续观察。下载次数,依然会涨。 [图片] 好家伙,啥都不动,次数也在变化。真的是啥都没动,而且是开发版,只能自己访问。就过一会打开云开发控制台看一下而已,其他的任何操作都没有,就观察下载次数是否有变化,反正每次看,基本上都在变化,有时候少,只有1,2,4这样的增加,依然在上涨变化。 [图片] 还有下载配额不是2000么,还没到1000,就有提示:存储读请求次数余量不足 20%。 [图片] 之前是700多,然后800多的时候,调整了图片,使用了同一张图片,并且连接也是同一个。然后慢慢涨到,现在949了。 [图片] 又增加了4次。 [图片] 也就不到5分钟,又增加了5次。 [图片] [图片] 基本上14:20调整图片为一张图片,连接为同一个连接之后,就没通过小程序访问资源,就只观察云开发控制台,那个数量变化次数跟图上截图变化还对得上。 [图片] 感觉,每过5分钟就有变化。 [图片] [图片] 补充记录: ============= 已删除页面,只保留两个空页面,甚至都没有image标签,而且把开发工具缓存也清空然后重启,依然有下载次数增加。 [图片] 我存储数量目前总共才21个,其实文件只有15个的样子,其他的是目录6个。当然,之前有过文件上传,删除过的。 什么都没有操作,有一次增加30的,这非常诡异,感觉有偷偷跑次数的嫌疑。 [图片] [图片] 感觉,真就是随机的,如果是打开的页面,里面有东西在跑,页面啥都没动,即使内部有处理,按理应该也是相同的次数,不可能是这样随机的变化。 而且,依稀次数变化已经超过我实际的图片的个数。 [图片] [图片] 这个是不是要找官方解释下,不然用着咋放心^_^ 不知其他有仔细观察过没,有没有遇到这个情况。 20220105,继续补充 ================ 特意停了两天,今天有时间再跟了一下。次数依然在增加,所以不是偶然因素。 [图片] [图片] [图片] [图片] [图片] [图片] 今天特意用Fildder抓包看了下,确实小程序内没有产生任何请求。只是在每次进入云开发管理平台,也就是查看存储下载次数的时候,会看到有一个跟云存储相关的请求。 [图片] 完整的请求地址大概是这样的:https://[云开发环境ID相关].cos.ap-shanghai.myqcloud.com/?prefix=&max-keys=1000 唯一这个跟云存储相关,看了下返回的内容,是获取存储的目录文件列表相关的信息。 是否跟该请求有关,按理说即使有关会计算次数,也不会那么多次。这个请求只有一次,次数增加也是随机的。只是发现这个请求次数越多,增加的随机值越大,应该是有一些关联。 这个希望官方确认排查下。
2022-01-05 - “网赚”小程序,你只了解1%
大部分微信开发者对“网赚”的初步认识仅仅局限于网上刷单赚佣金、或阅读文章赚佣金等业务模式。 除以上模式外,还包括自行或协助他人以拟人程序、利诱其他用户参与、转发、下载或委托刷单平台等方式等网赚行为。 今天小编通过实际案例给大家详细剖析相关网赚违规行为: 1. 小程序内纯粹做分享文章/内容后可立即得到奖励的内容(奖励包括但不限于现金、积分、礼品等) 违规示例:如下图违规小程序通过做阅读/转发文章即可获得金币奖励的模式贯穿业务,金币支持兑换现金并提现到账,属于网赚行为。[图片] 2. 小程序内含网赚刷单业务 违规示例:如下图违规小程序为APP提供刷单业务,完成刷单任务后,下载APP即可获取收益,属于网赚行为。[图片] 3. 小程序内存在通过体验APP/小程序/小游戏等产品赚取奖励的行为 违规示例:如下图违规小程序通过体验/转发小程序获取奖励,奖励包括但不限于现金、礼品、积分等,属于网赚行为。 [图片] 4. 小程序内存在通过体验自身业务获取奖励的行为 违规示例:如下图违规小程序通过体验自身业务15秒,即可获得5-10g水滴,水滴可兑换实物或现金等,属于网赚行为。 [图片] 5. 小程序昵称/简介/头像含明显网赚信息 违规示例:如下图违规小程序的头像/简介/昵称含明显网赚信息,诱导进入后获取用户信息,达到网赚推广目的,属于网赚行为。 [图片] 6. 小程序涉及以体验赚奖励、分享赚奖励等业务模式贯穿整个业务 违规示例:如下图违规小程序表面包装成打卡瓜分奖金的业务形态,实际必须通过跳转体验其他小程序、公众号后完成体验任务,才能完成每日打卡任务,属于网赚行为。 [图片] 7、小程序内无实质内容,存在通过批量观看激励视频的形式进行网赚的行为 违规示例①:如下图违规小程序内无实质内容,通过批量观看视频广告获得刮刮卡解锁机会。 [图片] 违规示例②:如下图违规小程序的每一份测试题结果,均需通过观看视频广告才能获得。[图片] 通过以上网赚违规类型及示例的介绍,希望开发者们能对小程序网赚违规有更进一步的了解。如若小程序存在网赚内容,平台将下发警告限期整改,视违规情节严重程度对小程序功能进行限制,或封号处理。
2020-03-18 - 如何使用小程序云开发轻松支撑一场超过50000人的投票活动
记录一次投票活动小程序的运营复盘 ~ 还有不到1小时,今天就结束了,历时10天的投票活动也来到了尾声,从最初的忐忑,到过程中的胸有成竹,到如今的些许遗憾,不过怎么样,这个活动算是完成了 活动官方链接为 https://mp.weixin.qq.com/s/kY6hZTei5vl1nX-Fw 具体的数据和费用我跟大家汇总下 本次活动大概消费了330元,单日日活最高为4.5W,累计投票人次超 8W,累计投票次数超30W 费用这块由于我个人的疏忽造成了很多不必要的消费,这个在前面的文章中已经多次提到了。 ~ 费用这块 [图片] ~ [图片] ~ [图片] ~ [图片] ~ ~ 数据最终定格在 [图片] ~ 其实后面几天扣费一直为0,买的几个套餐都没有消耗,看上去虽然数据库读操作,单日最高突破了150W,但是其实读操作是最便宜的,最贵的还是CDN的流量 第一天没有处理好这一块,第一天就跑了将近一个T,而我买的套餐只是100G,所以整体的支出是在这块,如下图所示 [图片] ~ 今天最后一天我盯了下数据,发现其实还是存在很严重的刷票现象的,比如下面这张截图 [图片] ~ 由于前期对于刷票这个行为没有考虑到,就导致很多用户在后台抱怨数据的不真实性,但是作为投票活动,要真正杜绝刷票真的还是太难了,这个问题也为我日后在小程序优化指明了方向。 今天趁尾声上线了几个小功能 1)增加了用户手机号的收集; 2)在用户反馈模块增加了用户联系方式的收集; 希望通过这二个优化,可以在用户抱怨的时候,做一些安抚的工作,除此之外还真得没有其他好的方式。 后面还有一件事情就是如上面公众号所描述的,随机抽取500位幸运投票用户奖励100元购物礼金,由于在昨天上线了地址收集功能,计划是在本市区随机选500位了 通过这种方式也可以最大程度保证购物礼金的实际兑付。 总结 刷票行为的存在让本来一次很完美的活动出现了一些不好的声音,也给带来了一点遗憾,但是作为一个新的尝试,我也只能安慰自己,其实想想之前第一次做答题活动的时候漏洞百出,甚至导致活动不得延期举办,这本身已是很大的进步了 参考 如何使用小程序云开发轻松支撑一场超过50000人的答题活动? - 微信开放社区 https://developers.weixin.qq.com/community/develop/article/doc/0004e484c14ba0587e5b018b656413 看到这个标题,我临时把刚开始的标题改成了跟这个类似的,也许是为了一种延续,目前答题、投票、抽奖、问卷,我已有其三,希望后面的路越走越宽
2022-01-20