# 小程序知识点

# 小程序框架

uni-app

# 开发流程

申请小程序-》完善名称和服务类目-》审核通过绑定商户号、申请渠道 id 和绑定类型-》前后端开发-》开发自测完毕后打包给测试-》测试通过上线就是通过小程序开发工具上传版本,在小程序管理后台审核版本-》审核通过以后可以选择全量发布和灰度发布

# 小程序如何规划分包

分包加载 (opens new window)

目前小程序分包大小有以下限制:

  1. 整个小程序所有分包大小不超过 20M
  2. 单个分包/主包大小不能超过 2M

# 小程序图片怎么处理

  • 图片压缩
  • 静态 cdn 资源
  • 本地图片引用最好将图片转成 base64 (在 js 中通过 import 的方式引入图片)

# 小程序页面有哪些传递数据的方法

  • 使用全局变量实现数据传递;

    • app.js 中的 this.globalData = { } 中放入要存储的数据。 在组件.js 中, 头部 引入 const app = getApp(); 获取到全局变量 直接使用 app.globalData.key 来进行赋值和获取值。
  • 页面跳转时或重定向时,使用 url 带参数传递数据;

    • 使用路由 wx.navigateTo 和 wx.redirectTo 时,可以通过在 url 后 拼接 + 变量, 然后在目标页面通过在 onLoad 周期中,通过参数来获取传递过来的值。
  • 使用组件模板 template 传递参数;

    • 在页面标签上通过 绑定 dataset-key = value , 然后绑定点击通过 e.currentTarget.dataset.key 来获取标签上绑定的值。
    <button bindtap="get" data-name="测试">拿到传值</button>
    
    get(e){ console.log(e.currentTarget.dataset.name) },
    
  • 使用缓存传递参数;

    • 使用 wx.setStorageSync 和 wx.getStorageSync 存储数据

# 小程序内的页面跳转

  • wx.navigateTo() 跳转到其他页面(非 tabbar)当前页面仅隐藏,可返回当前页面
  • wx.redirectTo() 跳转到其他页面(非 tabbar)当前页面卸载,不可返回当前页面,直接返回上一级页面
  • wx.switchTab() 跳转到底部 tabbar 页面,当前页面卸载
  • wx.navigateBack() 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层
  • wx.reLaunch() 小程序重载回到首页,关闭所有页面,打开到应用内的某个页面

# 小程序路由栈深度

wx.navigateTo,小程序中页面栈最多十层 (opens new window)

navigateTo 和 redirectTo 如何在项目中用?不需要回到上一层就用 redirectTo

# 小程序生命周期函数

  • onLoad:页面加载,调一次,可获得当前页面路径中的参数
  • onShow:页面显示,每次打开页面都调用,一般用来发送数据请求
  • onReady:初次渲染完成,调一次,代表页面已可和视图层进行交互
  • onHide:页面隐藏,当 navigateTo 或底部 tab 切换时调用
  • onUnload:页面卸载,当 redirectTo 或 navigateBack 时调用

# 小程序 wxss 与 css 的区别

  • wxss 背景图片不能采用本地相对路径或绝对路径引用,只能引入外链或者本地图片转换成 base64 的方式使用,
  • wxss 样式使用 @import 引入外联样式文件,地址为相对路径。
  • wxss 尺寸单位为 rpx,rpx 是响应式像素,可以根据屏幕宽度进行自适应。

# 小程序 wx:if 和 hidden 的区别

  • wx:if : 有更高的切换消耗。
  • hidden : 有更高的初始渲染消耗。

使用:频繁切换使用 hidden, 运行时条件变化使用 wx:if

参考 (opens new window)

# 小程序怎么实现下拉刷新

  1. 通过在 app.json 中, 将 "enablePullDownRefresh": true, 开启全局下拉刷新。 或者通过在组件 com.json , 将 "enablePullDownRefresh": true, 单组件下拉刷新。

  2. scroll-view : 使用该滚动组件自定义刷新,通过 bindscrolltoupper 属性,当滚动到顶部/左边,会触发 scrolltoupper 事件,所以我们可以利用这个属性,来实现下拉刷新功能。

# 小程序性能优化

  1. 减少 setData 调用次数、传递的数据量(频繁调用 setData 及 setData 过程中页面跳闪)
  2. 减少使用大图片资源
  3. 减少默认 data 的大小
  4. 控制包的大小(压缩代码,图片资源 CDN 部署,分包)
  5. 在 onLoad 阶段发送请求,先加载页面骨架,无需等待 ready
  6. 局部刷新;不改变大数据的整体接口,更新大数据中的具体更新的属性值
  7. 页面跳转的时候销毁定时器,事件监听等

# 小程序的原理

小程序分为两个部分 webview 和 appService,webview 用来展现 UI,appService 用来处理业务逻辑、数据及接口调用,它们在两个进程中运行,通过系统层 JSBridge 实现通信,完成 UI 渲染、事件处理。

# 小程序运行机制

热启动 :假如用户已经打开了某个小程序,在一定时间内再次打开小程序的话,这个时候我们就不再需要重新启动了,这需要把我们的后台打开的小程序切换到前台来使用。

冷启动:用户首次打开小程序或被微信主动销毁再次打开的情况,此时小程序需要重新加载启动。

# 小程序如何加载 H5 页面

<web-view src="https://baidu.com"></web-view>

直接从上一个页面路径用 navigateTo 跳转到这个 web-view 所在路径页面就行

# setData 的回调函数

微信小程序的 setData 实现是和 react 的 setState 实现类似的,所以它也是一个异步函数,并且有回调函数的参数,当然平时小量数据我们可能并没有感觉到它的异步,但是为了确保逻辑的正确执行,在需要用到 setData 后 data 里的数据的步骤,请写入 setData 的回调函数中,如下示例:

this.setData(
  {
    a: this.data.a++
  },
  () => {}
)

# webview 中的页面怎么跳回小程序中

wx.miniProgram.navigateTo({url: '/pages/login/login'+'$params'})
wx.miniProgram.navigateTo({url: '/path/to/page'})

# bindtap 和 catchtap 的区别是什么

bindtap 不会阻止冒泡事件,catchtap 阻止冒泡

# uni-app 的数据和页面渲染是由谁负责

Vue 负责数据管理,小程序负责页面渲染。 小程序负责视图渲染,页面 DOM 由小程序负责生成,小程序只接受 data 数据传递。

对应 vue 的执行流程,大致三方面的优化:

  • compile:optimize 过程可取消,因为该环节是为了标注静态文本节点,而 Vue 只负责数据,不需要关注 DOM 节点;
  • render function:不生成 vnode;
  • patch:不比对 vnode,因为 setData 仅能传递数据,所以我们只比对 data。

# uni-app 和原生有啥区别

  1. 小程序的双向绑定和 vue 区别:小程序直接 this.data 的属性是不可以同步到视图的,必须调用 this.setData({})
  2. 小程序和 vue 写法的区别

遍历时:

小程序  wx:for="lists"
vue    v-for="item in lists"

调用 data 模型时:

小程序:
this.data.item //调用
this.setData({item:1}) //赋值
vue:
this.item //调用
this.item=1 //赋值

# uni-app 中的条件编译如何使用

条件编译是里用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

# API 的条件编译

获取胶囊位置,API getMenuButtonBoundingClientRect 在微信小程序运行的时候才会生效,H5 会报错

// #ifndef H5
const menuTop = uni.getMenuButtonBoundingClientRect().top
// #endif

# 样式的条件编译

登录模块在微信小程序端背景颜色为白色

<style>
  /*  #ifdef MP-WEIXIN  */
  .login-container {
    background-color: #ffffff;
  }
  /*  #endif  */
</style>