WeChat小程序
1.微信小程序启动:
小程序启动的时候,就是创建一个应用程序对象,这个对象会优先的呈现一个首页页面,后面通过编码让页面与页面之间有一个来回的切换,然后做到一些业务功能的实现。注:配置文件.json、逻辑文件.js、样式文件.wxss。
2.项目目录结构概述:
3.全局各个文件概述:
①app.json
文件用来对微信小程序进行全局配置。文件内容为一个 JSON 对象,有页面路径列表pages、全局的默认窗口表现window、底部 tab
栏的表现tabBar、网络超时时间networkTimeout、debug:开启调试。等等配置。
**详述:**详细见开发者文档,自己写笔记难得写,值得注意的是window和页面的关系,页面是放在window中的,也可以理解为在window上。pages下面的logs.json文件,他的作用是覆盖app.json这个全局配置文件,实现此页面单独配置。
tabBar详述:
它是一个对象类型,tabbBar对象中最重要的一个属性是一个叫list的数组,它的作用是去指定tab
标签的个数,tab
标签的属性有文本,链接地址、position位置,仅支持 bottom
/ top
等属性。一个list最少要2个tab
才会生效,最多5个。
②app.js文件:在全局作用域中调用了App()方法,在方法中创建了一个对象作为参数。App()方法是一个全局函数,它的作用是创建应用程序实例对象、定义应用程序的生命周期事件。
③app.wxss文件:定义了样式文件。(定义了全局共享样式)
4.页面中各个文件概述
约定页面的各个组成文件名字都是一样的,约定大于配置
①.js文件如index.js文件:完成页面的逻辑,实现页面的功能(生命周期控制和数据处理)。
②.wxml(微信标记语言,基于xml)文件:用来定义页面结构,包括页面元素、数据绑定等。
③.wxss(微信样式表文件,完全遵循css语法,单位这点比css高级):用于定义页面样式。
注意取色器的使用,可以用chrome自带的取色器。
④logs目录下面比pages下面多一个logs.json文件,他的作用是覆盖app.json这个全局配置文件,实现此页面单独配置。
5.一个页面分为逻辑层(JavaScript)和界面层(html+css)
6.逻辑层(JavaScript):
①小程序不是运行在浏览器上面的,所以没有BOM和DOM对象
②小程序的js有一些额外的成员:
例如全局js文件中的APP()方法,页面js文件的page()方法和getapp()方法。
小程序的全局方法(全局可以调用执行):
app()方法 用于定义应用程序实例对象(里面有事件方法等)
page()方法 用于定义页面对象,里面传递一个对象,用这个对象去创建一个页面
getapp()方法 用来获取全局应用程序对象,然后可以调用这个对象中的方法。
getCurrentPages()方法 用来获取当前页面的调用栈。(它是一个数组,一个元素就代表了一个调用过的页面,这个元素里面包含了方法执行栈,最后一个元素就是当前页)。
小程序的全局对象wx(用来提供核心API的调用的):
它包含了很多方法和属性,例如上传文件、下载等等API。
③.小程序的js是支持CommonJS规范的
注:
1、es6有的时候不兼容可以转es5。
2、CommonJS规范简介:它规定了文件与文件之间如何组织,如何协同。例如在全局js文件app.js中去调用一个工具(utils)中的某一个js文件中提供的方法,就可以使用这种规范;提供方法的js文件中使用module.exports导出,使用方用路径的方式载入使用。
eg:
//提供方foo.js导出所提供的方法say()方法:
module.export={
say:say
}
//使用方要使用时以路径方式载入
const foo=require('./utils/foo.js')
foo.say()
//注意:关于js中变量定义const,var,let区别;
//1.const定义的变量不可以修改,而且必须初始化。
//2.var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
//3.let是块级作用域,函数内部使用let定义后,对函数外部无影响。
//var和let相比,var是js中全局有效,let是局部有效,有自己的作用域。
关于CommonJS规范,后面会详细介绍。
7.界面层的数据绑定
微信的数据绑定类似于vue的双向绑定,不像web中需要自己去获取元素然后进行数据赋值。但它只是类似于vue而不是vue,美团有一个基于vue的小程序开发框架mpvue简单好用可以了解下。
①简单绑定:
数据绑定使用Mustache语法(类似于vue的插值表达式),即双大括号将变量包起来,与页面结构元素结合就可以了。然后在数据域(词穷,请允许我管page{}中的data叫数据绑定域)赋值。而且这种小胡子语法不仅可以设置元素标签展示的数据,还可设置元素标签的属性值,实现样式的动态变化。
eg:
//页面
<view>{{message}}</view>
<view class="{{ viewClassName }}"></view>
<view>
<text>{{ '小肥宅' }}</text>//直接显示字符串
<text>{{ 125+125 }}</text>//简单逻辑符号
<text>{{ 100>99?'你对了':'你错了' }}</text>//三元运算符
<checkbox checked="{{true}}"></checkbox>//复选框演示布尔值被误解
</view>
//数据绑定域
Page({
data:{
message:'hello 肥宅?!',
viewClassName:'styleOne'
}
})
②mustache(小胡子)语法总结:
1.innerHTML(类似)
2.元素的属性上(不能用作属性名和标签名)
3.可以使用字面量和简单的逻辑运算符
4.当语法解析误解了布尔值ture和false时可以使用{{}}解决(如复选框的是否选中属性)
8.界面层列表渲染
简述:列表数据渲染也就是列表数据绑定。
①循环渲染:wx:for(类似于vue中的template)
1.明确页面结构中的循环体
2.只保留一个循环体元素
3.给循环体赋值,(类似vue)用wx:for遍历data数据绑定域中定义的数据源,(这个数据源一般是一个数组【也可以是对象等】),遍历过后用item代表这个遍历结果,里面包含了数据源各元素值和各元素序号(序号默认用index表示),然后就可以从item中去取值了。
4.注意:也可以给item改名,用wx:for-itme=“别名”,给遍历下标索引定义名称 wx:for-index
eg:要实现如下案例:
//原生代码
<view>
<view>
<checkbox></checkbox>
<text>javascript</text>
</view>
<view>
<checkbox checked="是"></checkbox>
<text>html</text>
</view>
<view>
<checkbox></checkbox>
<text>css</text>
</view>
</view>
//使用wx:for遍历代码
//数据域
data: {
todos:[
{name:'JavaScript',completed:false},
{ name: 'HTML', completed: true },
{ name: 'css', completed: false }
]
}
//循环体元素
<view>
<view wx:for="{{ todos }}">
<text>{{ index+1 }}</text>//index代表序号
<checkbox checked="{{item.completed}}"></checkbox>
<text>{{ item.name }}</text>
</view>
</view>
wx:for 也可以嵌套,下边是一个九九乘法表(官方示例)
<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>
9.界面层事件处理
简述:事件的触发,就像web中的鼠标单击事件、悬浮事件等。
**基本的事件使用:给组件添加一个 bind[xxx] 或者 catch[xxx](处理事件冒泡用) **
①屏幕触碰事件 bindtap
bindtap类似于鼠标单击事件,表示触碰到后执行某一方法。
方法console.dir(e)表示将e对象以树状结构展示,此方法便于调试。
②处理小程序中的事件冒泡
小程序也有事件冒泡,与web中是一样的,html元素嵌套,例如一个大view中有一个小view,他俩都有触碰事件,当触发了内部元素的事件过后,外部元素的事件也会随后触发。有的场景要求触发内部元素的事件而不触发外部元素的事件,这时候就需要阻止事件冒泡了,那么如何阻止事件冒泡呢?
阻止事件冒泡:
将添加事件的方式改为:“catch+事件名”。这种方式的意思是绑定事件并且阻止事件冒泡。
10.界面层事件传参
注意:小程序传参数,不能直接在元素属性定义事件处传了,只能借用系统帮我们传递的参数e(e参数),参数e中有一个target成员代表页面面中被点击的页面结构元素,而target对象中又有一个dataset成员,这个dataset就是页面结构元素的data-[xxx]属性值的集合。
所以小程序中页面传参,需要用data-[xxx]=“xxx”,传递,然后在事件处理函数中去用e.target.dataset取出这个元素的参数集合。
注意:在web开发中,在事件处理函数里面可以通过this找到被触发事件的页面元素,而小程序中不行,只能是e.target代表被触发事件的元素。小程序中this代表的还是触发事件的页面对象。
eg:
//页面传递参数(界面层)
<button bindtap="buttonTapHandle" data-name="张三,你是个小胖砸!!" data-age="32">肥宅快点我</button>
//逻辑层取参
buttonTapHandle: function(e){
console.log(e.target.dataset)//取出参数集合(貌似是一个对象)
console.log("看啥呢?小肥宅")
}
11.单向数据流
①简述:
因为小程序框架是类似但并不是vue,并没有数据的双向绑定,数据的传输是单向的。界面层传数据(参数)到逻辑层借助dataset;逻辑层传数据到界面层通过{{}}mustache(小胡子语法)类似差值表达式。
②那么小程序框架如何实现数据双向绑定并同步?:
注:e参数中有个detail里面包含了元素的value。界面层元素中的数据可以通过e参数的形式(e.detail.value)传递到逻辑层,逻辑层又可以通过小胡子表达式的方式传递到界面层,但是这是不会同步的,要想实现同步的数据双向绑定必须在js文件中的this.setData({})方法中去赋值。
eg:
//index.wxml:
<view class="container">
<input value="{{ message1 }}" bindblur="inputHandle"></input>
<text>{{ message1 }}</text>
</view>
//index.js端:
Page({
data: {
message1:"你好小肥宅!"
},
inputHandle: function(e){
console.log("小胖砸!")
this.setData({
message1:e.detail.value
})
// this.message1=e.detail.value
// console.log(this.message1)//直接赋值可以成功却不能实现同步,所以要在this.setData()方法中赋值。
}
})