小程序学习记录

65 阅读25分钟

学习路线

管理平台

微信小程序管理平台

小程序里面不同文件类型说明

json(最重要)

  • app.json 是当前小程序的全局配置,包括了小程序的所有页面路径界面表现网络超时时间底部 tab小程序的配置 app.json

  • project.config.json工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。开发者工具的配置

  • pages/页面目录/页面.json独立定义每个页面的一些属性,例如刚刚说的顶部颜色、是否允许下拉刷新等等.页面配置

xwml

充当类似 HTML

wxss

充当类似 css,有全局样式与局部样式

  • app.wxss,全局样式
  • pages/页面目录/页面.wxss 或者 components/组件/组件.wxss

详细的文档可以参考 WXSS 。

  • 定义在 app.wxss 中的样式为全局样式,会影响到每一个页面与组件,页面或者组件可以直接使用app.wxss声明的样式。
  • 不同page.wxss的样式即使是同个className也不会互相影响。
  • page里面的component,他们自己的样式会互相影响,也就是page.wxss与component.wxss会互相影响。

css全局变量的基本用法

小程序使用,全局声明

Page {
    --White:white;
}

子组件/页面组件

color:var(--White)

js

就是js

  • app.js,
  • pages/页面目录/页面.js
  1. WXML - 事件
  2. 小程序的API

微信小程序架构

逻辑层(App service) + 视图层(webview)

逻辑层(App service):

  • 组件/页面编写的js文件。
  • 此js文件不运行在浏览器中。
  • 逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。

视图层(webview)

  • 组件/页面编写的wxml、wxss、wxs文件

一个页面对应一个渲染层,一个小程序有多个页面,也就是说一个小程序由多个webview线程 + 一个jsCore线程组成,线程之间的通信通过native完成。

微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地。然后读取你的app.json文件,从而知道小程序的基本信息,如页面、风格等。

小程序的逻辑层与视图层分别在不同的线程运行,web则是单线程运行。

原因:

  1. 纯客户端渲染,需要随着app发版本而发版本。
  2. 纯h5渲染,ui渲染跟js的脚本执行在同一个单线程中执行,容易导致一些逻辑任务抢占ui渲染的资源。
  3. 介于客户单与h5渲染之间,hybrid技术渲染。

小程序是通过类似与hybrid技术进行渲染的,界面用web技术渲染,用大量的接口提供客户端原生能力,同时小程序每一个页面都是用不用的webview去渲染,避免单个webview任务繁重。

Skyline

针对webview渲染进行了优化,进化成了Skyline,性能更加优越,同时新增了webview所没有的特性,对于低版本小程序如果不支持skyline且没有使用Skyline的新特性,则自动回退到webivew渲染。

-skyline的特性

image.png

小程序与普通网页开发的区别

  • 网页开发渲染线程和脚本线程是互斥的,小程序不是,他们是分开的。
  • 网页开发可以使用到各种浏览器暴露出来的 DOM API,但小程序不行,只能用小程序提供的API。

小程序语法基础知识

js

浏览器js的构成如下

image.png

小程序的js构成如下

image.png

skyline

// page.json
// skyline 渲染
{
    "renderer": "skyline"
}

// webview 渲染
{
    "renderer": "webview"
}

新增特点

小程序宿主环境

app.ts

image.png

onLaunch,onShow参数说明

image.png

如何设置以及获取全局数据,通过小程序api getApp()获取

// app.js
App({
  globalData: 'I am global data' // 全局共享数据
})
// 其他页面脚本other.js
var appInstance = getApp() 
console.log(appInstance.globalData) // 输出: I am global data

官方资料

页面(page/name/name.ts)

image.png

setData修改原则:每次只设置需要改变的最小单位数据。

Page({
  data: {
    a: 1, 
    b: 2, 
    c: 3,
    d: [
        1, {text: 'Hello'}, 3, 4
    ]
  }
  onLoad: function(){
       // a需要变化时,只需要setData设置a字段即可
    this.setData({a : 2})
  }
})

关于setData的注意事项:

  1. 使用this.setData进行修改
  2. 设置的数据不能超过1024kb
  3. 不要将任何一个key所对应的值设置成undefined

小程序的页面前进最多到10层,超过之后需要用redirectTo进行页面跳转

组件

image.png

小程序原生组件

glass-easel,是对旧版组件框架exparser的一个重写,拥有比旧版组件框架更好的性能和更多的特性,注意:目前 glass-easel 组件框架仅可用于 Skyline 渲染引擎,因此这些特性也同样受此限制。

自定义组件

相关资料

{
  "component": true,
  "styleIsolation": "isolated",
}

生命周期说明

组件 image.png

页面 image.png

一个页面+组件初次渲染的生命周期钩子按顺序执行如下:

  • app.onLanuch
  • app.onShow
  • component created
  • component attached
  • page onLoad
  • page onShow
  • component ready
  • page onReady

注意通过app.json配置的"pages"页面路径,此页面一旦进入后就不会被销毁,除非小程序退出。

插件

插件是对一组 js 接口、自定义组件或页面的封装,用于嵌入到小程序中使用。插件适合用来封装自己的功能或服务,提供给第三方小程序进行展示和使用。

官方学习资料

常见的业务场景

1、scroll-view说明

skyline模式下type说明

  • list,适合于不需要复杂布局的场景。例如,普通的商品列表或新闻列表等。
  • custom, 适合需要复杂布局和交互的场景。需要实现吸顶布局、网格布局和瀑布流布局等功能。
  • nested, 适合有多个scroll-view的场景。在这种模式下,内部的ScrollView可以独立滚动,而外部的ScrollView负责整体的滚动和布局。

skyline模式下nested-scroll-header说明

  • 1、只为父scroll-view type为nested服务
  • 2、可以存在多个nested-scroll-header,但是只渲染其第一个子节点

skyline模式下nested-scroll-body说明

  • 1、只为父scroll-view type为nested服务
  • 2、只存在1个nested-scroll-header且只渲染其第一个子节点

associative-container说明

  • nested-scroll-view,为子scroll-view服务,设置这个属性后,父元素scroll-view的滚动与子元素scroll-view的滚动能够衔接自然。

下拉刷新说明

  • 1、启动需设置refresher-enabled
  • 2、需要设置refresher-triggered,一旦下拉成功(通过设置bindrefresherrefresh进行监听)需要将refresher-triggered的值设置为true,待请求完成后再将值设置为false,不这么操作会一直处于加载状态,也就是会有个loading一直在scroll-view那里展示。
  • 4、refresher-threshold的值除了代表刷新触发的阈值,还代表着loading在scroll-view里面占据的高度。如果是通过scroll监听滚动,要留意,当下拉触发成功(bindrefresherrefresh触发)并放手后,scrollTop会逐渐变为0,当触发bindrefresherrestore事件后,scrollTop会瞬间变为refresher-threshold的值(有一点误差),然后再逐渐变为0。
  • 3、如果需要自定义下拉刷新的动态按钮,可以通过<view slot="refresher"></view>自定义,同时scroll-view设置refresher-default-style="none"

2、小程序启动性能与运行性能分析

developers.weixin.qq.com/miniprogram…

3、微信搜一搜内容接入

接入文档

4、https请求

wx.request

注意点:

  • 开发版与体验版允许任意域名,发布版本需要在管理平台进行配置。
  • 只支持https协议。
  • 同一局域网支持http协议,也就是同个wifi下。

5、小程序登录

业务流程图 image.png

注意点

  • 对于没有https的本地开发,我们可以用nginx进行代理本地请求,用公司的证书进行处理。

6、自定义底部导航tabBar

tabBar常用于小程序的底部导航,比如我们常见的app下面的tab页面跳转。这个如果需要自定义展示方式的话,需要在app.json进行配置,同时它有固定的文件名为:miniprogram/custom-tab-bar

官方学习资料

image.png

注意:

  1. 自定义tab需要在app.json配置tabBar,只需要配置基本的内容就好了,配置多也不生效,如下
{
  "tabBar": {
    "custom": true,
    "list": [{
      "pagePath": "pages/index/index",
      "text": "index"
    }, {
      "pagePath": "pages/logs/logs",
      "text": "logs"
    }]
  }
}
  1. 在编写miniprogram/custom-tab-bar文件的时候,你就当成写一个组件,需要编写基本的内容进去,编写后小程序会自动将组件自动引入,并与page组件展示为同一层级。 image.png
  2. 在切换页面的时候,给元素绑定事件但原生不能带参数过去,小程序只能通过元素绑定data-xxx的形式,然后通过事件获取参数值e.currentTarget.dataset。页面切换只能用wx.switchTab({url: path})。url的值要与app.json配置tabBar的pagePath一致
<view class="tab-bar">
  <view 
    class="item {{index === selected ? selectedColor :  color}}" 
    wx:for="{{list}}" 
    wx:key="index"
    data-index="{{index}}"
    data-path="{{item.pagePath}}"
    bind:tap="selectItem"
    >
      {{item.text}}
  </view>
</view>
  methods: {
    selectItem(e) {
      const data = e.currentTarget.dataset
      const { index, path } = data
      this.setData({
        selected:index
      })
      wx.switchTab({url: path})
    }
  }
  1. 自定义的tab-bar选中状态,也就是关于tab-bar的视图变化只能通过页面组件去更新,否则会有大概率更新异常的问题。
Page({
  onShow() {
    if (typeof this.getTabBar === 'function' && this.getTabBar()) {
      this.getTabBar().setData({
        selected: 0
      })
    }
  },
})

7、router 页面路由

  1. 小程序的路由配置是通过app.json进行配置的,不需要额外引入三方库。
  2. 小程序的路由不像网页路由一样,有那么多层级的路由,小程序只有两层。主包与子包。子包就是次级路由,每个子包都处于同一层级,不像网页路由一样有很多层级。
  3. 当重新进入子包,子包页面的生命周期都会重新执行一遍,不会缓存,不像主包一样能缓存。
  4. 子包不会挂载自定义底部导航tabBar。
  5. 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包里所有的页面都下载下来,下载完成后再进行展示。

主包(一级路由)的配置

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
}

分包(二级路由)的配置

{
  "subPackages": [
    {
      "root": "subPages",
      "pages": [
        "detail/index"
      ]
    }
  ],
}

跳转子包

    wx.navigateTo({
      url:'/subPages/detail/index'
    })

8、小程序npm包的引入

官方文档

遇到的问题:

9、store 跨组件通信方式

mini-stores

# 1、引入
npm i mini-stores --save

# 2、点击开发者工具中的菜单栏:工具 --> 构建 npm

# 3、编写文件 store/index.ts
const create = require('mini-stores')
class Store extends create.Store {
  data = {
    title: '小程序多状态管理',
  }
  setTitle(data:string) {
    this.data.title = data
    this.update() // 这段代码执行后,数据才会更新。
  }
}
export default new Store()

# 4、组件/页面引入,在其生命周期中进行数据绑定
import store from '../../store/index'
# 这是组件的写法,页面自己去参考上面的链接
Component({
    ready() {
        store.bind(this, '$store')
    },
}

<view bind:tap="setTitle">{{$store.title}}</view>

10、css变量的使用

11、this.getPageId()

这个是能在组件或者页面都能使用的API,它是用来获取当前页面的标识id,不同的页面标识不一样,只要切换页面,就算进的是同一个页面,pageId还是会变化的。

12、本地数据保存

wx.getStorage 与 wx.setStorage

注意点

  • 不同小程序的本地缓存空间是分开的,每个小程序的缓存空间上限为10MB,如果当前缓存已经达到10MB,再通过wx.setStorage写入缓存会触发fail回调。
  • 同一个设备可以登录不同微信用户,宿主环境还对不同用户的缓存进行了隔离,避免用户间的数据隐私泄露。

常见的业务场景

  • 优化白屏现象,比如列表渲染,一般情况下需要等待拉取图片列表的请求回来才能渲染图片列表。但是我们可以利用本地缓存来提前渲染界面。在发起请求前,先检查是否有缓存过列表,如果有的话直接渲染界面,然后等到请求回调之后再覆盖本地缓存重新渲染新的列表。
  • 存储用户token

13、用户体验思路

  • 等待

image.png

  • 反馈

对于用户的操作结果,需要给出明确的结果反馈,以增强用户的操作信心和控制感。

  • 异常处理

异常场景往往是用户最为沮丧和需要帮助的时候,常见是接口报错,填写不规范等,因此,要注意在异常状态下的设计。在出现异常的时候需要给予用户清晰的状态提示,并告知解决方案,使其有路可退。

14、性能优化

0 项目性能工具诊断
  • 代码依赖分析,对项目进行合理分包。 image.png
  • 代码质量扫描,代码优化大概方向。 image.png
  • performance面板,发现哪些函数方法耗时,有红色框框的 image.png
  • Memory面板,看无操作状态是否有内存增加情况,判断是否有内存溢出 image.png
  • audits面板,节点数量检测、图片格式检测 image.png
  • 冷启动耗时与热启动耗时计数 image.png
1 小程序启动优化

官方小程序启动流程,统计启动时间为到页面的生命周期page.onReady()

总结:启动时间 = 环境准备 + 代码注入 + 首页(初次)渲染

环境准备

  • 运行环境准备(小程序进程+系统组件+UI+webview+js引擎+小程序基础库, 开发者无能为力)
  • 小程序相关信息准备(小程序的头像、昵称、版本、配置、权限等, 开发者无能为力)
  • 代码包准备(《代码包体积优化》,开发者可为)

代码注入

  • 逻辑层js(代码复杂度、同步接口调用(微信api sync结尾的方法)、一些复杂的计算。《代码注入优化》
  • 视图层wxss与wxml(当前页面结构复杂度和页面使用的自定义组件数量。《代码注入优化》
  • 如果未启用「按需注入」,耗时还会与启动使用到分包内的页面和自定义组件总数有关。

首页(初次)渲染

  • 页面+组件的生命周期(app.onLanuch 》app.onShow 》component created 》component attached 》page onLoad 》page onShow 》component ready 》page onReady)
  • 初始渲染缓存
1.0 包体积优化
  • 包大小要求,低于2mb。
  • 主包拆出几个分包,减少主包体积。
  • 分包异步化
主包有组件a,分包A与分包B引用了a组件,此时想要减少主包的体积。
将组件a移到分包A,分包B改成引用分包Aa组件从而到达目的。
这就是分包异步化。

注意:
1、当组件a被分包B引用的时候,分包B的体积并不会变大,这个组件a是算在分包A(不管分包A有没有引用)
2、当进入分包B的时候,a组件的渲染等得到分包A加载完毕才渲染出来。
  • 包体积查看 image.png
1.1 代码注入优化

分包拆分的有可能是一组页面,所以可以用按需注入按需引入来优化非当前页面所引用到的组件。

  • 无注入:在小程序启动时,启动页面依赖的所有代码包(主包、分包、插件包、扩展库等)的所有 JS 代码会全部合并注入,包括其他未访问的页面以及未用到自定义组件,同时所有页面和自定义组件的 JS 代码会被立刻执行。
  • 按需注入:小程序仅注入当前访问页面所需的自定义组件和页面代码。未访问的页面、当前页面未声明的自定义组件不会被加载和初始化,对应代码文件将不被执行。
  • 用时注入:在每一个页面内,如果是第一次渲染该组件,则只有页面的渲染流程结束后才会注入该组件,期间这个组件会以占位组件的形式渲染(包的体积大小还是不变,优化的是代码量注入的时间,前置条件:开启按需注入)。
# json
{
  "usingComponents": {
    "title":"./components/title/index"
  },
  "componentPlaceholder": {
    "title": "view"
  }
}
# js
data: {
    show: false,
},
onTap() {
    this.setData({
      show:!this.data.show
    })
}
# wxml
<title wx:if="{{show}}" style="color: blue;">111</title>
<button bind:tap="onTap" >show</button>

结论:
1、可以用弱网验证title的占位组件展示效果
2、在title组件声明的class与style会作用于占位组件
  • 涉及到启动小程序生命周期的钩子尽量不要用同步api,如getSystemInfo/getSystemInfoSync、getStorageSync/setStorageSync

注意:小程序开发者工具在上传代码的时候,不会将没有引用的组件打包进主包/分包,这在代码依赖分析是不一样的哦,所以无需担心无引用的组件会影响主包/分包的体积大小。

1.2 问答
  • 问:分包用了放在主包的组件(miniprogram/components),那么这个组件是归在主包还是分包?
  • 答:主包
  • 问:小程序编译阶段会不会自动tree shaking?
  • 答:会,但是只是简单tree shaking,它会把没有调用的js进行删除,但是没有es6那么精准,比如
// 如果没有其他地方引用,它会在编译阶段删除const json = {}
const json = {...}
Component({...})

// 但是加入了es6的导出,即使没有引用,它也不会删除。
export const json = {...}

验证方式可以通过开发者工具"上次预览确认"

image.png

  • 问:我写一个组件,但是不在json文件中引用,会影响包体积么?
  • 答:不会,如果在json文件中引用就会。
  • 问:小程序组件使用了按需注入用时注入,会减少包的体积么?
  • 答:不会,减少的是开发者代码注入时间,会优化小程序启动时间,小程序启动时间 = 包下载时间 + 代码注入时间 + ......
  • 问:我在组件的生命周期attached中使用异步方法执行等待一个方法,会不会阻塞到小程序启动时间?
  • 答:不会
1.3 业务实战

通过we分析工具-平台数据-页面访问top10以及业务了解,用户主要打开的页面是feed详情页与feed列表页。而我们的流量主要来源于app分享。

2 小程序运行时优化
2.1 运行时可以优化的点
  • 使用wxs脚本,在视图层完成事件处理
原理就是wxs是在视图层完成的,不需要走逻辑层,减少层与层(线程与线程)之间的沟通
  • 重渲染机制
wxml节点越少、节点嵌套越浅越好。
及格线:每一页的总节点数少于1000,层次低于30层,每个节点的子节点不能多于60个
  • 支持wxwebAssembly
就是使用胶水代码弥补JS的执行效率。
  • 允许开发者另开worker线程
  • 分页渲染、使用虚拟dom
长列表专属,setData不能超过256kb
  • 使用localStorage接口将数据缓存
缓存读取的数据,下次进入的时候先读取缓存的数据,后续再更新接口返回的数据。
  • 使用http2、quic协议
  • getCurrentPage()使用
页面销毁的时候,注意使用getCurrentPage,将页面中关于事件监听、定时器进行销毁,避免GC失效。
  • 获取原生context直接修改dom
  • 图片走CDN,图片格式用webp
4 微信团队性能优化实践
4.1 虚拟列表

recycle-view官方组件使用指南

注意遇到的坑

  • 跟着文档设置itemSize,css设置高度视图不生效,需要设置样式,看下方例子。
  • 现在itemSize设置的高度值跟css设置的高度值一样时,会有误差,也就是长列表滚动到底时,会有一大截空白的内容,这个优化待定。
  • 长列表数量影响性能的话,建议使用。
  • 长列表的里面的item宽、高必须是给到的。
<recycle-view enable-back-to-top catchscroll="onScroll" class="recycleView" batch="{{batchSetRecycleData}}" id="recycleId" >
  <view slot="before">长列表前面的内容</view>
  <recycle-item class="item-wrapper" wx:for="{{recycleList}}" wx:key="index">
    <view class="item-content">
      {{item.title}}
      <image style='width:300px;height:100%;' src="{{item.url}}"></image>
    </view>
  </recycle-item>
  <view slot="after">长列表前面的内容</view>
</recycle-view> 
.recycleView {
  position: relative;
  background-color: yellow;
  height: 500px;
  overflow: hidden;
  .item-wrapper {
    position: relative;
    display: flex;
    height: 150px;
    border: 1px solid black;
    .item-content {
      position: relative;
      height: 100%;
      width: 100vw;
      display: flex;
      flex-direction: row;
    }
  }
}
Page({
  onReady() {
    console.log('page onReady log')
    var ctx = createRecycleContext({
      id: 'recycleId',
      dataKey: 'recycleList',
      page: this,
      itemSize: {
        height: 150, // 值跟item-wrapper一样,但是滚动到底会有空白,需要优化。
        width: wx.getSystemInfoSync().windowWidth,
      },
    })
    let data = []
    for(let i = 0; i < 10000; i++) {
      let item = {title: 0, url: ''}
      item['title'] = i + 1
      item['url'] = 'http://mmbiz.qpic.cn/sz_mmbiz_jpg/GEWVeJPFkSEV5QjxLDJaL6ibHLSZ02TIcve0ocPXrdTVqGGbqAmh5Mw9V7504dlEiatSvnyibibHCrVQO2GEYsJicPA/0?wx_fmt=jpeg'
       data.push(item)
    }
    ctx.append(data)
  },
})
{
  "usingComponents": {
    "recycle-view": "miniprogram-recycle-view/recycle-view",
    "recycle-item": "miniprogram-recycle-view/recycle-item"
  }
}

15、files文件存储相关

官方学习资料

16、canvas相关

官方学习资料

17、订阅消息

用户通过弹窗订阅开发指南

时序图

sequenceDiagram
小程序管理后台->>小程序管理后台: 创建微信的消息通知模板
小程序管理后台->>小程序: 模板id
小程序->>用户: 通过wx.requestSubscribeMessage,向用户请求订阅权限
用户-->>小程序: 返回订阅结果
小程序->>服务: 内部自动告知用户的订阅操作结果
服务->>微信: 下发消息通知
微信-->>小程序: 用户通过“消息通知”的消息卡片进入到小程序

真机开发模式下重置微信小程序订阅权限申请:

image.png 1、一定要进行对应真机的人进行工具登录

在1的基础上每次想要重新唤起订阅权限就进行 “2” “3” 的操作

18、小程序内打开网页

官方文档

1、小程序内怎么打开网页?

需要前往小程序后台配置域名才可以打开。

19、组件computed与watch的使用

学习文档: github.com/wechat-mini…

20、移动端的安全距离

安全区域指的是一个可视窗口范围,处于安全区域的内容不受圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator)的影响。

padding-bottom: env(safe-area-inset-bottom)

关于安全区域的折叠问题解决方案:safe-area-inset-bottom

21、纯数据的设置(非响应式数据设置)

在setData中存储了不需要与页面绑定的数据,需要在.json里面进行配置

xxx.json
{
...
    "pureDataPattern": "^_"
...
}

xxx.ts
data: {
    _test: '不与视图绑定'
}

22、wxs的使用

学习文档

目的:对于频繁设置元素的style与class则可以考虑使用wxs,因为wxs是运行在webview线程(视图层wxml)的,这么做的好处是减少了app serivce线程(逻辑层js)与webview线程(视图层wxml)的通信,优化卡顿时间。

通常使用场景:对于频繁交互的事件,如拖拽,就可以使用这个wxs来优化卡顿情况。

wxs与js(逻辑层)的通信方式

遇到的坑
  • 在本地调试的时候,千万不要开启 skyline调试,它会导致 event跟ownerInstance失效,贼™傻逼。也不说清楚,傻逼小程序文档。

image.png

  • 不能写es6的语法,只能写es5的语法。

  • 这是不用skyline的模式下,如果用了skyline,那么动画效果要用新的动画方案worklet动画来实现

23、worklet 动画

官方学习文档

背景:逻辑层通知到视图层有延迟与不稳定性。

解决:使用worklet函数,优化这种通知

使用场景:频繁变动视图层,如拖拽、手势等。

注意点:

  • 在applyAnimatedStyle声明的更新函数,当shared变量变化时,会自动执行。
  • shared声明的变量不要为数组,因为applyAnimatedStyle无法监听到数组的变化
  • 如果有一组shared变量要声明成数组,可以考虑用this.数组存储,如下:
  initShardData() {
    const itemsRect = this.data.itemsRect
    const sharedItemsRect = []
    itemsRect.forEach((item) => {
      const sharedItem = wx.worklet.shared({
        transY: item.transY,
        transX: item.transX,
        key: item.key,
      })
      sharedItemsRect.push(sharedItem)
    })
    this.sharedItemsRect = sharedItemsRect;
  },
  
  这里有个疑惑,这里监听的是固定位置还是元素引用?
  比如我把数组下标12互换元素位置,这时候,我再更新数组下标2的位置,那么视图更新的是1还是2?
  更新的是1,元素引用。
  • 使用applyAnimatedStyle初始化的时候受CSS动画效果影响,后续通过监听自动变化属性的时候却没有动画效果了,需要使用自定义动画
  • 自定义动画设置的shared变量只能用基本数据类型,否则动画不生效。
  • applyAnimatedStyle pc端不生效,因为渲染模式为webview
   wx.showToast({title: this.renderer})

24、抽象节点的使用

使用背景:

封装了一个组件,这个组件使用了列表循环,这时候列表循环的子元素是插槽内容的话,
当引用这个组件的时候,如果想往插槽传数据,是做不到的,因为列表循环的插槽在封装组件那里。

解决方法就是用抽象节点 官方指导

视音频相关

we分析

小程序数据看板,提供以下服务:

  • 数据分析
  • 性能质量
  • 经营工具
  • 数据管理
  • 平台管理

工作中遇到小程序的坑或者问题

1、明明在.json文件引入了组件,但是却显示不出来

组件的位置换个行,比如从10行引入换成从从5行引入。

也有可能是开发者缓存了,需要清楚缓存,重新打开该项目

2、如何获取url上的参数

在onLoad的参数option上获取,如
// pages/list/list.js
// 列表页使用navigateTo跳转到详情页
wx.navigateTo({ url: 'pages/detail/detail?id=1&other=abc' })

// pages/detail/detail.js
Page({
  onLoad: function(option) {
        console.log(option.id)
        console.log(option.other)
  }
})

3、长屏幕如何滚动?

父容器需要为scroll-view

4、订阅消息相关问题记录

1、怎么知道用户是通过消息通知进来的?

服务端发送订阅消息文档说明

服务下发消息通知的时候,会设置page字段(scheme),前端开发可以通过page字段进行判断。
这个字段具体的值,前端同学需要告知服务端同学。

2、怎么知道用户已经订阅了此消息模板?

通过wx.getSetting) 接口可获取用户对相关模板消息的订阅状态。
或者直接用wx.requestSubscribeMessage再次申请

3、一次订阅只能用一次么?订阅的有效期的是多长?

是的,有效期无限长,直到收到微信的消息通知。

4、已经订阅了能够取消订阅么?

不能哦

5、触发订阅消息报“user tap gesture”这个错误

这是因为你的微信订阅触发了异步操作,不能以异步形式触发wx.requestSubscribeMessage

6、小程序的申请权限勾选了“保持以上选择”之后,“预览”模式下,申请的权限应该如何重置呢?

项目跑起来
点击清除全部缓存
点击编译
点击预览
扫描对应二维码即可

7、小程序的权限申请关于一次性订阅的,只能订阅一个模板消息通知么?

5、引入模块module 'xxx.js' is not defined, require args?

路径是对的,但就是报错了。

解决方案: 重启当前项目(辣鸡开发者工具)

6、构建npm包失败,报错:微信小程序npm构建失败,M packages not found. Please confirm npm packages which need to...

// 解决方案:
project.config.json
{
     "setting": {
        "packNpmManually": true,
        "packNpmRelationList": [
          {
            "packageJsonPath": "./package.json",
            "miniprogramNpmDistDir": "./miniprogram/"
          }
        ]
     }
}

配置完成后重启项目即可

7、本地开发可以,但是预览报Error: 非法的文件,错误信息:invalid file

点击 详情 本地设置 将JS设置成ES5 即可

image.png

8、swiper通过点击事件更改index后,swiper会偶现自动触发onSwiperChange事件且事件类型为“touch”

背景:如果通过点击事件更改index,且index的值很大,swiper会偶现自动触发onSwiperChange事件且事件类型为“touch”,这会导致关于index变换的业务代码重复执行。

解决方式:当触发点击事件时,设置一个变量isBanListenSwiper为true,这时如果触发了onSwiperChange就可以通过isBanListenSwiper来判断是否执行对应的代码。同时给swiper组件设置一个监听事件touchstart,当用户触摸swiper组件的时候就可以将isBanListenSwiper设置为false了。

9、text组件设置了宽度,当字体超过这个宽度时,无法显示省略号,且内容为空白

10、通过点击事件快速切换swiper的index,swiper的视图会跟不上切换

背景:移动端上activeTab的切换过快会导致swiper视图切换跟不上,这里做个防抖处理。

解决方式:设置防抖。

11、页面的存活与进栈、出栈有关,跟页面一二级无关。