微信小程序

一. 目录结构&&配置文件说明

  1. app.json:当前小程序所有的配置(必须的)

    1. window:当前小程序顶部title配置(全局)
      1
      2
      3
      4
      5
      6
      7
      8
      "window": {
      "backgroundColor": "#666", // 下来后显示背景色
      "enablePullDownRefresh": true, // 是否显示下拉后面的背景色
      "backgroundTextStyle": "light", // 下来后显示的 ···
      "navigationBarBackgroundColor": "#ff5777",
      "navigationBarTitleText": "小程序",
      "navigationBarTextStyle": "white"
      },
  2. app.js:小程序逻辑(全局)(必须的)

  3. app.wxss:全局样式文件
  4. pages:小程序所有的页面结构目录 每个页面又由以下四个文件组成
    1. js :
    2. wxml :
    3. json :当前页面的配置(列入窗口)
    4. wxss :
  5. project.config.json: 工具配置(跟换电脑,对该项目不许要在重新配置)
  6. WXML == HTML WXSS == CSS 他们在 渲染层工作

二. 常用组件的说明

  1. view == div
  2. text == span
  3. block == 一般配合wx:if wx:elif ex:else wx:for使用 将代码打包成块
    block 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

三. 小程序常用的事件

  1. 冒泡事件
  2. 非冒泡事件
  3. 事件类型有哪些
    1. tap:触摸马上离开(点击事件)
    2. longpress:长按 不会触发元素自身定义过的tap事件
    3. longtap:长按 会触发元素自身定义过的tap事件
  4. 注意:
    • 冒泡事件用bind开头
    • 非冒泡事件用catch
    • 后面都跟事件类型
    • 事件第一个参数默认返回event对象
      • target: 当前点击元素
      • currtarget:当前触发事件的元素

四. 路由跳转

  1. wx.navigateTo: // 路由跳转到/page/index/index

    1
    wx.navigateTo({ url: '/page/index/index'})
  2. wx.redirectTo://关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面

    1
    wx.redirectTo({ url: "/page/index/index"})
  3. wx.switchTab:// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

    1
    wx.switchTab({  url: "/page/index/index" })
  4. wx.navigateBack://关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层

    1
    wx.navigateBack({delta:1})// delta大于页面栈 将返回到首页
  5. navigator

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!-- // 有历史 无法调换navbar页面 -->
    <navigator url="/pages/details/details">跳转到我的页面</navigator>
    <!-- // 替换页面 没有历史记录 -->
    <navigator url="/pages/details/details" open-type="redirect"> 替换跳转</navigator>
    <!-- // 替换页面 跳转navbar页面 -->
    <navigator url="/pages/details/details" open-type="switchTab"></navigator>
    <!-- 跳转到新的页面 清楚所有页面历史记录 -->
    <navigator url="/pages/details/details" open-type="reLaunch"></navigator>
    <!-- 返回上一个页面 data:指定返回历史中前几个页面-->
    <navigator url="/pages/details/details" open-type="navigateBack" data="2"></navigator>

五. 小程序常用的API

  1. wx.getSetting:获取用户是否授权了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    wx.getSetting({
    withSubscriptions: true, // 是否同时获取用户订阅消息的订阅状态
    success (res) {
    console.log(res.authSetting)// 用户授权信息
    // res.authSetting = {
    // "scope.userInfo": true,
    // "scope.userLocation": true
    // }
    console.log(res.subscriptionsSetting)// 用户订阅信息
    // res.subscriptionsSetting = {
    // mainSwitch: true, // 订阅消息总开关
    // itemSettings: { // 每一项开关
    // SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戏系统订阅消息
    // SYS_MSG_TYPE_RANK: 'accept'
    // zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性订阅消息
    // ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
    // }
    // }
    }
    })
  2. wx.getUserInfo 获取用户授权后的 用户信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    wx.getUserInfo({
    success: (res) => {
    this.setData({
    userInfo:{
    avatarUrl:res.userInfo.avatarUrl,// 头像
    nickName:res.userInfo.nickName // 用户名
    }
    })
    },
    })
  3. 获取用户地理位置

    1
    2
    3
    4
    5
    6
    7
    wx.getLocation({
    type: 'wgs84',
    success: (res) => {
    var latitude = res.latitude // 纬度
    var longitude = res.longitude // 经度
    }
    })
  4. 调起微信扫一扫

    1
    2
    3
    4
    5
    wx.scanCode({
    success: (res) => {
    console.log(res)
    }
    })
  5. wx.showToast: 掉起message提示

    1
    2
    3
    4
    5
    wx.showToast({
    title: '页面出错了', icon:"none",mask:true,// 是否显示透明蒙层,防止触摸穿透
    image:"url", duration:"time",// 提示的时间、
    success:()=>{}// 成功的函数
    })
  6. wx.showModal:掉起模态框

    1
    2
    3
    4
    5
    6
    7
    wx.showModal({
    title:"提示框", content:"提示内容",
    showCancel:true, // 是否显示取消按钮
    cancelText:"string",confirmText:"string" // 取消/确认按钮的文字
    cancelColor:'string', // 颜色
    success:fn // 成功的回调
    })
  7. wx.chooseAddress: 获取用户收获地址

    1
    2
    3
    4
    5
    wx.chooseAddress({
    success(res){

    }
    })
  8. wx.showLoading:加载框

    1
    2
    3
    4
    wx.showLoading({
    title:'加载'
    mask:true // 遮罩层 防止点击穿透
    })
  9. wx.showActionSheet:底部弹出选择项

    1
    2
    3
    4
    5
    wx.showActionSheet({
    itemList:['相册',"拍照"], // 选择项
    itemColor:"red", // 文字的颜色
    success:fn
    })

六. 小程序底部tabbar的配置:至少2个 最多5个

1
2
3
4
5
6
7
8
9
10
11
// app.json
"tabBar": {
"selectedColor":"green", // 选中的当前bar后文字显示的颜色
"list": [
{
"pagePath": "pages/index/index", // 跳转的路由
"text": "Home", // 每个item显示的文字
"iconPath": "./images/tabbar/home.png", // 没有选中的时候展示的图片效果
"selectedIconPath": "./images/tabbar/home1.png"// 选中当前bar展示的效果
},
}
坑:首页要设置路由中 且tabBar中要含有首页

七. 生命周期

  1. onLoad:监听页面加载 // 页面加载 请求数据

    1
    2
    onLoad: function (options) { // options 上一个页面 传递的路由参数
    },
  2. onReady: 监听页面初次渲染完成 //

    1
    onReady: function () { },
  3. onShow: 监听页面显示 // 每次显示页面 就会执行

    1
    onShow: function () { },
  4. onHide: 监听页面隐藏// 每次关闭页面 就会执行

    1
    onUnload: function () { },
  5. onPullDownRefresh: 监听用户下拉动作

    1
    onPullDownRefresh: function () { },
  6. onReachBottom:页面上拉触底事件的处理函数

    1
    onReachBottom: function () { },
  7. onShareAppMessage: 用户点击右上角分享 // 如果没有写这个 那么页面就无法分分享

    1
    2
    3
    4
    5
    6
    7
    8
    9
    onShareAppMessage: function (options) {
    return {
    title:"自定义标题",
    path:"/pages/kms/kms",
    imageUrl:"../../images/kms/1.jpg"
    }
    }
    // 页面功能调起分享
    <button open-type="share">分享</button>

八. 自定义组件

  1. 组件的自定义

    • 在项目目录下创建components 文件夹
    • 在components目录下创建组件文件夹(lesson)
    • 在lesson文件夹下创建组件模板(使用 新建Component)
    • 在要使用的页面的json文件中引入

      1
      2
      3
      4
      "usingComponents": {
      // 组件名 组件的路径
      "lesson-cmp":"../../components/lesson/index"
      },
    • 在wxml中使用

      1
      <lesson-cmp></lesson-cmp>
  2. 父组件向子组件传值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 父组件使用components组件    并传值
    <lesson-cmp info="{{info}}" ></lesson-cmp>
    // componets 组件接收
    properties: {
    info:{
    type:Object,
    value:{name:''},
    observer:function (newValue,oldValue){
    // newValue,oldValue 新值 旧值
    }
    }
    },
  3. 子组件给父组件传递消息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // components。wxml
    <view bindtap="onTab">{{info.name}}</view>
    // components
    methods: {
    onTab(){
    var myEventDetail = {} // detail对象,提供给事件监听函数 //参数 在event.detail
    var myEventOption = {} // 触发事件的选项
    this.triggerEvent("myEvent",myEventDetail, myEventOption)
    }
    }

    // 父组件中
    <lesson-cmp info="{{info}}" bind:myEvent="onMyEvent"></lesson-cmp>
    onMyEvent(a){
    console.log(a);
    console.log("子组件发消息来了");
    },
  4. 父组件给组件传递样式

    1
    2
    3
    4
    5
    6
    // 父组件使用components组件    并传值
    <lesson-cmp info="{{info}}" titleClass=".class样式"></lesson-cmp>
    // 子组件 并传值
    <view bindtap="onTab" class="titleClass">{{info.name}}</view>
    // 给组件传递class样式
    externalClasses:['titleClass']
  5. 获取组件对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    const component = this.selectComponent("class/id")
    component.setData({ // 对组件的的值进行修改 不推荐
    counter:20
    })
    // 推荐写法
    // 通过调用子组件methods中的的方法修改子组件
    component.changeComponentData(value)
    //子组件
    methods:{
    changeComponentData(value){
    this.setData({
    value:value
    })
    }
    }
  6. 组件的插槽slot

    1. 创建一个带有slot的组件

      1
      2
      3
      <view>头部</view>
      <slot></slot>
      <view>尾部</view>
    2. 使用

      1
      2
      3
      <my-slot>
      <view>我是中间</view>
      </my-slot>
    3. 具名插槽

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      // component.wxml
      <view>
      <slot name="one"></slot>
      <slot name="two"></slot>
      <slot name="three"></slot>
      </view>
      // component.js
      Component({
      options:{
      multipleSlots: true, // 开启多插槽模式
      },
      })
      // page.wxml slot与组件的slot name值一样 先后顺序由组件插槽定义的位置决定
      <my-slot>
      <button slot="one">one</button>
      <button slot="two">two</button>
      <button slot="three">three</button>
      </my-slot>
    4. Component可以创建哪些东西

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      // components/my-slot/my-slot.js
      Component({
      // 定义组件的配置选项
      options:{
      multipleSlots: true, // 允许使用多插槽
      styleIsolation:'' // 样式的隔离方式
      },
      // 外界传入组件的样式
      externalClasses:[],
      // 让使用者可以传递组件数据
      properties: {},
      // 组件内部初始化数据
      data: {},
      // 组件data的监听器
      observers:{
      // 只有最新的value
      counter(newValue){}
      },
      // 定义组件内部的函数的
      methods: {},
      // 组件中的生命周期函数
      // 1. 监听所在页面的生命周期
      pageLifetimes:{
      show(){},// 监听组件所在页面显示出来时
      hide(){},// 监听组件所在页面隐藏时
      resize(){}// // 监听组件所在页面尺寸发生改变
      },
      // 2. 监听组件本身的生命周期
      lifetimes:{
      created(){},// 组件被创建出来
      attached(){},// 组件被添加到页面
      ready(){}, // 组件被渲染出来
      moved(){}, // 组件被移动到另外一个节点
      detached(){}// 组件被移除掉
      }
      })
  7. 注意:

    • 组件的样式不会与page样式冲突
    • 组件的选择器不能用id 标签 选择器 属性选择器
    • 若想class 相互影响 可以使用 options:{styleIsolation:”apply-shared”}// 外部可以影响组件 组件不影响页面
    • 若想class 相互影响 可以使用 options:{styleIsolation:”shared”}// 相互影响

      九. template的使用

  8. 定义一个模板

    1
    2
    3
    4
    5
    6
    <template name="item">
    <button>{{btnText}}</button>
    <view>{{contentText}}</view>
    </template>

    <template is="item" date="{{btnText:'点击',contentText:'内容'}}"></template>
  9. 可使用import 引入

    1
    2
    3
    4
    // 导入
    <import src="模板文件路径" />
    // 使用
    <template is="abc"></template>
  10. 模板禁止套娃(模板套模板 一次导出)

    十. include的使用

  11. 用户复用代码 写死的代码 只能是wxml 可以递归导入(套娃)
  12. 使用
    1
    <include src="文件路径"></include>

十一. WXS

  1. 微信WXML中无法使用变量,字符串,数字等直接调用js方法 或wxjs中的方法 (类似Vue的过滤器)
  2. 只能使用es5的方法 es6的写法会报错
  3. 使用(在wxml中使用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <wxs module="demo">
    // 定义内容 并导出
    var message = "hello world";
    var sum = function (num1,num2){
    return num1+num2
    }

    module.exports = {
    message:message,
    sum:sum
    }
    </wxs>
    // 引入夹module名字 且wxs要导出
    <view>{{demo.message}}</view>
    <view>{{demo.sum(20,30)}}</view>
  4. 单独文件定义 使用导入的方式引进

    1
    2
    只能使用相对路径引用  绝对路径不可以
    <wxs src="../../wxs/demo.wxs" module="demo"></wxs>

十二. 其他

  1. 动态绑定一个class
    1
    2
    3
    <block wx:for="{{list}}" wx:key="index">
    <text bindtap="hanBar"class="{{active===index?'active':''}}" >{{item}}</text>
    </block>

  1. 小程序上面添加自定义属性data 会自动转化成小写 第三个会大写 data-Url-url === data-url-Rul
  2. web-view加载白屏的时候 退出开发者工具,重新打开就好了