小程序-WX

149 阅读8分钟

微信小程序

1.文件结构与配置

1.1页面结构

  1. wxml :结构,写标签代码
  2. wxss: 样式
  3. JS:ES 💥 没有DOM、BOM
  4. json: 配置

1.2最精简的结构

  1. appjs: 全删
  2. app.json:pages字段必须有;pages数组中,至少有一个页面
  3. pages/index:.json 保留json的{} ;.js 保留Page({})入口函数 ;wxml 全删 ;wxss 全删

1.3全局/页面配置

  1. app.json文件中 ,更多配置参考

    ,💥默认情况下json文件不允许有注释,以下注释为笔记用

    {
      // pages 每个页面都要在此注册,默认情况下数组的第一个页面就是默认启动页,当配置的页面不存在相应文件时会自动创建
      "pages": ["pages/lifeCycle/index","pages/test/test"],
      "window": {
        "navigationBarBackgroundColor": "#ff7043", //页面头部背景颜色
        "navigationBarTitleText": "测试页面标题", //页面头部标题
        "navigationBarTextStyle": "white", //头部标题文字颜色 black/white
        "navigationStyle": "default", //头部导航栏的 显示与隐藏 :default / custom
        "enablePullDownRefresh": true, //是否允许下拉刷新
        "backgroundColor": "#00b26a" //下拉刷新的背景色
      },
     // 底部 tabBar导航栏配置
      "tabBar": {
          //所有tabBar的页面都要在list中注册,且tabBar页面数量为 2~5 个
        "list": [
            {
            "pagePath": "pages/testone/index", //页面路径
            "text": "启动页", //栏目名
            "iconPath": "assets/icons/category.png", //栏目未被选中时的icon图标
            "selectedIconPath": "assets/icons/category-o.png"  //栏目被选中时的icon图标
          },
          {
            "pagePath": "pages/index/index",
            "text": "首页",
            "iconPath": "assets/icons/home.png",
            "selectedIconPath": "assets/icons/home-o.png"
          }
          
        ],
        "color": "#1d82fe", //栏目未被选中时的字体颜色
        "selectedColor": "#ff7043" //栏目被选中时的字体颜色
      }
    }
    
  2. 页面.json文件中,可以配置一些app.json中window内的部分属性(直接配置,不用写window),不能配置tabBar,对当前页面而言,页面配置的代码优先级会高于全局配置

    {
      "navigationBarBackgroundColor": "#636aeb",
      "enablePullDownRefresh": true,
      "backgroundColor": "#636aeb",
      "navigationBarTitleText": "单页面配置",
      "navigationBarTextStyle": "black"
    }
    

2.模板语法

2.1插值表达式

  1. 变量声明在对应的页面.js文件中

    Page({
      data: {
        dataList: ["阿尼亚", "黄昏", "约尔", "次子"],
        inpValue: "",
      },
      addFn() {
        // this.setData() 才能更新视图
        //可同时更新多个变量
        this.data.dataList.push(this.data.inpValue);
        this.setData({dataList:this.data.dataList,inpValue:''})
      }
      },
    });
    
  2. 页面.wxml中使用,

    <!-- 在属性中,当值为布尔型,数字,变量时,都要使用 {{}} 否则会被编译成字符串 -->
    <view class="content">
      <input bindinput="changeFn" value="{{inpValue}}" type="text" placeholder="请输入添加词" style="border: 2px solid orange;" />
      <button bindtap="addFn">点击添加</button>
    </view>
    

2.2wx:if和hidden

  1. wx:if与v-if类似,条件为真才会创建渲染标签,通过创建与销毁标签来控制标签的显示隐藏

    <!-- wx:if wx:elif wx:else => 类同 if elseif else 的逻辑线-->
    <view wx:if="{{true}}">标签未创建</view>
    
  2. hidden与v-show类似,不同点在于控制条件为真时,hidden会隐藏标签,原理是通过控制标签的CSS属性=>display:none控制标签的显示隐藏

    <view hidden="{{true}}">标签隐藏</view>
    

2.3wx:for

  1. wx:for与v-for类似,都是用于标签的循环渲染

  2. wx:for依赖的数据变量定义在页面.js文件中,数据变量可以是数组/对象/字符串

  3. 使用wx:for循环渲染的同时也要有wx:key ,目的也是按需更新

  • 数据变量为简单数组或字符串时,一般 wx:key=" *this ",*this代指数组的每项元素
  • 数组变量为对象数组时, wx:key ="对象中值唯一且不重复的键名",如: [{id:1,name:'张三'},{id:2,name:'李四'}] ,使用该数据渲染时,wx:key="id" ,💥不要用{{}}包裹键名
<!-- item和index为小程序默认的 每项元素 和 下标 的变量名 -->
<!-- 当要修改 每项元素 和 下标 的默认变量名,可通过 wx:for-item="value" wx:for-index="curIndex" 的模式修改变量名-->
<view wx:for="{{list}}" wx:key="*this">{{item}}=>{{index}}</view>

2.4事件绑定

  1. 语法:bind+事件名,如 bindtap(点击事件) / bindblur(失焦事件)等

  2. 事件绑定在标签上,事件函数声明在页面.js文件中,与data同级,不用写在methods内

  3. 必须通过标签的自定义属性传参, tapFn(100) 此种写法编译时,小程序会判定tapFn(100)为函数名,而非tapFn()为函数名,自定义属性传递的参数可通过事件对象在函数中获取:event.target.dataset.自定义属性名

  4. 演示如下

    <view bindtap="tapFn" data-index="1"></view>
    
    Page({
        data:{},
        clickFn(event){
            //event.target.dataset.index 获取传递的参数
           console.log(event.target.dataset.index)
        }
    })
    

2.5关于CSS样式的说明

  1. 小程序的CSS写法与原生CSS用法几乎一致,但以下两点须知:
    • 小程序不支持通配符* ,因为小程序底层已对标签进行了样式默认值处理,如仍有标签样式要重置,可用并集选择器处理
    • 新增相对单位rpx,视口宽度=750rpx=100vw,

3.小程序的标签

3.1view 和 text

  1. view类似div标签,块级元素

  2. text类似span标签,行内元素,具有以下特点:

    • text标签提供user-select属性,允许用户长按选中复制文本
    • text只能嵌套text
    <view>块级元素</view>
    <text user-select>文本可被选中</text>
    

3.2image

  1. 类似img标签,用于显示图片,盒子具有默认宽高,320rpx*240rpx

  2. src属性,支持绝对路径和在线链接

  3. mode属性,用于设置图片的显示模式,常用如下:

    • 默认值,用于缩略图,占满整个容器,图片可能变形
    • aspectFit,等比例缩放,直到宽或高触碰到盒子边界,不会截断图片,可能有留白
    • widthFix,需指定宽度,高度自适应
    • heightFix,需指定高度,宽度自适应
  4. lazy-load属性,长列表下图片的懒加载,以便提高加载速度

    <image style="width: 750rpx;" mode="widthFix" src="{{image_src}}"></image>
    

3.3swiper轮播图

  1. swiper只能放置, swiper-item组件

  2. 默认有高度,往往需要调整高度

  3. 默认滚动间隔为5秒,通常需要调整

    <swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
      <swiper-item>
       <view class="swiper-item {{item}}"></view>
      </swiper-item>
    </swiper>
    

3.4navigator

  1. 作用:跳转到小程序内部的页面和其它小程序中

  2. url跳转注意点

    1. 以 / 开头
    2. 没有文件后缀
    3. 只有在pages中指定过路径列表的才能跳转
    4. 默认不能调到tabBar的list列表中
  3. 跳转模式open-type

    • switchTab :可以允许跳转到tab页面,会清除掉历史记录,没有回退按钮
    • redirect:不产生一条跳转的历史记录
    • navigatorBack:回退一步,通常配置自定义导航栏、自定返回按钮,不需要写url,无效
    • reLaunch:会清除掉所有的历史记录,重新打开某个页面,不常用, 小程序希望尽量缓存页面
  4. url也可以传递参数,在跳转后的页面的onLoad函数的形参option中接收传递的参数

    <view class="btn-area">
      <navigator url="/page/navigate/navigate?title=navigate">跳转到新页面</navigator>
      <navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect">在当前页打开</navigator>
      <navigator url="/page/index/index" open-type="switchTab">切换 Tab</navigator>
      <navigator target="miniProgram" open-type="navigate" app-id="" path="" extra-data="" version="release">打开绑定的小程序</navigator>
    </view>
    

3.5button

  1. open-type属性

    • share 分享小程序
    • feedback 反馈 💥慎用,用户投诉可能导致小程序被封禁
    • contact 联系客服
    • openSetting 打开设置=>向用户申请过的权限才能再次打开、关闭
    • getPhoneNumber 获取手机号码
    <button open-type="share" class="mini-btn" type="primary" size="mini">按钮</button>
    

3.6rich-text

  1. nodes属性绑定要解析的html字符串

  2. style 和 class 可以控制样式

  3. id 和 标签不能控制样式

    <!-- htmlSnip需在js文件中的data属性中定义 -->
    <rich-text nodes="{{htmlSnip}}"></rich-text>
    

4.自定义组件与组件通信

4.1自定义组件

  1. 创建组件=>文件结构必须有文件名: components/文件夹名/文件名

    <!-- 组件文件名:ShopSubmitBar -->
    <view>子组件的内容</view>
    
  2. 注册组件=> 哪个页面用,哪个页面的json文件: usingComponents: { "组件名": "绝对组件路径" }

{
  "navigationBarTitleText": "商品详情页",
  "enablePullDownRefresh": true,
  "usingComponents": {
    "shop-submit-bar": "/components/ShopSubmitBar/ShopSubmitBar"
  }
}
  1. 使用与注意点=>区分大小写,文件夹名称、文件名称、 组件注册名称保持一致
<!-- 商品详情页页面文件中使用自定义组件 -->
<view>
    <shop-submit-bar></shop-submit-bar>
</view>

4.2组件通信

4.2.1父传子

  1. 父组件-传 => 组件标签上,写:属性=“值”,值变量定义在父组件.js文件中

    <shop-submit-bar goodsText="{{goodsText}}"></shop-submit-bar>
    
  2. 子组件-接 => 语法子组件.js文件中

Component({
  properties: {
    goodsText: {
      type: String,
      value: "默认值",
    },
  }
});

4.2.2子传父

  1. 给子组件绑定一个事件处理函数,并在组件中,定义方法: 在methods中定义

    <view bindtap="handlerClick" class="box">被传递的值是{{title}}</view>
    
  2. 子组件触发自定义事件:this.triggerEvent(“自定义事件名”, 参数)

Component({
  properties: {
    title: {
      type: Object,
      value: "默认值",
    },
  },
  methods: {
    handlerClick() {
      this.triggerEvent("testEvent", this.data.title);
    },
  },
});
  1. 父组件监听自定义事件:bind自定义事件名 = "父组件中的处理函数"

    <MyButton bindtestEvent="handevent" title="被传递的"></MyButton>
    
    
  2. 父组件处理函数中, 获取形参 => 形参.detail

Page({
  handevent(e) {
    console.log(4, e);
    console.log(5, e.detail);
  },
});

5.生命周期函数

5.1应用级别

  1. 写在app.js文件中

  2. 函数分类

    App({
      // 启动小程序,全局执行一次 获取初始数据, 如获取地理位置
      onLaunch (e) {
          // console.log(e);
      },
        
      // 小程序从后台切到前台会触发,启动时也会触发一次 收集一些需要统计的数据, 比如: 使用时长、时间段
      onShow() {
        // console.log("切到前台了");
      },
        
      // 小程序从前台切到后台会触发,
      onHide() {
        // console.log("切到后台了");
      },
        
      //任何一处代码,有错误时自动触发,配合后台接口,上报异常(埋点)
      onError(e) {},
        
      //切换日间、黑夜模式时;跟随系统,切换样式
      onThemege(){}
    });
    

5.2页面级别

  1. 写在对应的页面.js

  2. 函数分类

    // pages/testIndex.js
    Page({
      //生命周期函数--监听页面加载 形参options可以接收页面跳转过来时候的url上的参数
      //发送请求获取数据
      onLoad(options) {},
        
      // 生命周期函数--监听页面初次渲染完成 开启定时器、 获取标签等
      onReady() {},
        
      // 生命周期函数--监听页面显示
      onShow() {},
        
      //生命周期函数--监听页面隐藏 收集用于统计的数据, 💥某个页面的统计数据,可能要重新获取最新数据, 💥如购物车
      onHide() {},
    
      // 生命周期函数--监听页面卸载 做清除的动作,如清除定时器、缓存等
      onUnload() {},
        
      //页面相关事件处理函数--监听用户下拉动作
      onPullDownRefresh() {},
        
      //切换横竖屏幕时 响应对应UI尺寸
      onResize(){},
    
      //页面上拉触底事件的处理函数 上拉请求下一页数据
      onReachBottom() {},
        
      // 用户点击右上角分享
      onShareAppMessage() {},
        
      //用户转发朋友圈
      onShareTimeline(){},
        
      //用户收藏时
      onAddToFavorites(){}
    })
    

5.3组件级别

  1. 写在组件.js

  2. 函数分类

    Component({
      //组件挂载时  发请求、开定时器
      attached(){},
    
      //组件卸载时 清除的动作、如清除定时器、缓存等
      detached(){},
        
      //别的方法函数
      methods: {}
    })