小程序开发的一些技巧

195 阅读8分钟

笔者刚接触小程序不久,简单总结下,不对的地方欢迎指正。

官网小程序开发文档

快速新建页面

直接在app.json那边配置页面路径,这样会自动生成,页面的文件夹及其四个文件。

{
  "pages": ["pages/demo/demo"]
}

如果不配置"entryPagePath",则 pages 里的第一个项就是首页。

注意!!!

只有在app.json里配置了才是页面。

页面的四个文件

设置页面的背景色

小程序里,每个页面有个隐藏的根元素page
其最低高度就是整个屏幕的高度,当内容低于一屏时,想要设置整个页面背景色,可以巧妙的利用page元素

page{
	backgroud-color:#fff;
}

page元素

快速查看当前页面的所有绑定数据

调试面板里有个appData,能迅速看到当前时间,data 里所有的值。

调试面板里有个appData

让事件不冒泡

点击列表项跳到详情页,但点击头像是进入个人中心,而不想冒泡触发列表项的点击事件。
这时候可以巧妙的用下catch

<view bind:tap="tapItem" class="item">
  <image catch:tap="tapAvatar" class="avatar"></image>
</view>

事件想获取元素的其他数据 - 自定义属性

vue事件可以传入自定义数据,但是小程序不行,需要先加个自定义属性。

比如点击列表项跳到详情页需要postId

// <view class="item" bind:tap="goDetail" data-post-id="{{item.postId}}">
goDetail(e){
  // 这里请用currentTarget,表示当前绑定事件的元素
  const {postId} = e.currentTarget.dataset
  wx.navigateTo({
    url: `/pages/detail/detail?postId=${postId}`,
  })
}
// detail.js
onLoad(options) {
  const {postId} = options
}

注意!!!
两个单词只能用-连接,而且不能使用驼峰,如果用data-postId的话,获取的时候只能postid

输入框 input 可以使用 confirm 事件

官方文档 input

输入在手机端会调起键盘,而键盘上会有完成键,小程序可以捕获点击完成键

比如:当用户点击完成的时候,搜索

// <input bind:confirm="onSearch" type="search" ></input>
  onSearch(e){
    console.log(e.detail)
    // value就是用户输入的值
    const {value} = e.detail
  },

注意!!! 本地开发的时候,在小程序开发者工具里,可以点击回车键模拟。

设置全局变量

全局变量写在app.js

// app.js
App({
  onLaunch() {
    console.log("app onload");
  },
  test: 1,
});

在其他地方获取:

// 这里的app就是App里的对象参数,里面的所有函数和变量都可以拿到,getApp是小程序的方法
const app = getApp();
const { test } = getApp();

设置全局效果,需要使用全局文件,其在所有页面生效

  • app.js
  • app.json
  • app.wxss

设置页面内部的变量

页面内部可能也需要共享一些变量,但不用显示在页面上

这些变量约定俗成的在前面加个_,增强可读性。

data:{
  _pid:null
},
onLoad(options){
  this.data._pid = options._pid
}

路由跳转区分 navigateTo 和 redirectTo

  • navigateTo:保留旧页面,再跳转到新页面,触发onHide。更多表现父子关系,可以返回父页面。
  • redirectTo:销毁旧页面,直接打开新页面,触发onUnload,如果页面栈是空的话,会显示首页图标。
wx.navigateTo({ url: "/pages/detail/detail" });
wx.redirectTo({ url: "/pages/welcome/welcome" });

注意!!!
小程序目前最多支持 10 层子页面。

让 swiper 滑块容器固定宽高

官方文档

单纯的让设置swiper宽高,有时不一定有理想效果。

此时,可以设置swiper-item里面的元素的宽高。

设置水平滚动的效果

水平滚动是不太能用 web 端的那种,需要使用scroll-view

注意!!!

如果用了 flex 布局的话,记得启用enable-flex

<scroll-view enable-flex scroll-x></scroll-view>

直接显示正在开发的页面 - 增加编译模式

正在开发的页面,不希望总是从首页一点点进去,而是希望页面能直接显示

  • 显示正在开发中的页面
  • 点击编辑区上方的普通编译
  • 添加编译模式
  • 自动填充当前页面的路径,额外需要参数的话自己添加

配置导航栏标题

静态显示,配置页面的json文件,"navigationBarTitleText": "更多"

动态显示,js文件里

onReady(){
  wx.setNavigationBarTitle({ title: 'title', })
}

顺便提下,配置颜色的话使用navigationBarBackgroundColor

在导航栏显示加载图标

// 显示
wx.showNavigationBarLoading()
// 发请求
await wx.request(...)
// 隐藏
wx.hideNavigationBarLoading()

mini_loading

上滑触底加载更多数据

小程序提供onReachBottom,每次滑动到底部的时候,会自动触发该事件。

在该事件里,请求下一页的数据

async onReachBottom() {
    // 如果已经加载完就不用再加载了
    if(this.data._isLoadAll){
      console.log('到底啦')
      return
    }
    // 请求下一页数据
    const res = await wx.request({
      url: '/list',
      data:{
        start:this.data.movies.length,
        count:12
      }
    })
    let list = res.data.subjects
    // 判断是不是加载完了
    this.data._isLoadAll = list.length < 12
    // 追加数据
    list = [...this.data.movies,...list]
    this.setData({
      movies:list
    })
  },

下拉刷新数据

首先在json 文件,配置"enablePullDownRefresh": true

配置完,下拉相应的页面,就会出现三个点的加载效果。

当用户下拉的时候,会触发事件onPullDownRefresh

async onPullDownRefresh() {
  const res = wx.request({
    url:'/list',
    data: {
      start: 0,
      count: 12
    }
  })
  // 记得关闭三个点的回弹的效果,默认的回弹效果时间约3s
  wx.stopPullDownRefresh()
  this.setData({ movies: res.data.subjects })
},

增删改查缓存

小程序的缓存可以存储任意类型的值。

// 增改
wx.setStorageSync("test", 888);
// 删除某个key
wx.removeStorageSync("test");
// 清空缓存
wx.clearStorageSync();
// 查
const test = wx.getStorageSync("test");

一般存储的逻辑是:

// 先从缓存拿数据
let info = wx.getStorageSync("info");
// 根据交互修改数据
info.name = "yan";
// 修改完之后,记得同步下缓存里数据
wx.setStorageSync("info", info);
// 如果需要在view显示,需要更新下data
this.setData({ name: info.name });

更多法子

下载最新的稳定版小程序开发工具

工欲善其事必先利其器,选择最新的稳定版,下载页面

注册 appId 和获取 appId

mini_appid

小程序开发工具的常用设置

  • 稍微隐蔽的:可以切换网络环境、模拟手机端的 Home 键、返回键

  • 编辑器可设置深色皮肤 - 菜单栏的设置里

  • 必须勾选的本地设置

    • 勾选增强编译 (支持 async 这类的)
    • 勾选使用 npm 模块
    • 勾选不校验合法域名 (上线的时候必须是 https,但是测试环境可以没有)

小程序开发工具的常用设置

项目使用 npm

官方文档

  • 先看下根目录有没有package.json,没有的话先执行npm init -y快速创建一个:
  • 本地设置 - 勾选“使用 npm 模块”选项
  • 点击菜单栏 => 工具 => 构建 npm。根目录里会自动生成miniprogram_npm文件夹,里面内容和 node_modules 是一样的。
  • 使用第三方组件的话,和自定义组件一样需要配置字段usingComponents

注意:如果仅是开发情况下用的话,使用npm i xxx -D。这样,打包的时候就不会打包该插件了。

快速查看某个标签的使用文档

将鼠标放在标签上,就会出现一个气泡,就有一个相应标签的文档链接。

设置标签某属性值是 false 的话

布尔类型的属性值:

  • true的话,直接写上改属性即可,<swiper autoplay>
  • false的话,需要加双大括号<swiper autoplay="{{false}}">
  • 其实,只要不是字符串或者数字类型的话,都需要加双大括号

设置选项卡 tabBar

官方文档 tabBar

app.json里添加tabBar,同时需要选中和未选中的图标,文字颜色也一样。 还可以配置tabBar的位置,在顶部或者底部,等等。

  "tabBar": {
    "selectedColor": "#333",
    "color": "#999",
    "list":[
      {
        "text":"阅读",
        "pagePath": "pages/list/list",
        "iconPath": "/images/1.png",
        "selectedIconPath": "/images/1.png"
      },
      {
        "text":"电影",
        "pagePath": "pages/movies/movies",
        "iconPath": "/images/2.png",
        "selectedIconPath": "/images/2.png"
      }
    ]
  }

注意!!!

如果页面变成 tabBarpagePath,跳转的话需要使用 wx.switchTab({url:'/pages/list/list'})

建议:推荐用 import - 导入导出

// 导出数据:
var posts = [{title:"hello"}]
exports { list:posts }

// 导入数据
import { list } from "../data/data.js";
console.log(list);

不推荐 require:

var posts = [{ title: "hello" }];
module.exports = { list: posts };

// 导入数据
var list = require("../data/data.js").list;

建议:引用图片尽量用绝对路径

引用图片可以两种路径:

  • 绝对路径:/images/avatar.png
  • 相对路径:./images/avatar.png

但推荐使用:绝对路径,不容易出错,而且相对简短些。

建议:尽量避免使用小程序的原生 button

小程序的原生button不是很好使用,没有特殊情况,直接用view模拟就好。

推荐:异步方案使用 await

推荐await,注意必须在async函数内部使用:

async onLoad(){
  const res = await wx.request({...})
}

推荐:第三方组件库-LinUI

github 地址 官方文档

LinUI 组件库可以作为小程序原始组件库的补充。

注意:设置 wx:for 的 key 是不要双大括号的

同理,itemindex也不需要双大括号

<block
  wx:for="{{posts}}"
  wx:key="postId"
  wx:for-item="item"
  wx:for-index="index"
>
  <block></block
></block>

注意:image 不支持长按识别

  • image 组件默认宽度 320px、高度 240px
  • image 组件中二维码/小程序码图片不支持长按识别。仅在wx.previewImage中支持长按识别

编写自定义组件

官方文档

自定义组件一般在文件夹components那边,结构和页面根相似,一个组件包含一个文件夹和四个文件。

用自定义组件的话,记得在json 里配置usingComponents:{"post":"/components/post/index"}

这里再次强调,自定义组件的名字是使用页面决定的,并不是文件的名字决定的。

组件添加属性

注意,设置类型就会有当前类型的默认值,Number 的默认值是 0 等等

// 组件内部js
properties: {
  text:{
    type:String,
    // value就是默认值
    value:'123'
  },
  text2:String
},
onLoad(){
  // 获取自定义属性
  const text = this.properties.text
}

使用的话

<post text="77"></post>

添加事件的话放在 methods,类似 vue。

组件添加自定义事件和传参

组件内部

// <view bind:tap="onTap">
methods:{
  onTap(event){
    this.triggerEvent("tapPost",{event,uid:"uid"})
  }
}

使用的话

// <movie bind:tapPost="onGoPageDetail"></movie>
onGoPageDetail(e){
  // e.detail就是triggerEvent的第二个参数,即{event,uid:"uid"}
  const {event,uid} = e.detail

}

给组件容器加样式 - 外部样式类

如果组件写好之后,使用组件的时候,需要给组件在使用场景里增加一些样式,单纯的增加类名,可能 不会生效,这时候需要添加外部样式类。

  • 在组件的wxml的最外层容器 加上 <view class="f-class">
  • 在组件的 js 上增加externalClasses:['f-class']
  • 在使用组件的时候,<movie-list f-class="movie-list">
  • 写样式的时候,.movie-list{margin-bottom: 10rpx;}
Page({
  externalClasses: ["f-class"],
});

样式名,一般都以 class 结尾,可读性强。

外部样式类如果不生效,可能是和组件内部的样式冲突了,增加外部样式类的权重即可,比如!important

注意!!!

上面说了可能不会生效,但是有一种情况是不需要外部类,也能生效的。

当组件是flex项的时候,设置的 class 可生效。

<view style="display:flex">
  <movie class="movie"></movie>
</view>
<!-- wxss -->
<!-- .movie{margin-left:10rpx} -->

引用