小程序基础

小程序前言

想要开发小程序,必须要先注册一个微信小程序,用过的邮箱(比如注册过公众号)就不可以再拿来注册小程序了。

然后需要下载一个微信开发者工具,作为小程序的集成开发环境。

小程序目录结构

小程序基础

配置介绍

  1. 配置介绍
    一个小程序应用程序会包括最基本的两种配置文件。一种是全局的 app.json 和 页面自己的 page.json
    注意:配置文件中不能出现注释

  2. 1.1. 全局配置app.json
    app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。 普通快速启动项目
    里边的 app.json 配置

  {
   "pages":[
   "pages/index/index",
   "pages/logs/logs"
   ],
   "window":{
   "backgroundTextStyle":"light",
   "navigationBarBackgroundColor": "#fff",
   "navigationBarTitleText": "WeChat",
   "navigationBarTextStyle":"black"
   }
  }

字段的含义:

pages 字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。

  1. window 字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等。

  2. 完整的配置信息请参考 app.json配置
    1.2. page.json
    这里的 page.json 其实用来表示页面目录下的 page.json 这类和小程序页面相关的配置。
    开发者可以独立定义每个页面的一些属性,如顶部颜色、是否允许下拉刷新等等。
    页面的配置只能设置 app.json 中部分 window 配置项的内容,页面中配置项会覆盖 app.json 的 window 中相同的配置项。

小程序基础语法

数据绑定:

<view>{{message}}</view>

这里的message需要在js文件里的data里面声明。

Page({

  /**
   * 页面的初始数据
   */
  data: {
      message:1
  },

如果是布尔类型

不可以直接写 checked ="false",他的结果会变成一个字符串,应该像下面一样

<checkbox checked="{{false}}"></checkbox>

运算:

三元运算:

<view hidden="{{flag ? true : false}}" Hidden </view>

算术运算:

<view><{{a + b}}/view> //这才是把a和b相加
<view><{{a}} + {{b}}</view> //这个会是字符串拼接 a的值“+”b的值

逻辑判断:

<view wx:if="{{length > 5}}"></view>

字符串运算

<view>{{"hello" + name}}</view> //name是一个字符串变量

wx:for

<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
array:[{
      message:'foo',
    },{
      message:'bar'
    }]

wx:for

<block wx:for="{{[1,2,3]}}">
  <view>{{index}}:</view>
  <view>{{item}}</view>
</block>

渲染一个包含多节点的结构块,block最终不会变成真正的dom元素。

wx:if

<view wx:if="{{condition}}"> True </view>

hidden:

<view hidden="{{condition}}"> True </view>

类似于 wx:if

频繁切换用 hidden

不常使用 用wx:if

小程序的双线程模型

小程序基础

上图为官方文档给出的双线程模型

小程序的宿主环境

微信客户端 微信客户端提供双线程去执行wxml,wxss,js文件。

双线程模型

1.上述的 渲染层 上面运行这wxml文件已经wxss文件,渲染层使用是的webview线程进行渲染(一个程序会有多个页面,也就会有多
个view线程进行运作)

2.js文件是运行在逻辑层,逻辑层的js是通过jscore进行运行的。

通过双线程界面的渲染过程是怎样的?

小程序基础

双线程中的一个线程生成dom,另一个线程生成变量和逻辑等,渲染到dom上。

当数据发生变化的时候

小程序基础

1如果通过setDat把hell改成dsb,则js对象的的节点会发生改变.
2 这时会用diff算法对比两个对象的变化,
3 然后将变化的部分应用到DOM树上
4 从而达到更新页面的目的,这也就是数据驱动的原理

总结

界面渲染的整体流程
1在渲染层将wxml文件与wxss文件转化成js对象也就是虚拟DOM
2 在逻辑成将虚拟的DOM对象配合生成,真实的DOM树,在交给渲染层渲染
3 当数据变化是,逻辑层提供更新数据,js对象发生改变,用diff算法进行比较
4 将更新的内容,反馈到真实的DOM树中,更新页面

小程序的启动流程

小程序基础

在app生命周期中执行了什么??

小程序基础

执行App()函数也就是注册一个APP

  1. 在注册app的时候,可以判断小程序的进入场景
  2. 我们可以在执行通过生命周期函数,做一些数据请求
  3. 可以在app中设置一个全局对象,让所有页面都能够使用

在页面的生命周期中执行了什么

小程序基础

1 在生命周期函数中发送网络请求,从服务端获取数据
2 初始化一些数据,在data里面,以方便wxml引用
3 监听wxml的事件,绑定对应的事件函数
4 还有页面滚动,上拉,下拉等

页面的生命周期

小程序基础

事件

小程序的常见事件

小程序基础

事件捕获与事件冒泡

现在有三个view,嵌套存在。点击最里面的view,就相当于点击了三个。

这时候事件是怎么捕获的?

<view class='container1' id='container' capture-bind:tap='outer_ca' bindtap='onContainerTap'>我是外层
<view class='middle' capture-bind:tap='middle_ca' bindtap='middle'>我是中间
<view class='inner1' id='inner' capture-bind:tap='inner_ca' catch:tap='onInnerTap'>我是内层</view>
</view>
</view>

<view>{{start}}</view>
<button bindtap='jia'>jia</button>

结果是,事件的捕获是从外到内的。

冒泡是从内到外的。

阻止事件捕获

catch阻止事件捕获

只需要把capture-bind改成capture-catch就可以捕获

阻止事件冒泡

只需要把bindtap改成catch:tap就可以阻止了。

自定义组件

自定义组件就像是vue的子组件。

先自己建立一个根文件夹,命名为components,然后在文件夹下建一个自定义组件文件夹,随意命名,在这个文件夹里新建page就可以了,一定要把js文件里的component改成true,这样就表示他是一个自定义组件。

{
  "component": true,
  "usingComponents": {}
}

然后在别的组件中的json文件里这样写

{
  "usingComponents": {
      //t1就代表自定义组件的名字,后面写的是这个自定义组件的决定路径。
    "t1":"/components/t1/t1"
  }
}

完成上面的步骤之后,就可以在别的组件中直接用这个自定义组件了。

<!--t1这个组件的页面中写了什么,这里就会显示什么-->
<t1></t1>

页面像自定义组件传递数据

#页面中,这里把bing赋值给了sb,注意,这里的sb并不是这个页面中声明的变量,而是自定义组建的变量。
<t1 sb="bing"></t1>
properties: {
      sb:{
        //sb这个变量的类型为字符串
        type:String,
        //默认值为tank,当有传递过来的值时,就改变成那个值。
        value:"tank"
      }
  },

组件将事件传给页面

类似于vue的子传父

页面
<!--通过传来的jia点击事件,来触发tt1点击事件-->
<t1 bind:tt1="jia"></t1>
页面中的js

jia:function(e){ 
    console.log(e)
    this.setData({
      num: this.data.num + 1
    })
   
  }

组件中的wxml

<button bind:tap="jia" data-age='11'>jia</button>

组件中的js

jia:function(e){
        console.log(e)
    //triggerEvent,用这个可以传递给页面点击事件,后面的括号是参数。
        this.triggerEvent("tt1",{age:e.currentTarget.dataset.age},{})
      }

wx:request

这个用来和后端服务器做交互

wx.request({
  url: 'www.aaaa.com', // 后端url
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success(res) {
    console.log(res.data)
  }
})

小程序路由跳转

wx.switchTab(Object object)

这里的tabBar是地下的导航栏指定的页面,跳转到tabBar页面,并关闭其他所有非tabBar页面。

实例代码:

//app.json中写的的tabBar
{
    "tabBar": {
    "list": [
        {
            "pagePath": "index",
            "text": "首页"
         },
         {
            "pagePath": "other",
            "text": "其他"
          }
        ]
      }
    }
wx.switchTab({
 url: '/index'
})

wx.reLaunch(Object object)

关闭所有页面,打开到应用内的某个页面

示例代码

wx.reLaunch({
    url: 'test?id=1'
})

wx.redirectTo(Object object)

关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。

wx.navigateTo(Object object)

保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈,最多十层。

示例代码

wx.navigateTo({
 url: 'test?id=1'
})
// test.js
Page({
   onLoad(option) {
      console.log(option.query)
     }
})

wx.redirectTo与wx.navigateTo的区别

1.利用wx.navigateTo跳转到下一个页面的时候(这时候会执行onHide方法),下一个页面头部会有返回按钮
2.如果不想有返回按钮,可以用wx.redirectTo进行页面跳转(这时候关闭此页面,会执行onUnload生命周期,这样下一个页面就
不会有返回按钮了,因为上一个页面已经被关闭了,没有页面可以返回)

wx.navigateBack(Object object)

关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。

示例代码

wx.navigateTo({
 url: 'B?id=1'
})
// 此处是B页面
wx.navigateTo({
 url: 'C?id=1'
})
// 在C页面内 navigateBack,将返回A页面
wx.navigateBack({
    delta:2
})

wx存储数据到本地及本地获取数据

存到本地就是存在手机上。

wx.setStorageSync(string key, any data)(同步)

参数:

string key: 本地缓存中指定的 key

any data: 需要存储的内容。只支持原生类型、Date、及能够通过 JSON.stringify 序列化的对象。

示例代码

wx.setStorage({
    key:'key',
    data:'value'
})

try{
    wx.setStorageSync('key', 'value')
} catch(e){ }

wx.setStorage(Object object)(异步)

将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。数据存储生命周期跟小程序本身一致,即除用户主动删除或超过一定时间被自动清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。

示例代码

wx.setStorage({
    key: 'key',
    data: 'value'
})
try {
    wx.setStorageSync('key', 'value')
} catch (e) { }

上面的两个就是一个是同步的一个是异步的,还是有区别的,想用哪一个看你的业务来定

wx.getStorageSync(string key)(同步)

参数
string key: 本地缓存中指定的 key
返回值: any data,key对应的内容
示例代码

wx.getStrage({
    key:'key',
    success(res){
        console.log(res.data)
    }
})

try{
    const value = wx.getStorageSync('key')
    if(value){
        console.log('yes')
    } 
}catch(e){
    console.log('no')
}

wx.getStorage(Object object)(异步)

示例代码

wx.getStorage({
    key: 'key',
    success(res) {
        console.log(res.data)
    }
})
try {
    const value = wx.getStorageSync('key')
    if (value) {
 // Do something with return value
    }
} catch (e) {
 // Do something when catch error
}

小程序基础

上一篇:微信公众平台开发问答


下一篇:微信助力活动开发