美文网首页
小程序指南

小程序指南

作者: A郑家庆 | 来源:发表于2020-05-08 20:25 被阅读0次

    小程序代码构成

    JSON配置

    JSON是一种数据格式,并不是编程语言,在小程序中,JSON扮演的是静态配置的角色.

    小程序配置app.json

    app.json是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部tab等.
    1.pages---用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录,文件名后面不需要写文件后缀.
    2.window---用于设置小程序的状态栏、导航条、标题、窗口背景色.
    3.tabBar---指定tab栏的表现,以及tab切换时显示的对应页面.
    4.networkTimeout---各类网络请求的超时时间,单位均为毫秒.
    5.debug---可以在控制台看到打印的日志
    6.usingComponents---在此处声明的自定义组件视为全局自定义组件,在小程序内的页面或自定义组件中可以直接使用而无需再声明.
    7.sitemapLocation---用来指明sitemap.json的位置;默认为sitmap.json即在app.json同级目录下名字的sitemap.json文件,sitemap.json文件用于配置小程序及其页面是否允许被微信索引.

    配置文档:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html

    页面路由

    在小程序中所有页面的路由全部由框架进行管理.框架以栈的形式维护了当前的所有页面.栈主要是用来控制点击小程序左上角回退按钮时回退顺序,通过不断入栈、出栈来控制回退页面的顺序.

    路由方式 页面栈表现
    初始化 新页面入栈
    打开新页面(navigateTo) 新页面入栈
    页面重定向(redirectTo) 当前页面出栈,新页面入栈
    页面返回(navigateBack) 页面不断出栈,直到目标返回页
    Tab切换(switchTab) 页面全部出栈,只留下新的Tab页面
    重加载(reLaunch) 页面全部出栈,只留下新的页面

    开发者可以使用getCurrentPages()函数获取当前页面栈.

    注意:

    • navigateTo、redirectTo只能打开非tabBar页面
    • switchTab只能打开tabBar页面
    • reLaunch可以打开任意页面
    • 页面底部的tabBar由页面决定,即只要是定义为tabBar页面,底部都由tabBar
    • 调用页面路由带的参数可以在目标页面的onLoad中获取

    reLaunch和switchTab用途有点类似,只是reLaunch先关闭了内存中所有保留的页面,再跳转到目标页面,switchTab是先关闭所有非tabBar页面,再跳转到tabBar页面,用switchTab如果从tabBar页面1跳转到tabBar页面2,返回的时候就会返回1,但是用reLaunch就会跳出小程序

    小程序页面栈详解

    页面栈主要是用来控制返回页面的顺序.

    什么是页面栈

    一个小程序存在多个界面,所以渲染层存在多个WebView线程,一个WebView就是一个页面栈,页面栈保存对应页面的所有信息,最多不超过10条页面栈.当路由发生变化时页面栈也会做出对应的变化.

    路由跳转的使用场景

    参考文章:https://juejin.im/post/5d47d7326fb9a06af2385b00
    总结:小程序的路由跳转有navigateTo、redirectTo、reLaunch、switchTab这4种前进方式,返回有navigateBack这一种方式,返回的页面顺序是由页面栈决定的,前进的4种方式就是修改页面栈

    WXML语法参考

    数据绑定

    // 内容
    <view> {{ message }} </view>
    // 组件属性
    <view id="item-{{id}}"> </view>
    // 控制属性
    <view wx:if="{{condition}}"> </view>
    // 关键字
    <checkbox checked="{{false}}"> </checkbox>
    // 三元运算
    <view hidden="{{flag ? true : false}}"> Hidden </view>
    // 算数运算
    <view> {{a + b}} + {{c}} + d </view>
    // 逻辑判断
    <view wx:if="{{length > 5}}"> </view>
    // 字符串运算
    <view>{{"hello" + name}}</view>
    // 数据路径运算
    <view>{{object.key}} {{array[0]}}</view>
    // 数组
    <view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
    // 对象
    <template is="objectCombine" data="{{for: a, bar: b}}"></template>
    // 扩展运算符
    <template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
    

    写template模版、component组件是传值,传的是一个对象,其他的是取值,两者是不一样的

    列表渲染

    <view :wx:for="{{array}}" wx:key="index">
      {{index}} : {{item.message}}
    </view>
    

    array可以是数组也可以是字符串,默认数据的当前项下标变量名默认为index,数组当前项的变量名默认为item,列表渲染一般都需要添加wx:key

    <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
      {{idx}} : {{itemName.message}}
    </view>
    

    使用wx:for-item可以指定数组当前元素的变量名
    使用wx:for-index可以指定数组当前下标的变量名

    <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
      <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
        <view wx:if="{{i <= j}}">
          {{i}} * {{j}} = {{i * j}}
        </view>
      </view>
    </view>
    <block wx:for="{{[1, 2, 3]}}">
      <view> {{index}}: </view>
      <view> {{item}} </view>
    </block>
    

    wx:for也可以嵌套使用,也可以包裹在block标签中,以渲染一个包含多节点的结构块,block并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性,例如wx:if、wx:for

    条件渲染

    wx:if和v-if功能是一样的,hidden和v-show功能是一样的

    template模版

    小程序中组件化的实现有两种方式:template模版和component组件.这两种放别适用不同的场景.
    1.template模版主要用于展示,模版中不涉及事件处理,需要处理的事件逻辑放在调用模版的页面中.一个template模版只包含wxml.wxss文件.
    2.component组件作为一个单独的功能模块,不仅可以包含页面展示还可以包含该模块的事件逻辑处理,像一个单独的页面,component组件可以包含wxml、wxss、js、json文件.

    template模版语法

    一个template.wxml文件中适用<template>标签包含一个模版,一个template.wxml文件可以包含多个<template>模版,使用name属性作为模版的名称.
    在模版中可以接受变量,使用{{}}展示,为变量的传递者由调用该模版的页面传递.

    // index.wxml
    <import src="./template.wxml">
    <view>
       <template is="A" data="{{name}}">
       <template is="B" data="{{name, msg}}">
    </view>
    // 或者
    <view>
       <template is="A" data="{{name, msg}}">
    </view>
    
    // index.wxss
    @import "./template.wxss"
    

    tempalte模版的引用需要使用<import>标签,该标签的src属性为引入模版的路径.import引用作用域是有限制的,引用页面只能使用被引用页面的模板,不能使用被引用页面中引用其它页面模板的模板
    is属性用来区别模版文件中定义的模版名称,data是传入模版中的数据.
    模版的样式需要在调用页面的wxss中单独引用template.wxss文件.

    // template.wxml
    <template name="A">
      <text>template name: {{name}}</text>
    </template>
    <template name="B">
      <text>template name: {{name}} {{msg}}</text>
    </template>
    // 或者
    <template name="A">
      <template is="B" data="{{name, msg}}"></template>
    </template>
    

    我们可以看到模版中还可以嵌套模版,而且是可以多层嵌套.

    模版中的事件处理

    在模版中定义的事件,需要调用页面中执行

    // template.wxml
    <template name="A">
      <text bindtap="handleTap">{{name}}</text>
    </template>
    
    // index.js
    Page({
      data: {},
      handleTap () {
        console.log('点击')
      }
    })
    
    include

    include可以将目标文件除了<template/><wxs/>外的整个代码引入,相当于是拷贝到include位置,如:

    <!-- index.wxml -->
    <include src="header.wxml"/>
    <view> body </view>
    <include src="footer.wxml"/>
    
    <!-- header.wxml -->
    <view> header </view>
    
    <!-- footer.wxml -->
    <view> footer </view>
    
    template和include区别

    小程序中有两种引用方式一种是直接引用include,通过它相当于把<templete/>标注的以外的代码全部copy过来当前位置,而import则是相反,它是只引用模板
    最后总结就是import可以用来引用模板,在开发中可以避免相同模板的重复编写,而include适合引入组件文件
    参考文章:https://blog.csdn.net/sinat_39343982/article/details/74095205
    参考文章:https://www.jianshu.com/p/ead124a6b7cf

    WXSS

    WXSS具有CSS大部分特性.同时为了更适合开发微信小程序,WXSS对CSS进行了扩充以及修改.与CSS相比,WXSS扩展的特性有:

    尺寸单位(rpx)

    rpx可以根据屏幕宽度进行自适应,规定屏幕宽度为750rpx,比如在iphone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素,所以开发小程序都以iphone6作为标准

    样式导入

    WXS

    WXS是小程序的一套脚本语言,结合WXML可以构建出页面的结构.
    WXS可以在所有版本的小程序中运行,与JS是不同的语言而且跟JS代码是隔离的,WXS中不能调用其他JS文件中定义的函数,也不能调用小程序提供的API.

    WXS模块

    WXS代码可以编写在wxml文件中的<wxs>标签内,或以.wxs为后缀名的文件内,wxs代码是独立的,与其他代码是隔离的,都有自己独立的作用域,里面定义的变量和函数只能通过module.exports暴露出来
    wxs文件有两个属性module:当前wxs标签的模块名
    src:引用.wxs文件的相对路径

    注意:<wxs> 模块只能在定义模块的 WXML 文件中被访问到。使用 <include> 或 <import> 时,<wxs> 模块不会被引入到对应的 WXML 文件中。
    <template> 标签中,只能使用定义该 <template> 的 WXML 文件中定义的 <wxs> 模块。WXS和JS是不同的语言,它有自己的一套,可以看官网文档,里面的API和JS大部分相同.

    WXS里面的函数接受2个参数,第一个是event,在原有的event的基础上加了event.instance对象,第二个参数是ownerInstance,它们都是ComponentDescriptor对象,具体使用如下:

    • 在组件中绑定和注册事件处理的WXS函数。
    <wxs module="wxs" src="./test.wxs"></wxs>
    <view id="tapTest" data-hi="WeChat" bindtap="{{wxs.tapName}}"> Click me! </view>
    **注:绑定的WXS函数必须用{{}}括起来**
    
    • test.wxs文件实现tapName函数
    function tapName(event, ownerInstance) {
      console.log('tap wechat', JSON.stringify(event))
    }
    module.exports = {
      tapName: tapName
    }
    

    ownerInstance包含了一些方法,可以设置组件的样式和class

    WXS响应事件

    因为小程序是由逻辑层和渲染层构成的,渲染层和逻辑层每次通信都需要通过微信客户端,如果频繁通信就会影响性能开销,所以为了减少通信的次数,让事件在渲染层响应推出了WXS,WXS 函数的除了纯逻辑的运算,还可以通过封装好的ComponentDescriptor 实例来访问以及设置组件的 class 和样式,对于交互动画,设置 style 和 class 足够了。WXS 函数的例子如下:

    var wxsFunction = function(event, ownerInstance) {
        var instance = ownerInstance.selectComponent('.classSelector') // 返回组件的实例
        instance.setStyle({
            "font-size": "14px" // 支持rpx
        })
        instance.getDataset()
        instance.setClass(className)
        // ...
        return false // 不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault
    }
    

    event.instance 来表示触发事件的组件的 ComponentDescriptor 实例。ownerInstance 表示的是触发事件的组件所在的组件的 ComponentDescriptor 实例,如果触发事件的组件是在页面内的,ownerInstance 表示的是页面实例。
    WXS主要用于自定义动画以及频繁、大量的逻辑运算,类似vue中的计算属性,WXS可能不支持es6语法

    事件系统

    target和currentTarget区别

    target:指的是当前点击的组件
    currentTarget:指的是事件捕获的组件

    <view catchTap = "fetchImage">
      <image src="a.png" data-postId = "item.id">
    </view>
    

    上面这段代码,如果点击想获取自定义属性postId的值是这样的:

    fetchImage (e) {
      var  id = e.target.dataset.postId
    }
    

    target指的是image
    currentTarget指的是view
    自定义数据使用data-开头

    mark

    可以使用mark来识别具有触发事件的target节点.此外,mark还可以用于承载一些自定义数据(类似于dataset),当事件触发时,事件冒泡路径上所有的mark会被合并,并返回给事件回调函数.

    <view mark:myMark="last" bindtap="bindViewTap">
      <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button>
    </view>
    

    在上述 WXML 中,如果按钮被点击,将触发 bindViewTap 和 bindButtonTap 两个事件,事件携带的 event.mark 将包含 myMark 和 anotherMark 两项。

    Page({
      bindViewTap: function(e) {
        e.mark.myMark === "last" // true
        e.mark.anotherMark === "leaf" // true
      }
    })
    

    mark 和 dataset 很相似,主要区别在于: mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值。

    简易双向绑定

    在WXML中普通属性的绑定是单向的,如果要实现双向绑定需要添加model:前缀:

    <input model:value="{{value}}">
    

    打括号中只能是一个单一字段的绑定,如:

    <input model:value="值为  {{value}}">
    <input model:value="{{a+b}}">
    <input  model:value="{{a.b}}">
    

    以上都是不支持的.

    在自定义组件中传递双向绑定

    // custom-component.wxml
    <input model:value="{{myValue}}">
    // custom-component.js
    Component({
      properties: {
        myValue: String
      }
    })
    

    这个自定义组件将自身的myValue属性双向绑定到了组件内输入框的value属性上.

    <custom-component model:my-value="{{pageValue}}"></custom-component>
    

    在自定义组件中触发双向绑定更新

    自定义组件还可以自己触发双向绑定更新,做法就是:使用 setData 设置自身的属性。例如:

    // custom-component.wxml
    <view bind:tap="update">更新数据</view>
    // custom-component.js
    Component({
      properties: {
        myValue: String
      },
      methods: {
        update: function() {
          // 更新 myValue
          this.setData({
            myValue: 'leaf'
          })
        }
      }
    })
    

    如果页面这样使用这个组件:

    <custom-component model:my-value="{{pageValue}}" />
    

    获取界面上的节点信息

    WXML节点信息

    // 创建一个查询对象
    const query = wx.createSelectQuery()
    // 选取查询节点,获取它距离显示区域的边界距离
    query.select('#the-id').boundingClientRect(function(res) {
      res.top
      res.left
      ....
    })
    // 选择显示区域,用于获取显示区域的尺寸、滚动位置.滚动位置查询请求 ,节点必// // 须是scroll-view或者viewport
    query.selectViewport().scrollOffset(function (res) {
      res.scrollTop
    })
    // 执行所有请求
    query.exec()
    

    WXML节点布局相交状态

    用于监听两个或多个组件节点在布局位置上的相交状态.这一组API常用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见.
    1.参照节点:监听的参照节点取它的布局区域作为参照区域.
    2.目标节点:监听的目标节点
    3.相交区域:目标节点和参照区域的相交区域
    4.相交比例:相交区域占参考区域的比例
    5.阀值:相交比例如果达到阀值,则会触发监听器的回调函数.
    以下示例代码可以在目标节点(用选择器 .target-class 指定)每次进入或离开页面显示区域时,触发回调函数。

    Page({
      onLoad () {
       // 创建交集观察者,指定页面显示区域作为参照区域,指定目标节点并开始监听相 
       // 交状态变化情况
        wx.createIntersectionObserver().relativeToViewport().observe('.target-class', 
           res => {
               res.intersectionRect // 相交区域
               // ...
           })
      }
    })
    

    相关文章

      网友评论

          本文标题:小程序指南

          本文链接:https://www.haomeiwen.com/subject/knsaghtx.html