简单入门微信小程序

220 阅读11分钟

先上官方文档,我见得很简陋,完整的可以在这里查 全局配置 | 微信开放文档 (qq.com)

文件类型:

image.png

.wxml模板:

1.标签名的一些更改:
<div /> === <view />
<span /> === <text />
<img /> === <image /> image的属性:src、model,具体选项 可以查文档,且自带宽高

2.定义事件:
bind:事件类型="事件处理函数"
点击:click ===> tap

.js中的逻辑:

Page({
    data:{
        msg:'你好',
        message: {
            say: '谢谢'
        }
    }
})

注意:.js文件中至少有一个Page({}),否则页面不显示

定义方法:

Page({
    newFunction() {}
})

修改数据

Page({
    //基本数据类型
    this.setData({
        msg:'我很好'
    })
    
    //引用数据类型
    //1.类似解构的语法
    this.setData({
        message: {say: '不用谢'}
    })
    //2.简写
    this.setData({'message.say': '不用谢'})
})

使用数据
1.在wxml中:
使用插值表达式{{}},和vue不同,不管是内容还是属性都可以使用过插值表达式,但是不能调用方法
2.在js中:

Page({
    data:{msg: {
        message:  '你好'
        }
    },
    say() {
        console.log(this.data.msg)
    }
})


双向绑定数据: model:value="{{}}",和vue不同,小程序的双向绑定无法绑定复杂数据(引用数据类型

.wxss样式:

定义全局样式:
app.wxss中定义的类名,可以在所有的组件中使用,其中的标签选择器,会选中所有组件中的该标签
注意:
wxss文件中,无法直接调用本地的图片,如果需要,可以使用网络图片,可以使用<image>,可以使用base64格式的图片

.json配置

1.全局配置: 注意:最外层是一个匿名(无名)对象 路径(默认相对路径):

{
"pages":\[
"pages/index/index",
"pages/logs/logs",
"pages/page1/pageOid",
"pages/page2/pageNew"
],
}

常见window配置(全局有,局部无):

  {
      "window":{
        "navigationBarBackgroundColor": "#fff",    //头部背景颜色
        "navigationBarTitleText": "标题",          //标题内容
        "navigationBarTextStyle":"black",          //导航栏标题颜色
        "backgroundTextStyle":"light",             //下拉 loading 的样式,仅支持 `dark` / `light`
        "enablePullDownRefresh":true               //是否开启全局的下拉刷新
      }
  }

常见tabbar配置(全局有,局部无):

{
   "tabBar": {
       "color": "#999",                   //默认颜色
       "selectedColor": "#ff0000",        //选中颜色
       "list":[                           //设置导航按钮列表,数组元素最少有两个,最多五个
         { 
           "pagePath":"pages/index/index",           //地址
           "text": "主页",                           //页面文字简述
           "iconPath": "./pages/static/tabbar/home-default.png",            //默认页面图标
           "selectedIconPath": "./pages/static/tabbar/home-active.png"      //选中时图标
         },
         { 
           "pagePath":"pages/page2/pageNew", 
           "text": "老页面", 
           "iconPath": "./pages/static/tabbar/face-default.png",
           "selectedIconPath": "./pages/static/tabbar/face-active.png" 
         }
       ]
     },
  }

2. 常见局部配置
 2.1自定义头部导航 

//在xxx.json中配置
{
"navigationStyle": "custom"     //自定义头部导航
}

3. 怎么解决微信要求整个小程序主包和分包代码加起来不超过20M,单个包要求小于2M的问题

 3.1.忽略静态资源

//在project.config.json文件配置
{
  "description": "项目配置文件",            //描述
  "packOptions": {                         //包的设置
    "ignore": [                            //忽略配置
      {
        "value": "static/uploads",         //需要忽略的文件路径
        "type": "folder"                   //需要忽略的文件类型(这里是文件夹
      }
    ],
    "include": []
  }

 3.2配置分包

//在app.json中配置
{
  "subpackages": [                            //分包配置项
      {
        "root": "packageA",                   //分包包名
        "pages": [                            //分包有哪些页面
          "pages/cat",                        //分包页面路径
          "pages/dog"
        ]
      }, {
       "root": "packageB",
        "name": "pack2",
        "pages": [
          "pages/apple",
          "pages/banana"
        ]
      }
   ]
 }

 3.3主包配置分包的预加载

 //在app.json中配置
 {
    "preloadRule": {                            //预加载规则
        "pages/index/index": {                  //预加载分包的路径
          "network": "all",                     //在什么网络环境下加载
          "packages": ["important"]             //需要预加载的包名
        }
    } 
 }

屏幕适配

自带适配单位rpx,约定所有屏幕宽度下,750rpx即沾满一行

路由跳转

  1. 使用<navigator>标签, 使用url属性跳转
  2. 跳转到tabBar页面,配置了tabBar之后,如果代码在跳转且目标页面是vavbar的页面,需要配置 open-type="swithTab"
  3. 跳转到其他小程序,需要加上属性target="miniProgram"以及app-id="wx123456789"
//绝对路径跳转
<navigator url="/page/page1/page1">跳转至其他页</navigator>

//相对路径跳转
<navigator url="../page1/page1">跳转至其他页</navigator>

//跳转到其他小程序
<navigator target="miniProgram" app-id="wx123456789123">跳转至其他页</navigator>

//跳转到tabBar页
<navigator open-type="switchTab" url="/page/page1/page1">跳转至其他页</navigator>

轮播图

swiper | 微信开放文档 (qq.com)
简单写一个轮播图

<swiper 
class="swiper"     
indicator-dots      //是否显示面板指示点
interval="5000"     //轮播间隔时间
circular="true"     //是否采用衔接滑动
autoplay            //是否自动切换
>
  <swiper-item>
    <image class="img" src="https://img.alicdn.com/imgextra/i2/O1CN01lFNk4Z1JDkviZe8EG_!!6000000000995-2-tps-846-472.png" mode="" />
  </swiper-item>
  <swiper-item>
    <image class="img" src="https://img.alicdn.com/imgextra/i1/O1CN01DZGZD41NmnhXf5uB7_!!6000000001613-0-tps-846-472.jpg" mode="" />
  </swiper-item>
  <swiper-item>
    <image class="img" src="https://img.alicdn.com/imgextra/i4/O1CN01cmWoxh1S6H07yrmcM_!!6000000002197-0-tps-846-472.jpg" mode="" />
  </swiper-item>
</swiper>

表单控件

button | 微信开放文档 (qq.com)

侧边栏

scroll-view | 微信开放文档 (qq.com)

小程序的一些指令

这里需要有vue基础方便理解

  1. model:value ==> 数据双向绑定 ,类似于v-model
  2. wx:if ==> 符合/不符合条件,创建/销毁元素 ,类似于v-if
  3. wx:ifel ==> 类似于v-else-if
  4. wx:else ==> 类似于v-else
  5. hidden ==> 符合/不符合条件,显示/隐藏元素 ,类似于v-show
  6. wx:for="{{list}}" ==> 循环数组,并提供item(每项元素)和index(角标) ,类似于v-for="(item, index) in list"
  7. wx:key ==> 用于提升渲染效率,微信官方推荐循环普通数组,key值为*this

注意!写属性时,引用变量一定要记得带{{}}

小程序中发请求的API ( wx.request )

开发阶段,需要勾上:
右上角详情 => 本地设置 => 勾上下图选项

image.png
否则需要在 微信公众平台 => 开发管理 => 开发设置 => 服务器域名 那里注册你的地址,才能发请求
注意,微信要求只能注册https协议的地址,http不行!

  getBook() {
    wx.request({
      url: 'https://xxxxxxxxxxxxxxxxxxx',        //请求路径
      method: 'GET',                                       //请求方法
      data:{},                                             //请求参数
      success:(res) => {                                   //成功后回调
        console.log(res);
      },
      fail(error){                                         //失败后回调
        console.log(error);
      },
      complete() {                                         //不管成功失败都调用
        console.log('不管成功失败都调用');
      }
    })
  },

注意:如果你发现有这个报错:

image.png 说明将方法定义到了data中

小程序的提示和加载显示

wx.showToast(Object object) | 微信开放文档 (qq.com)

  getBook() {
    wx.showLoading({                //开启加载状态
      title: '正在取回数据',         //加载时提示文字
      mask: true,                   //防止触摸穿透,即不要在加载时还能点东西
    })
    wx.request({
      url: 'http://xxxxxxxxxxxxxx',
      method: 'GET',
      success:(res) => {
        console.log(res);
        wx.showToast({
          title: '成功获取数据',     //提示文字
          icon: 'success',          //提示图标类型
          duration: 2000            //提示显示时间
        })
      },
      fail(error){
        console.log(error);
        wx.showToast({
          title: '未能获取数据',
          icon: 'error',
          duration: 2000
        })
      },
      complete() {
        console.log('不管成功失败都调用');
        wx.hideLoading()            //关闭加载状态
      }
    })
  },

小程序的本地数据缓存

wx.setStorageSync(string key, any data) | 微信开放文档 (qq.com)
常用API:

  • wx.setStorageSync(key, value) 存入一个数据,复杂类型数据不需要 JSON.stringify 处理
  • wx.getStorageSync(key) 读取一个数据,复杂类型数据不需要 JSON.parse 处理
  • wx.removeStorageSync(key) 删除一个数据
  • wx.clearStorageSync()清空全部数据

小程序API的类型

  1. 同步的,特征是API名字后面带sync
  2. 异步的
  3. 支持promise对象的,如图,不支持就不能

image.png

小程序事件处理函数传参问题

首先小程序的事件处理函数是无法传参的,为了解决该问题,有两种解决方案
这两种解决方案都需要用到事件对象,事件处理函数的第一个参数会接受事件对象

1. mark:参数名="值"
// 在.wxml中
    <view><button bind:tap="getMark" mark:id="10">getMark</button></view>
// 在.js中
    Page({
      getMark(e) {
        console.log(e);
      }
    }
    

image.png

2. data-参数名="值"
// 在.wxml中
    <view><button bind:tap="getData" data-num="10">getData</button></view>
// 在.js中
    Page({
      getData(e) {
        console.log(e);
      }
    }

image.png

常用组件事件

1. scroll-view组件
a. `bindrefresherrefresh` 自定义下拉刷新被触发<br>
b. `bindscrolltolower` 滚动到底部/右边时触发<br>
2. form组件
a. input组件,使用`model:value`双向绑定<br>
b. radio/checkout/picker组件,使用`bindchange`,在事件对象的detail属性中获取值<br>
c. 表单的整体提交:<br>
   i.需要在form标签上定义事件`bindsubmit`<br>
   ii.需要在button按钮上添加`form-type="submit"`属性<br>
   &emsp;&emsp;&emsp;iii.需要给所有的表单控件加上name属性<br>
   iiii.在事件对象的detail属性中获取值和form表单的id

小程序页面级别生命周期

生命周期 | 微信开放文档 (qq.com)

  1. 加载页面钩子onLoad     常见场景发请求
  2. 显示页面钩子onShow       更新数据(从本地数据/示例数据....)
  3. 准备完成钩子onReady    只在第一次打开执行一次,用于开场动画
  4. 隐藏页面钩子onHide      常见场景清除定时器
  5. 销毁页面钩子onUnload

小程序应用级别生命周期

App(Object object) | 微信开放文档 (qq.com)

  1. 小程序启动onLaunch   常见场景,获取query参数,记录场景值scene:判断用户是哪种方式点开的
  2. 小程序显示onShow
  3. 小程序隐藏onHide

自定义组件

1.创建自定义组件

image.png  1.1 在根目录创建components文件夹
 1.2 在components文件夹下在创建一个文件夹,该文件夹名就是组件名
 1.3 右键组件文件夹,点击新建 Component
 1.4 注册组件
  1.4.1 全局注册,在app.json中设置"usingComponents": {"组件名" : "组件路径", ...}
  1.4.2 局部注册,和全局一样配置,但要在页面的.json文件中配置
 1.5 在需要调用组件的页面的.json文件中设置"component": true,

2.怎么配置自定义组件样式为全局的(一般不用,也不建议用)

//在组件的.js文件中配置
    Component({
      options: {
        addGlobalClass: true   //设置类名为全局的
      }
    })

3.怎么设置外部样式类

 3.1 在组件的.js文件中配置外部类

Component({
  externalClasses: ['my-class1', 'my-class2', ...]
})

 3.2 在组件的.wxml文件中使用类名

<text class="my-class1">组件1</text>

 3.3 在调用的页面的.wxss里用这个类名写样式

.my-class1 {color: red;}

 3.4 在调用的标签内传入类名,语法为 类名="类名"

<MyComponent my-class="my-class"></MyComponent>

4.自定义组件怎么定义数据和方法?

Component({
    data:{               //定义数据,必须写在data对象里,和页面没什么不同
        msg: '你好'
    },                   
    methods:{            //要注意,定义方法必须写在methods对象里!!
        changeMsg(){
            this.setData({
                msg: '我很好,谢谢'
            })
        }
    }                 
})

5.自定义组件中的插槽

5.1 如何定义和使用插槽?

  5.1.1在组件的wxml文件中使用<slot>标签占位

<view class="my-navbar" style="padding-top: {{top}}px;">
  <slot></slot>
</view>

  5.1.2在页面的组件标签中,写入新标签和内容,自定义组件部分功能

<my-navbar>
    <view>左边</view>
</my-navbar>
5.2 如何定义和使用具名插槽?

  5.2.1 在组件的.js文件中配置开启具名插槽模式

Component({
  options:{
    multipleSlots:true
  }
})

 5.2.2 在使用slot标签占位时,加上name属性

<view class="my-navbar" style="padding-top: {{top}}px;">
  <slot class="left" name="left"></slot>
  <text class="title">你好</text>
  <slot class="right" name="right"></slot>
</view>

 5.2.3 在组件中使用多个插槽,并使用slot属性匹配对应的name

<my-navbar>
    <view slot="left">左边</view>
    <view slot="right">右边</view>
</my-navbar>

6.自定义组件的生命周期

created不能使用setData,此时一般用于给this加属性 attached常用于发请求

Component({
  lifetimes:{
    created() {
      console.log('组件被创建了');
    },
    attached() {
      console.log('组件可以发请求了');
    }
  }
})

7.自定义组件的传值

7.1 父(页面)传子(组件)

  7.1.1 将要传值的变量名作为属性写在页面的组件标签头里

<my-com2 msg="你好"></my-com2>

  7.1.2 在组件的.js文件中设置接收

Component({
  properties: {
    msg: {
      type: String,
      value: "nihao"
    }
  }
})

  7.1.3 在组件中调用

<text>{{msg}}</text>
7.2 子传父

7.2.1 在组件的.js文件中,Component构造函数配置项的methos属性中,定义事件并使用this.triggerEvent('自定义事件名', 值)
7.2.2 在页面中,使用bind:自定义事件名="事件处理函数"接收事件和参数
7.2.3 在页面的.js文件中,使用事件处理函数将传过来的值从事件对象中提取出来

使用npm安装vant-weapp

1.打开vant-weapp官网 Vant Weapp - 轻量、可靠的小程序 UI 组件库 (gitee.io)
2.按照官网要求安装npm包
3.在根目录新建miniprogram文件夹,操作完后根目录如下

image.png
4.重构项目结构,将所有项目相关的文件放到miniprogram文件夹里

image.png
5.这时你会发现项目炸了,需要在project.config.json中配置

{
    setting:{
        "packNpmManually": true,
        "packNpmRelationList": [
          {
            "miniprogramNpmDistDir": "miniprogram",
            "packageJsonPath": "./package"
          }
        ],
    },
    "miniprogramRoot": "miniprogram",
}

配置完后保存,你会发现"miniprogramRoot": "miniprogram"后面多了一个斜杠,这是正常的,现在页面会正常显示了

image.png

跳转携带参数

在navigator标签的url属性中加上query参数

wx.redirectTo({
          url: '/pages/login/index?redirectURL=/' + route,
        })

易错:不要在字符串里乱加空格!

image.png
这样写最终导致页面不显示,且log id 正常,查看network发现url参数为%20x,因为空格就是%20

在目标的.js文件的 onLoad 钩子中获取携带的参数

onLoad({ redirectURL }) {
    //将获取的参数挂载起来
    this.redirectURL = redirectURL
  }

怎么实现共享数据

  1. 写在app.js中app({})中的数据就是全局的

    App({
        message: 'nihao'
    })
    

    image.png

  2. 使用全局的API: getApp() 获得app的配置对象

const app = getApp()    //这里app存储的就是app的配置对象
console.log(app)

image.png

获取当前页面的信息对象

使用getCurrentPages()获取页面栈

const pages = getCurrentPages()

pages是一个数组,存有所有的浏览过的页面信息对象,当前页面信息默认在数组的最后一个元素 可以通过页面信息对象修改它的数据,使用pages[x].setData({})

如何封装一个鉴权组件

写一个插槽,插槽要有wx:if属性,判断token是否存在,存在就显示,不存在就跳转至登录页,使用就是将整个页面用鉴权组件包起来

如何实现强制登录后的回跳?

  1. 在鉴权插件中,利用getCurrentPages获取当前页面信息对象,并获取该对象的route属性
  2. 在跳转时,路径携带参数,将route的值传过去
Component({
  data: {
    isLogin: false
  },
  lifetimes: {
    attached() {
      const app = getApp()
      const isLogin = !!app.getToken()
      this.setData({
        isLogin,
      })
      if (!isLogin) {
        console.log(1);
        const pages = getCurrentPages()
        const lastPage = pages[pages.length - 1]
        wx.redirectTo({
          url: '/pages/login/index?redirectURL=/' + lastPage.route,
        })
      }
    }
  }
})

3. 在onLoad钩子函数中获取路径中的参数,并保存到Page对象上

onLoad({ redirectURL }) {
    this.redirectURL = redirectURL
}

4. 在登陆后,根据保存的参数进行跳转,没有则跳转到首页

wx.redirectTo({
    url: this.redirectURL || '/pages/index/index'
})

wechat的常用插件

  1. wechat-http 封装的发请求组件库 www.npmjs.com/package/wec…
  2. wechat-validate 封装的表单校验组件库 www.npmjs.com/package/wec…
  3. vant-weapp vant组件库 Vant Weapp - 轻量、可靠的小程序 UI 组件库 (gitee.io)

小知识点: <button>可以设置 open-type="chooseAvatar"来让它被点击时自动弹出头像选择框 <van-field>可以设置type="nickname"来让他被点击时自动弹出昵称选择框