- 云开发 多个input的输入内容同时作为查询条件时,如何将空的条件忽略或者条件为空时查询所有?
现在有多个input框来输入查询条件,请问当其中的一个或者多个input输入框输入的内容为空时,如何将为空的条件忽略掉,只进行其他非空条件的判断? [图片]
2021-03-17 - 如何实现快速生成朋友圈海报分享图
由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 Canvas 功能生成一张带有小程序码的图片,然后引导用户下载图片到本地后再分享到朋友圈。相信大家在绘制分享图中应该踩到 Canvas 的各种(坑)彩dan了吧~ 这里首先推荐一个开源的组件:painter(通过该组件目前我们已经成功在支付宝小程序上也应用上了分享图功能) 咱们不多说,直接上手就是干。 [图片] 首先我们新增一个自定义组件,在该组件的json中引入painter [代码]{ "component": true, "usingComponents": { "painter": "/painter/painter" } } [代码] 然后组件的WXML (代码片段在最后) [代码]// 将该组件定位在屏幕之外,用户查看不到。 <painter style="position: absolute; top: -9999rpx;" palette="{{imgDraw}}" bind:imgOK="onImgOK" /> [代码] 重点来了 JS (代码片段在最后) [代码]Component({ properties: { // 是否开始绘图 isCanDraw: { type: Boolean, value: false, observer(newVal) { newVal && this.handleStartDrawImg() } }, // 用户头像昵称信息 userInfo: { type: Object, value: { avatarUrl: '', nickName: '' } } }, data: { imgDraw: {}, // 绘制图片的大对象 sharePath: '' // 生成的分享图 }, methods: { handleStartDrawImg() { wx.showLoading({ title: '生成中' }) this.setData({ imgDraw: { width: '750rpx', height: '1334rpx', background: 'https://qiniu-image.qtshe.com/20190506share-bg.png', views: [ { type: 'image', url: 'https://qiniu-image.qtshe.com/1560248372315_467.jpg', css: { top: '32rpx', left: '30rpx', right: '32rpx', width: '688rpx', height: '420rpx', borderRadius: '16rpx' }, }, { type: 'image', url: this.data.userInfo.avatarUrl || 'https://qiniu-image.qtshe.com/default-avatar20170707.png', css: { top: '404rpx', left: '328rpx', width: '96rpx', height: '96rpx', borderWidth: '6rpx', borderColor: '#FFF', borderRadius: '96rpx' } }, { type: 'text', text: this.data.userInfo.nickName || '青团子', css: { top: '532rpx', fontSize: '28rpx', left: '375rpx', align: 'center', color: '#3c3c3c' } }, { type: 'text', text: `邀请您参与助力活动`, css: { top: '576rpx', left: '375rpx', align: 'center', fontSize: '28rpx', color: '#3c3c3c' } }, { type: 'text', text: `宇宙最萌蓝牙耳机测评员`, css: { top: '644rpx', left: '375rpx', maxLines: 1, align: 'center', fontWeight: 'bold', fontSize: '44rpx', color: '#3c3c3c' } }, { type: 'image', url: 'https://qiniu-image.qtshe.com/20190605index.jpg', css: { top: '834rpx', left: '470rpx', width: '200rpx', height: '200rpx' } } ] } }) }, onImgErr(e) { wx.hideLoading() wx.showToast({ title: '生成分享图失败,请刷新页面重试' }) //通知外部绘制完成,重置isCanDraw为false this.triggerEvent('initData') }, onImgOK(e) { wx.hideLoading() // 展示分享图 wx.showShareImageMenu({ path: e.detail.path, fail: err => { console.log(err) } }) //通知外部绘制完成,重置isCanDraw为false this.triggerEvent('initData') } } }) [代码] 那么我们该如何引用呢? 首先json里引用我们封装好的组件share-box [代码]{ "usingComponents": { "share-box": "/components/shareBox/index" } } [代码] 以下示例为获取用户头像昵称后再生成图。 [代码]<button class="intro" bindtap="getUserInfo">点我生成分享图</button> <share-box isCanDraw="{{isCanDraw}}" userInfo="{{userInfo}}" bind:initData="handleClose" /> [代码] 调用的地方: [代码]const app = getApp() Page({ data: { isCanDraw: false }, // 组件内部关掉或者绘制完成需重置状态 handleClose() { this.setData({ isCanDraw: !this.data.isCanDraw }) }, getUserInfo(e) { wx.getUserProfile({ desc: "获取您的头像昵称信息", success: res => { const { userInfo = {} } = res this.setData({ userInfo, isCanDraw: true // 开始绘制海报图 }) }, fail: err => { console.log(err) } }) } }) [代码] 最后绘制分享图的自定义组件就完成啦~效果图如下: [图片] tips: 文字居中实现可以看下代码片段 文字换行实现(maxLines)只需要设置宽度,maxLines如果设置为1,那么超出一行将会展示为省略号 代码片段:https://developers.weixin.qq.com/s/J38pKsmK7Qw5 附上painter可视化编辑代码工具:点我直达,因为涉及网络图片,代码片段设置不了downloadFile合法域名,建议真机开启调试模式,开发者工具 详情里开启不校验合法域名进行代码片段的运行查看。 最后看下面大家评论问的较多的问题:downLoadFile合法域名在小程序后台 开发>开发设置里配置,域名为你图片的域名前缀 比如我文章里的图https://qiniu-image.qtshe.com/20190605index.jpg。配置域名时填写https://qiniu-image.qtshe.com即可。如果你图片cdn地址为https://aaa.com/xxx.png, 那你就配置https://aaa.com即可。
2022-01-20 - 小程序端视频剪辑的春天来了?
前言-吐槽篇 在这个短视频遍地的时代,小程序端视频剪辑功能似乎一直是缺失状态,前段时间发布了一个视频编辑器的接口,试了下感觉也很鸡肋。也有在社区看到前辈们试水小程序音视频合成初探,研究了一番,其中涉及到几个重要的api:1-视频解码器,将视频解码,获得帧数据绘制到canvas上;2-音视频合成器,负责向原视频中添加音频;3-画面录制器,最后通过画面录制器导出成视频。这里必须要吐槽下小程序的文档,简约派代表,能省略的绝不多写一句,翻一下上述api文档便可石锤,几乎全靠猜,这么复杂的接口也不提供个demo。曾尝试按照上述思路做一些复杂的视频剪辑功能,比如图片视频合成一个,单单解决音频错位的问题就搞得头秃,可以说是步履维艰…… 正文开始 最近发现小程序发布了一款视频剪辑插件 - 微剪,看了下官方提供的Demo还挺有趣的,相比于上述API功能更完善,感觉小程序一直在探索新姿势,真香啊。 小程序:是的,我啥都能做[手动狗头] 本文前半部分旨在结合上述插件,输出一个简单的视频剪辑小程序,感兴趣(不想动手只想白嫖)的同学也可以直接在小程序中搜索「微剪插件演示」,感受一下插件的功能;后半部分着重介绍下插件的一些核心思想和高级用法。 插件接入 微剪以插件的形式提供给开发者,不能单独使用,所以我们必须要先有个小程序主体(不会吧阿sir,这都想白嫖我?如何注册小程序请自行百度好伐)。插件的接入流程也比较简单,官方文档 写的比较清楚,这里就不啰嗦了。目前好像处于公测阶段,可以免费申请使用。 代码开发 上述准备工作做完后,我们就可以在代码中使用微剪插件了,插件暴露了两个组件clip和export,clip是入口组件,export为出口组件,其间的流程完全被插件接管,开发者无需关心也无法干涉(有点霸道总裁的味道了啊),通过一系列简单的配置后就可以看到插件的全貌了。【2020/09/23日 删除】 【2020/09/23日 新增】最新版插件提供两种开发模式,暂称为自动模式(仅通过少许配置即可)和手动模式(利用插件暴露的组件自定义开发,1.3.0版本新增)。先介绍第一种方式,按照下述步骤走一遍,应该就能看到插件的全貌了,问题不大。 step1:app.json 引入插件配置 参考这里:小程序插件配置 [代码]{ "plugins": { "myPlugin": { // 自定义插件名,后面会用到 "version": "1.3.0", // 最新版本号即可 "provider": "wx76f1d77827f78beb" // 插件ID,固定值 } } } [代码] step2:页面中添加插件 新建一个页面,在页面的json文件中引入插件暴露的clip组件 [代码]{ "usingComponents": { "my-clip": "plugin://myPlugin/clip" } } [代码] my-clip: 自定义组件名字,在wxml中使用; myPlugin: 引入插件的时候,在app.json中声明的插件名; clip: 固定值,官方暴露的组件名称。 wxml文件: [代码]<view> <my-clip settings="{{settings}}"></my-clip> </view> [代码] js文件: [代码]Page({ data: { settings: { common: { videoMaxDuration: 30, // 小程序限制最多拍摄30秒 chooseMaxDuration: 1000, // 选择视频的默认时长限制 clipMaxDuration: 60, // 裁切时长的默认限制 } } }, }) [代码] settings有众多配置项,具体可参考官方文档;不设置也可以,插件提供了一套默认的配置项。 PS:这里得吐槽下插件的主题机制,感觉很繁琐。跟平时写vue组件等通过样式覆盖的方案不同,而是通过一系列配置项进行配置,这也意味着只能修改配置项涉及的UI,其他的一律无法修改。这里有个疑问,为什么不采用外部样式类的方案呢?感觉更灵活啊。 到这里,应该就可以在手机上看到插件的全貌了,截取了几张图如下: [图片] [图片] [图片] [图片] step3:导出视频 点击上图的「下一步」按钮,就可以导出视频到相册中了。插件本身也支持自定义导出,下面简单介绍下用法: step3-1:新增导出页 创建一个自定义的导出页,在导出页中引入插件提供的导出组件即可。 json文件: [代码]{ "usingComponents": { "my-export": "plugin://myPlugin/export" } } [代码] wxml文件: [代码]<view> <view>自定义导出界面部分</view> <my-export bindexportsuccess="handleExportSuccess"> <button>自定义导出按钮</button> </my-export> </view> [代码] 然后在js文件中处理导出成功回调即可,导出组件提供了一系列属性,包括水印,导出进度等,具体导出数据结构及属性,可参考官方文档。 step3-2:配置导出页路径 新增上述导出页后,还需要通知插件导出页路径。还记得上文提到的 my-clip 组件中的settings属性吗,此为插件的配置项入口,在里面配置下即可。 [代码] data: { settings: { common: { videoMaxDuration: 30, // 小程序限制最多拍摄30秒 chooseMaxDuration: 1000, // 选择视频的默认时长限制 clipMaxDuration: 60, // 裁切时长的默认限制 exportPagePath: '/pages/export/export' // 自定义导出页面地址 } } } [代码] 事已至此,通过开发工具的预览功能便可以在手机中看到自定义的导出页了。 【2020/09/23日 新增】 高级模式(1.3.0版本新增) 还记得上文提到的简单(自动)模式,我们只用到了插件暴露的两个组件,clip和export,难道插件只暴露了两个组件吗?就这?就这??? 插件从1.3.0版本开始,开放了更多的组件出来,也提供了一种称为【高级接入】的方式,接下来让我们一探究竟: 高级模式需要先了解插件的数据机制,即下文提到的Track驱动模式,在此基础上可以结合插件暴露的组件进行自定义创作。 标准的数据驱动模式 高级模式,即文章开头提到的手动模式,遵循一套标准的Track数据结构,此处引用官方文档的一张图和介绍 [图片] 什么是Track? track顾名思义为轨道,播放器支持多种轨道,如:媒体(视频 或者 图片), 音乐, 特效, 滤镜, 文字 等。 每一种类型的轨道对应不同类型的track,可以简单的理解track就是轨道。 什么是Clip? clip是轨道中的素材片段。举个例子: 你需要编辑三段视频,那么你需要将三个视频片段加入媒体轨道中,那么这里的每个视频片段就对应不同的clip,每个clip的属性会不相同,如: 视频时长,开始结束时间等。 上述官方定义看得有点懵?大白话简单理解,画面播放的时候,我们在某一时刻可以看到(听到)很多元素,比如原始画面的一帧,特效的一部分(几个小心心),滤镜,文字以及音乐等,Track就是这些元素的数据载体,不同的元素由不同类型的Track管理,所以Track是个数组。 随着时间轴的推移,我们又可以看到不同的视频、图片、特效切换效果等等,比如由图片A切换到图片B,再切换到C、由特效A切换到特效B等,这个时候就涉及到clip的概念,clip可以简单理解为上述Track的一个属性,里面存放着原始素材的信息(基本信息,展示时长等),比如上述🌰,负责媒体的Track的clips就得包含图片A、图片B以及图片C的信息,负责特效的Track的clips就得包含特效A和特效B的信息。 官方提供了详细的Track以及Clip的数据接口定义,具体请参考官方文档 数据结构文档 部分,这里只做核心思想解释。 积木已有,创作在你 最新版本(1.3.0)暴露的几个核心组件: wj-player:插件的核心播放器组件,对应的上述简单模式截图里的播放视频的容器; wj-camera:相机组件,可以拍摄视频,也可以从相册选择视频、图片,截图里的图片、视频就是从这来的; wj-clipper:裁切器组件,上述截图中可以看到视频一帧一帧画面的那部分,就是用这个组件实现的。 上述组件即插件实现的核心部分,还有个文字组件(wj-textEditor、向视频中添加文字)和导出组件(wj-export、与自动模式的导出组件基本相同)使用比较简单,每个组件都有各自的属性和方法,具体请参考高级组件API文档。结合标准的Track数据驱动,理论上可以搭配出与插件功能完全一致的视频剪辑体验,当然如果自动模式可以满足业务需求,那白嫖它,做条闲鱼不好吗?如果业务需求需要个性化,可以考虑使用上述手动模式,自力更生,丰衣足食。 光说不练假把式 下面通过一个简单的 相册集小demo 演示一下上述组件的用法,可以下载小程序片段到本地运行(注:由于插件的使用需要先申请资格,所以请填写一个有使用权限的小程序AppID)。主要使用了三个组件,wj-camera(收集素材)、wj-player(展示素材和特效)、wj-export(导出视频),通过camera页面从相册选择图片,然后搭配插件内置的一些特效输出到player页面中预览效果,最后通过export页面导出。 核心代码如下: camera 页面 camera.wxml [代码]<!--pages/camera/camare.wxml--> <wj-camera bindmediachanged="onMediaChanged" > <view class="preview-button" catchtap="onClickDefaultBtn"> <navigator data-source="jump" url="../player/player?type=default" hover-class="none"> <text>随机特效</text> </navigator> </view> <view class="preview-button" style="right:230rpx;width:240rpx" catchtap="onClickPointBtn"> <navigator data-source="jump" url="../player/player?type=wyyl" hover-class="none"> <text>卡点视频(6图)</text> </navigator> </view> </wj-camera> [代码] camera.js [代码]// pages/camera/camare.js Page({ data:{ _media:[] }, onMediaChanged(e){ this.data._media = e.detail.track }, onClickDefaultBtn(){ global.testMedia = JSON.parse(JSON.stringify(this.data._media)) }, // 【万有引力】卡点设置 onClickPointBtn(){ let durationList = [2.6, 2.6, 2.6, 2.8, 2.8, 2.6], startAt = 0 let copyMedia = JSON.parse(JSON.stringify(this.data._media)) copyMedia.clips.forEach((item,index) => { // 更新卡点视频图片播放时长 let duration = durationList[index] item.section.end = duration item.section.duration = duration item.startAt = startAt startAt += duration }); copyMedia.duration = startAt global.testMedia = copyMedia } }) [代码] player 页面 player.wxml [代码]// pages/player/player.js Page({ data: { styleConfig: { height: 1000, width: 750 }, type: 'default' }, onLoad: function (option) { this.setData({ type: option.type }) }, // 生命周期函数--监听页面初次渲染完成 onReady: function () { this.bindPlayer() }, // 绑定player bindPlayer() { this.player = this.selectComponent("#player"); }, // 设置player组件的数据 async onPlayerReady() { let tracks = [] if (this.data.type === 'default') { tracks = this.getDefaultTrack() } else { tracks = this.getWYYLTrack() } this.player.updateData(tracks) // 更新player的数据 global.testExportTracks = tracks // 存储导出页数据 }, // 随机特效 getDefaultTrack() { let startAt = -3, { TRACK_TYPES, CLIP_TYPES, Clip, ClipSection, Track } = global['wj-types'] let mediaTrack = global.testMedia // 获取camera组件输出的media轨道 let effectTrack = new Track({ // 新建一个effect轨道 type: TRACK_TYPES.EFFECT, clips: [] }) let effectList = this.player.getEffects(); // 获取player内置的特效 let randomEffects = new Array(mediaTrack.clips.length).fill(null).map((item, index) => { startAt += 3 return new Clip({ id: `effect-${index}`, type: CLIP_TYPES.EFFECT, key: this._getRandomEffect(effectList).key, section: new ClipSection({ start: 0, end: 3 }), startAt: startAt }) }) effectTrack.clips = randomEffects // 更新effect轨道的clips数据 return [mediaTrack, effectTrack] }, // 【万有引力】卡点特效 getWYYLTrack() { let { TRACK_TYPES, CLIP_TYPES, Clip, ClipSection, Track } = global['wj-types'] let mediaTrack = global.testMedia // 获取camera组件输出的media轨道 let effectTrack = new Track({ // 新建一个effect轨道 type: TRACK_TYPES.EFFECT, clips: [] }) // 定制卡点特效 let effectList = [ { key: 'Swing', duration: 2.6, startAt: 0 }, { key: 'SoulOut', duration: 0.6, startAt: 2.6 }, { key: 'Shining', duration: 2, startAt: 3.2 }, { key: 'SoulOut', duration: 0.6, startAt: 5.2 }, { key: 'Blink', duration: 2, startAt: 5.8 }, { key: 'SoulOut', duration: 0.6, startAt: 7.8 }, { key: 'LightCircle', duration: 2.2, startAt: 8.4 }, { key: 'SoulOut', duration: 0.6, startAt: 10.6 }, { key: 'FlowingLight', duration: 2.2, startAt: 11.2 }, { key: 'SoulOut', duration: 0.6, startAt: 13.4 }, { key: 'Heart', duration: 2, startAt: 14 }, ] let randomEffects = new Array(mediaTrack.clips.length * 2 - 1).fill(null).map((item, index) => { return new Clip({ id: `effect-${index}`, type: CLIP_TYPES.EFFECT, key: effectList[index].key, section: new ClipSection({ start: 0, end: effectList[index].duration }), startAt: effectList[index].startAt }) }) effectTrack.clips = randomEffects // 更新effect轨道的clips数据 let musicTrack = new Track({ // 新建一个music轨道 type: TRACK_TYPES.MUSIC, clips: [] }) let bgMusic = new Clip({ id: 'music', type: CLIP_TYPES.MUSIC, info: { tempFilePath: "https://imgcache.qq.com/operation/dianshi/other/wanyouyinli.c7f973d906d9b8a3e7db90a90a7874d01454614b.mp3", }, section: new ClipSection({ start: 0, end: 1000 }), startAt: 0 }) musicTrack.clips = [bgMusic] return [mediaTrack, effectTrack, musicTrack] }, // 跳转至导出页 goExport() { wx.navigateTo({ url: '../export2/export' }) }, // 获取随机特效 _getRandomEffect(effectList = []) { let index = Math.floor(Math.random() * effectList.length) return effectList[index] } }) [代码] export 页面 export.wxml [代码]<wj-export tracks="{{exportTracks}}" bindexportsuccess="onExportSuccess" bindready="onExportReady"> <button>导出视频</button> </wj-export> [代码] export.js [代码]// pages/export2/export.js Page({ data: { exportTracks: [] }, // 设置导出数据 onExportReady() { this.setData({ exportTracks: global.testExportTracks }) }, // 导出成功回调 onExportSuccess(e){ let res = e.detail; wx.saveVideoToPhotosAlbum({ filePath: res.tempFilePath, success: res => { wx.showToast({ title: "已保存至相册" }); } }); } }) [代码] camera和export页面比较简单,这里就不啰嗦了。主要说下player页面的实现思路,player的Track数据暂时只涉及到了三种:media类型、effect类型以及music类型(卡点模式用),其他的暂未使用。 随机模式:针对每张图随机获得一个特效key(wj-player组件内置了一些特效,直接使用即可),然后设置其时长与media类型的clip时长一致即可(默认是3s)。 卡点模式:根据音乐节奏调整了下每张照片的展示时长。 这样一个简单的照片集应用就做出来啦,so easy,妈妈再也不用担心我的发际线了。 卡点模式最终的成果物 点此预览 PS:使用过程中发现 wj-player 组件和 wj-export 组件无法在同一个页面中使用,不知道是不是我的姿势不对,有待后续验证;还有就是素材切换的时候没有转场动画,显得有些僵硬;另外看了下,特效倒是挺多的,但是没办法一键输出卡点视频,缺少一些常见的视频模板,自己做卡点视频特别费劲,要微调好久…… 自动挡虽然好开,但是真正的赛车手都用手动挡[手动狗头结束] 总结 作为小程序端的一款视频剪辑工具,麻雀虽小五脏俱全,基础的功能是齐全的。个人使用下来整体体验还不错,接入也比较简单,官方配套文档也很完善,也期待官方后续可以提供更丰富的功能、组件。 最后,对视频剪辑小程序感兴趣的同学不防申请插件尝试一下,在官方基础api让人如此头秃的情况下,使用插件或许是个不错的选择。
2020-09-28 - 天天爆单、月入千万,2021小程序10大突破口你知道几个?
回顾 2020,微信小程序除了日活 4 亿外,全年 GMV 同比增长还超过了 100%,更有意思的是:商家自营 GMV 同比提升达到了恐怖的 255%。 这个已经上线 3 年的产品,依旧具有极大的增长潜力和市场空间。 今天,我们特意盘了盘有赞去年打通、上线的 10 个微信小程序关键功能。 温故知新,不断反思尝试,才能打破僵局。也许,这当中就藏着你 2021 年新的突破口! 内容概览: 小程序可生成链接:流量或将翻倍 智能商品悬浮窗:2 个月 5 千万 GMV 智能进店有礼:笔单价提升 11% 智能多人拼团:成团率提高 20% 小程序直播:业绩、拉新的双向优势 一键分享朋友圈:引流转化更直接 附近的小程序:隐藏的外来流量 店铺装修:打造品牌调性 微信物流助手:强大伙伴为你分忧 试用小程序:0 费用、快转正 小程序可生成链接,流量或将翻倍众所周知,过去小程序的流量虽然庞大,但仍受到微信生态和仅支持二维码分享等条件的限制。 小程序支持生成链接后,这一局面被彻底颠覆。从网页、短信、社交 App……凡是你能想到一切分享方式,几乎都能得到实现。 有人预测,2021 年小程序的流量或将因此再翻一倍。 更关键的是,二维码的打开步骤是「识别+打开」两步,而链接只有一步,触达新流量后的打开率也会大大提升。 [图片]这么好的机会摆在面前,你难道想错过吗? 使用路径:有赞店铺后台-应用-配套工具-链接生成工具(小程序)。 智能商品悬浮窗,2 个月 5 千万 GMV大批流量涌入小程序后,光停留在逛店、浏览可不够,还得考虑更重要的转化、成交。除了耗时耗力的营销玩法外,就没有轻松一点的法子吗? 于是,智能商品悬浮窗应运而生。 由 AI 智能算法自动挑选出精选好货、人气爆品等最吸引人的内容,通过「用户浏览足迹」、「热门商品排行榜」、「为你推荐」等形式在首页、详情页等浏览量最集中的核心链路进行展示。 据统计,这一功能在短短 2 个月内,就创造了 5000 万的 GMV [图片] 所以说,明明智能推荐场景简单、高效,何必白白放过流量,把客户让给别人呢? 使用路径:应用中心-个性化推荐-智能商品悬浮窗。 智能进店有礼,笔单价提升 11%为了让新客多次复购,很多商家都爱发优惠券。可是,统一、粗放地发券,既耗费成本,也不能差异化地刺激下单,业绩提升还不明显。 而有了智能进店有礼后,状况就不同了: 可以借助 AI 智能算法,识别客户画像;根据画像,判断出客户历史浏览数据、购买偏好、消费水平等;再结合店铺行业、经营业绩等,定向给不同客户发放不同折扣的优惠券;运营设置好后,折扣会自动上下浮动。[图片] 这么一来,商家便可以省下不少成本:适当减少给部分折扣敏感度低的客户过多的优惠,且仍然能促使其成交。 另外,在客单价的提升也相当明显,比例可以达到 11%。 使用路径:有赞后台-应用-客群维护-进店有礼(原发券宝)。 智能多人拼团,成团率提高 20%在私域社交场景里,团购是非常给力的裂变手段。 可如果完全依靠运营经验、感觉来设置,往往花了大把的钱,拉来的可能都是只想着抢特价的低质量新客。 这时候,就该多用用新上线的智能多人拼团:会根据老客画像、店铺行业与经营状况,为商家提供拼团活动的建议值。 [图片] 据统计,商家采用智能拼团后,平均成团率足足提高了 20%。 以前要花半小时甚至几小时来思考的拼团方案,现在 1 分钟甚至几分钟就能全搞定,还不用起来。 使用路径:有赞后台-应用-多人拼团(系统会自动为你推荐最佳设置)。 小程序直播,业绩、拉新的双向优势说到去年最火的带货模式,绝对非直播莫属。如今疫情反复,线下客源又面临了大幅减少的困境,直播再一次成为焦点。 那么,对于想构建私域流量来说,趁机把老客聚拢到小程序里来,就有了一定规模的初期粉丝,观看量和业绩就有了保证,还有利于持续触达、刺激复购和拉新裂变。 [图片] 特别是在直播间推出爆款单品、引来大批订单时,小程序商城的访问量、加购量都能翻倍式上涨。 更重要的是,用小程序观看直播,不用单独下 App,转发分享更容易带来新粉丝。 使用路径:有赞后台-店铺-微信小程序-小程序直播。 一键分享朋友圈,引流转化更直接既然要做拉新、做直播,就一定不能放过朋友圈这个特大的流量圈子。 之前,把小程序分享到朋友圈的步骤相当麻烦。现在,已经支持一键转发: 点击程序码右上角的「…」按钮;直接分享到朋友圈。[图片] 这一优化最大的好处是: 过去忠诚低一般的老客可能因操作麻烦而不愿转发,现在能把这一大批人都争取过来;让他们养成习惯后,你就等于拥有了一支免费的推广团队。 使用路径:有赞后台-店铺-小程序店铺(小程序升级到最新版即可)。 附近的小程序,隐藏的外来流量在小程序的商家群体中,线下门店占了相当大的比重。想要比同行更快一步、脱颖而出,那就要用好微信内的每一个流量入口,像「附近的小程序」就是非常好的曝光渠道。 商家只要有意识地去推广这个「隐藏」入口,涌入的新流量也会相当可观: 线上:在朋友圈、社群分享小程序时,不定期介绍此功能,通过转发、裂变,完成对陌生消费者的习惯教育和培养。线下:在门店周边摆放易拉宝、投广告等形式,让初次不想到店的新客、或周边的意向客群在线上浏览、下单。[图片]多一个这样的低成本流量渠道,就多省下一笔推广费用。只要试一试,你就知道它管不管用了。 使用路径:有赞店铺后台-店铺-微信-微信小程序-附近小程序。 店铺装修,打造品牌调性品牌调性,是与老客产生深度情感链接的一大关键,而店铺装修就是其中必不可少的一环。 小程序的店铺装修新功能上线后,更特色的导航,更快捷的跳转……都能给客户带来不一样的舒适体验。 [图片] 除了这些,还支持在转发海报、微信小程序时,可以分享大图,方便商家添加更多个性化内容。 [图片]只要品牌够有调性,吸引来的新客就够精准,还怕业绩不上涨? 使用路径:有赞后台-店铺管理-全店装修/微页面。 微信物流助手,强大伙伴为你分忧一家店铺能否让老客持续复购,不单单靠业绩说话,售后同样重要。 小程序接入免费微信物流助手后,商家们便能任意选择最快捷的渠道。用最低的成本,发最快的货! 目前已支持顺丰速运、圆通速递、中通快递、申通快递、韵达快递等众多物流公司。 [图片] 使用路径:有赞后台-应用-配套工具-微信物流助手。 试用小程序:0 费用,快转正讲到这里,可能有些想入局的新商家还会犹豫。 问题在于,微信小程序的势头虽然猛,但也有几个难点: 自己开发难,流程长,还得花不少钱;运营缺经验,老客没使用习惯,担心效果不佳。现在,这些问题一招就能解决:试用一遍就行了。 最近,有赞打通了试用小程序功能:1 分钟内就能快速得到一个体验小程序,时间长达 14 天,试用过程中还可随时转正。 另外,借助有赞完成试用、转正流程,还能免去认证服务费。 开通路径:有赞后台-店铺-小程序店铺-微信。 我们的小建议其实,开通小程序的理由千千万,绝不止这 10 条。 像在微信公开课上还提到的一个点:不断拓宽小程序场景,为小程序生态持续注入活水,大方向是视频号、直播与小程序的互通,形成交易转化闭环。 要知道,视频号的日活也已经达到 3.5 亿,直播的热度更是一直未退,这当中的可能性太多太多了。 但要获得这一切的前提,还是抢先一步、行动起来。成功,永远是留给行动者的! 感兴趣的商家,可点击 → 免费试用有赞店铺~
2021-02-26