小程序的认识(初步概括有哪些)

小程序的数据绑定

在data中定义数据
在页面中使用mustache表示(和React中一致)

小程序的列表展示

vx:for
<view wx:for="{{students}}">{{item}}</view>

小程序的事件监听

<view>当前:{{counter}}</view>
<button size="mini" bindtap='functionname '></button>
通过this.setData来改变Data中的数据

小程序的MVVM架构

Model View ViewModal
视图层 逻辑层 MINA框架
wxml js 数据绑定&&DOM监听
//编程范式
1.命令式编程:原生操作DOM
2.声明式编程:直接操作data

小程序的生命周期(以app.js为例)

onLaunch:页面初始化完成,一般在这里获取用户信息wx.getuserinfo()

onShow:小程序界面显示的时候执行

onHide:界面隐藏时候被执行。当用户退出小程序的时候,数据状态会持续将近两个小时
时间内用户再次进入小程序不会再触发onLaunch

onError:程序发生错误的时候执行

注册APP的时候,一般会做一些什么?

1.根据小程序的打开场景进行场景分发,在onShow中的option参数中的scene字段,可以根据文档查找相应场景
2.只想执行一次的可以放在onLaunch中,每次进来都想执行,就放在onShow中
3.wx.getUserInfo获取用户信息。官方据说要废弃?记于2020.03.09日

获取用户信息的方法

  • 前面提到的要被废弃但是任然没有废弃的getUserInfo
  • 用具有open-type为getUserInfo的按钮绑定bindgetUserinfo来获取用户信息
  • 使用open-data组件展示用户相关信息,type进行用户属性选择

4.定义全局数据,使用getApp方法来获取App.js中的实例对象

注册Page的时候发生了什么

1.在生命周期函数中发送网络请求,做数据处理和展示

page中的生命周期和App中类似,按照执行顺序排列为
onLoad:页面被加载时候执行
onShow:页面显示出来时候执行
onReady:页面初次渲染完成,第二次渲染就不执行了
onHide:页面隐藏时候的时候执行
onUnload:页面跳转到另外一个页面的时候
2.初始化一些数据,存放在page中的data里面
3.监听wxml中的相关事件
4.其他的事件监听
  • 滚动onPageScroll
  • 下拉到底部onReachBottom
  • 下拉刷新onPullDownRefresh
  • 点击tabbar时候的监听onTabItemTap

组件

Text组件

  • Text组件相当于一个行内元素,连续的Text元素会在同一行(不加额外样式的情况下)
  • Text组件默认不可选中,除非把selectable设置为true
<text selectable='{{true}}'>hello word</text> 等效于 <text selectable>hello word</text>

selectable:决定文本是否可以长按选择
space:决定文本空格的大小,nbsp ensp emsp 默认为nbsp ensp为字母字符大小 emsp要:一个中文字符的大小
decode:是否解码文本,<text>5>3</text> 当decode为true的时候才会正确解码

Text组件api

Button组件

就是一个button,用bindtap绑定事件
button组件api

View组件

等效于div,一个简单的块元素
view组件api

image组件

bindload监听图片加载完成事件
wx.chooseImage来让用户选择图片
lazy-load:图片的懒加载,等屏幕即将进入屏幕之后再进行加载
mode:图片的覆盖模式,和backgroudsize属性来互相理解
image组件api

Input组件

input默认透明没有边框
type定义input的限制值
confirm-type定义键盘右下角的按钮的text
bindinput bindblur bindfocus和html中的onchange onblur和onfocus一一对应
Input组件api

scroll-view组件

实现一个可以局部滚动的div
一个固定宽高设置overflow-scrool-x或者-y的div
通过绑定bondscroll事件来监听滚动事件来获取event获取当前滚动位置
scrolltoupper/scrolltolowers
涉及到滚动就可以联想到函数的防抖来优化
scroll-view组件api

组件的共同属性

id:元素的标识符,一般每个元素的ID不一样
class:控制元素的样式
hidden:控制元素的隐藏
data-:定义自定义数据
*bind*/catch*元素的事件绑定

WXSS

行内样式style和class来混合修饰
全局样式在app.wxss中定义
涉及到样式的权重问题

div > #title{color: blue;}             //标签+id = 100+1 = 101`

div > h3 #title.title{color: red;}         //标签+标签+id+类 = 1+1+100+10=112`

[lang=”en”] h3.title{color: green;}//属性+标签+类 = 10+1+10 =21`

[lang=”en”] #title{color: gray;}         //属性+id = 10+100 = 110`

source:错误题目题解


善于利用官网样式库的样式来做,可以节省时间

WXML

类似于html语法:可以写成单标签,也可以写成双标签
必须有严格的闭合:没有闭合会导致编译错误
大小写敏感:class和Class是不同的属性

Mustache语法

可以用{{}}使用对应js中data总定义的变量在wxml中动态展示

条件判断

wxml中常见的条件判断
三目运算符:

<view> {{isActive?"active":''}} </view>

wx:if-wx:elif-wx:el
通过不同分数显示不同的结果

<view wx:if="{{score>=90}}">优秀</view>
<view wx:elif="{{score>=80}}">良好</view>
<view wx:elif="{{score>=60}}">及格</view>
<view wx:else>不及格</view>

通过hidden属性隐藏的时候,通过设置组件的display:none
通过逻辑判断来隐藏的时候,组件不会渲染在dom中
当某个子元素需要经常隐藏显示的时候,使用hidden属性来控制
否则用条件判断来判断是否显示

wx:for列表渲染

使用wx:for对一个可遍历对象(数组,字符串等)进行渲染,自动生成对应的子元素变量item和index
当遍历对象为数字的时候,会从零开始遍历到 数字-1位置

<view wx:for="{{[abc,cba,ngb]}}">{{item}}{{index}}</view>
<view wx:for="{{9}}">{{item}}</view>// 0 1 2 3 4 5 6 7 8 

block标签

</block>并不是一个组件,仅仅是一个包裹元素,不会在页面中作任何渲染,只接受控制属性
相当于Fragment,用于包裹子标签无实际意义的空标签,不会在dom中生成实际节点
只会在逻辑层起效
如果用view包裹的话,浪费性能,且容易被全局样式影响

wx:for-item='xxx' wx:for-index="i"

在遍历时候可以给默认的item和index进行重新定义名字,在多重遍历的时候,防止歧义用

<view wx:for="{{movies}}" wx:for-item="movie" wx:for-index="i">{{movie}}{{i}}</view>

key的作用

<view wx:for="{{[abc,cba,ngb]}}" wx:key="{{index}}">{{item}}{{index}}</view>

和流行框架vue和React一样,key值在虚拟dom中的diff算法的对比起到至关重要的作用。当每个遍历子元素有唯一标识key的时候,子元素发生改变的时候会根据key值对子元素进行局部修改。当没有key值得时候,就要全部替换后重新渲染,极大的影响性能。所以key的作用就是高效的更新虚拟dom

模板语法

template

可以在模板中定义代码片段,在不同的地方调用(是一种wxml代码的复用机制)
(之前的小程序不支持自定义组件,为了进行代码的复用出来的template机制)

//模板中包裹的内容,在没有使用前,是不会进行任何的渲染的
<template name=“contentItem”>
  <button>{{btntext}}</button>
  <view>{{content}}</view>
</template>

<template is=“contentItem” data="{{btntext:'按钮',content:'hhhhh'}}">

模板导入

将上述代码单独放在一个名为template.wxml文件夹中,需要使用的地方只需要用improt进行导入
相对路径和绝对路径均可

<import src="../../wxml/template.wxml">
<import src="/wxml/template.wxml">

include进行模板导入的时候,常用场景是多页面的header和footer的复用,支持循环导入
比如AincluedB BincludeC 此时A也是includeC的
import导入:

  • 主要是导入template
  • 特点:你们进行递归导入(不能套娃)

include引入:

  • 将公共的wxml中的组件抽取到一个文件中
  • 特点:不能导入template/wxs,可以进行递归导入

WXS(wxscript)

官方:wxs与javaScript是不同的语言,有自己的语法,并不和javcScript一致(不过基本一致:疯狂吐槽)
在wxml中不能直接调用Page/Component中定义的函数
但是在某些情况,我们可以希望使用函数来处理WXML中的数据(类似于Vue中的过滤器),这个时候就使用WXS了

  • WXS的运行环境和其他JavaScript代码是隔离的,WXS中不能调用其他JavaScript文件中定义的函数,也不能调用小程序提供的API
  • WXS函数不能作为组件的事件回调
  • 由于运行环境的差异,在IOS设备上小程序内的WXS会比JavaScript代码快2-20倍。在android设备上二者运行效率无差异

wxs的使用方法

直接在wxml中使用

<wxs module="info">
//JS代码 不支持ES6
var message="hello world"
var name="code why"
var sum=function(num1,num2){
  return num1+num2
}
module.exports={
  message:message,
  name:name,
  sum:sum
}
</wxs>
<view>{{info.message}</iview>}

在单独文件中定义后引入,不能使用绝对路径,必须使用相对路径

<wxs src="../../info.wxs" module="info"/>

wxs的应用

定义一些常用的数据处理函数,来在wxml直接对变量进行处理

//format.wxss
function priceFormat(price, number) {
    var number = number || 2;
    var f_price = parseFloat(price);
    return f_price.toFixed(number)
}
module.exports = {
    priceFormat: priceFormat
}

//wxs.wxml
  <wxs src="../../wxs/format.wxs" module="format"/>
  <view>{{format.priceFormat(price,3)}}</view>

事件

常见事件

<button bindtap='handleBtnClick' size='mini'>按钮</button>

<button bind:tap='handleBtnClick' size='mini'>按钮</button>

<button catch:tap='handleBtnClick' size='mini'>按钮</button>

某些组件会有自己特性的事件类型,大家可以在使用组件时具体在文档中查看
其他的常见时间类型:
touchstart:手指触摸动作开始
touchmove:手指触摸后移动
touchcancel:手指触摸动作被打断
touchend:手指触摸动作结束
tap:手指触摸后马上离开
longpress:手指触摸后,超过350ms离开,如果指定了事件回调函数出发了这个事件,tap事件将不被触发1
longtap:推荐用longpress代替

事件对象的分析event

理解changtouches和touches的区别
理解currenttarget和target的区别

事件参数传递

使用data-xxx在元素中定义
在方法中通过event元素的event.target/currenttarget.dataset获取

事件的冒泡和捕捉(xxx 为事件类型)

事件捕获阶段的事件绑定:captrue-bind:xxx
事件冒泡时候的事件绑定:bind:xxx
阻止事件继续传递的绑定方式:catchxxx

组件化开发

创建一个自定义组件

在项目目录下创建一个components文件夹,新建一个component,包含四个文件

  • 首先需要在json文件中进行自定义组件的声明(将component字段设为true可将这一组文件设为自定义组件)
  • 在wxml中编写属于我们组件自己的模板
  • 在wxss中编写属于组件自己的相关样式
  • 在js文件中,可以定义数据或组件内部的相关逻辑

使用自定义组件的细节注意事项

  • 因为WXML字节标签名只能是小写字母、中划线和下划线组合,所有自定义组件的标签名也只能包含这些字符(数字其实也行)
  • 自定义组件也是可以应用自定义组件的,应用方法类似于页面应用自定义组件的方式(使用usingComponents字段)
  • 自定义组件定义名字的时候,不要用'wx-'为前缀
  • 如果在app.json的usingCoponents声明某个组件,那么所有页面和组件可以直接使用该组件(很多UI库的应引用方式)

自定义组件的样式注意事项

  • 组件内定义的样式不会对全局样式造成污染
  • 组件内不推荐使用id选择器,属性选择器,标签选择器

如果想要组件和page之间的class相互影响,
需要在Component中的options参数,该参数可以配置多个值,不同的值

  • isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
  • apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
  • shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。
Component({
  options:{
  styleIsolation:'apply-shared'
}
})

组件和页面之间的通信

  • 数据:properties 在页面标签中添加数据,在组件的properties中接收,同事可以使用observer属性对值进行监听
properties{
  title:{
      type:String,
      value:''//默认值  
      observer:function(newvalue,oldvalue){
        console.log(newvalue)
        console.log(oldvalue)
  }
  }
}
  • 样式:externalClasses 再页面标签中添加class,在组件的externalClasses中做接收,用数组保存
  • 标签:slot插槽

首先定义一个单插槽组件

//插槽的定义
//mtyslot
<view>这是组件的头部</view>
<slot />
<view>这是组件的尾部</view>
---------------------------------------
//插槽的使用
<mtyslot>
    <button size="mini">我是插入的按钮</button>
</mtyslot>

<mtyslot>
    <text>我是插入的文本</text>
</mtyslot>

当使用多个插槽时候,需要给每一个插槽给一个name属性,且必须在component中的options中添加multipleslot:true

//插槽的定义
//mtyslots
<view>这是组件的头部</view>
<slot name="slot1"></slot>
<slot name="slot2"></slot>
<slot name="slot3"></slot>
<view>这是组件的尾部</view>
<button slot="slot1"></button>

组件中的js配置

Component({

  options:{
    multipleSlots:true
  },
})
  • 自定义事件:通过在组件中定义事件,并用triggerEvent进行事件分发后在父组件中接收,实现组件向页面中的数据传递
  • 操作组件对象:直接获取到组件对象,并且对组件的内部的值进行修改(不推荐使用,最好还是用自定义事件来进行统一修改)
//获取到组件对象
//id 为组件在页面中使用的id,class为组件中的class
const my_sel=this.selectComponent(id)
//const my_sel=this.selectComponent(class)
my_sel.setDate({
  xxxxxxxxxxxxxxxxxxxx
})
//对组件进行操作修改值

Component构造器


网络请求

Page({
data:{
},
onLoad:function(options){
  //send request
  //对应的域名需要配置
wx.request({
  url:'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  sucess:function(res){
  console.log(res)
}
})
}
})

网络请求的封装

export default function request(options) {
 return new Promise((resolve, reject) => {
   wx.request({
     url: options.url,
     method: options.method || get,
     data: optinos.data || {},
     sucess: function(res) {
       resolve(res)
     },
     fail: function(err) {
       reject(res)
     },
   })
 })
}



request({
 url: 'xxxxxxxxxxxxxxxxxxxx'
}).then(res => {
 console.log(res)
}).catch(
 err => {
   console.log(err)
 }
)

pan463859
21 声望0 粉丝

永远的前端小白~