1.创建小程序
- 创建小程序:没注册过的邮箱
- appid:微信公众平台登陆小程序,开发栏可查看
2.小程序项目结构
APP(宏观主体):
app.js(创建app实例以及一些全局相关内容)
app.json(全局配置:window,tabbar等)
app.wxss (全局的一些配置)
Page(页面):
page.js(创建page实例的代码,以及相关内容)
page.json:(业务单独的配置,比如页面对应的window配置,usingComponents)
page.wxml:页面的wxml布局代码
page.wxss:页面的样式配置
Component:
component.js : 创建component实例的代码以及组件内部的内容
component.json : 组件内部的配置,比如当前组件使用了别的组件
component.wxml : 布局代码
component.wxss : 样式代码
3.小程序三体验
1.数据绑定:
在页面或者组件的中的js文件中的data定义 ,在wxml中使用{{}} 使用
2.列表渲染:
<view wx:for='{{student}}'>{{item.name}}+{{item.age}}</view>: student为js中的数组数据 ,item为微信自动生成的变量,为遍历出的每一项数据
3.事件监听:
bindTap:监听点击事件
注意: 在js中修改数据的时候,不能直接修改,必须使用this.setData({})
4.**小程序配置文件:project,sitemap
1.project : 小程序功能版本,一般不手动修改,而是在详情中修改
2.sitemap : 配置小程序搜索
3.app.json全局配置:
1.所有使用的页面都必须在pages下注册
2.window默认窗口配置:navigationBarBackgroundColor(导航颜色)navigationBarTextStyle(导航文字颜色) navigationBarTitleText(导航标题) enablePullDownRefresh(开启全局下拉刷新)
3.底部tabbar:(配置图片可以将iconfont导出为图片进行使用)
=>list数组中每个对象都是一个tabbar,对象中可以配置item选中和未被选中的图标,和文字,图片就新建文件夹放在项目中,用绝对路劲使用
=>和list同级,还可以设置选中tabbar的字体颜色,具体查文档
4.page页面配置:
1.调用公共组件
2.配置和全局不一样的属性(如:导航样式等等,具体查看文档)
5.小程序的双线程模型
谁是小程序的宿主环境呢?=>微信客户端
宿主环境为了执行小程序的各种文件:wxml wxss js 提供了小程序的双线程模型
wxml和wxss运行于渲染层 ,js运行为逻辑层 ,这两个线程都会经由微信客户端(native)进行中转交互
6.小程序的启动流程
1.微信下载小程序包 -> 启动小程序 -> 加载解析app.json -> 注册App() (也会执行App生命周期) -> 加载自定义组件代码(注册自定义组件)
-> (1.解析page.json 2.渲染层加载渲染page.wxml 3.逻辑层注册page()) ->执行Page生命周
2.注册App做什么
App生命周期
=> onlaunch:小程序初始化完成执行
=>onShow(options):小程序页面显示之后执行
1.可监听小程序的进入场景 可以通过options查看
2. 获取用户信息 wx.getUserInfo(这个接口即将废弃) 现行方案:使用按钮,让用户自己来确认,按钮设置 属性:<button open-type=‘getUserInfo’ bindgetUserInfo=”method“>获取信息</button> 然后打印 传入默认参数的详情信息中就有 method(event){ console.log( event.details )}
3.拓展:(可以不再生命周期中使用) 展示用户信息:<open-data></open-data> (可以在文档中的组件中查看使用 ->组件->开放能力)使用:<open-data type="user..."></open-data>具体查看文档
=>onHide:界面被隐藏时执行
=>onError:当程序出现错误的时候执行
3.注册Page做什么:
=>1.在js的onload生命周期中发送数据请求 (设置this.setData的时候注意this的指向,微信提供的请求api 一般用箭头函数来解决this指向问题)
=>2.在data中初始化一些数据
=>3.监听上拉,触底事件
7.常用的内置组件
text组件:
行内标签 其中的文本默认不能被选中
1.可以设置能被选中 <text selectable=‘{{true}}’> helloWorld </text> ->如果不用mastache语法,传入的是字符串,而不是布尔值,
2.还能设置space属性,设置空格大小 3.解码属性 decode :可用于大于号小于号等其他符号的解码
button组件:
1.默认块级元素,如果设置了size='mini',就会变为行内块元素
2.可以设置type来设置颜色
3.plain属性 边框
4.loading属性,加载小圆圈
5.设置点击样式,添加属性hover-class=”ppd“ 然后再wxss中设置样式 .ppd{ color:red;....}
view组件:
容器组件,常用属性
1.hover-class 当用户按下后的属性 (当用户松手,会恢复原有的属性)
2.hover-style-time 样式停留时间
3.hover-stop-propagation 阻止冒泡
image组件:
1.lazy-load属性:图片懒加载
2.bindload:监听图片加载完成事件
3.还有长按识别小程序二维码的功能
4.也有能设置图片在image盒子中的缩放拉伸模式
input组件:
1.value属性:input中的默认值
2.type属性:text ....
3.confirm-type属性:设置弹出键盘右下角的文字 还有一些input的事件具体查看文档
----------------------------------------------------------------------------
scroll-view组件:
实现局部滚动(水平滚动和垂直滚动)
=>水平滚动:
(scroll-view作为父盒子设置宽高和(white-space: nowrap不换行) ,子盒子inline-block (行内元素))
<scroll-view class=”container“ scroll-x>
<view v-for="{{10}}"> 子盒子 </view>
</scroll-view>
=>垂直滚动:
<scroll-view class=”container“ scroll-y>
<view> 子盒子 </view>
</scroll-view>
=>scroll-view的事件:
bindscroll事件,可监听滚动的高度 ,还有类似事件和使用查看具体文档
-------------------------------------------------------------------------------
所有组件的共同属性: id class style hidden(布尔值) data- (自定义属性) bind/catch 组件的事件
8.Mustache ,wxss,wxml,wxs
Mustache :
1.可以写入多个变量 {{ a + b }}
2.可以写表达式 {{ age>=10 ? '成年人': '未成年人' }} (题外话:获取当前时间 new Date().toLocaleString)
3.如何点击按钮,切换某个元素的样式(小程序不允许使用DOM操作):
定义一个布尔值bool,在按钮的点击事件中每次点击都取反, 在需要变换的元素上使用Mustache语法 class=”box {{bool?‘active’:‘’}} “
wxss:
1.支持的选择器: .class #id element ::after ::before
2.扩展单位: rpx 规定屏幕宽度为750rpx (ipone屏幕宽度为375px ,相当于 1rpx = 2px)
3.样式导入,有时候可能会将样式分在多个wxss文件中 ,在页面或者组件中新建文件夹存放多个css,然后再主css中 @import ‘./xxx/xxx.css’
4.导入官方样式库:WeUI ,具体将WeUI在github上download下来,用微信开发工具跑起来,用什么就引用什么(注意一些组件除了css还绑定了很多js)
wxml:
wx:if wx:elif wx:else hidden wx:for wx:for-item wx:for-index
1.=>使用变量控制某个元素的显示和隐藏 <view wx:if="{{isShow}}"></view>
2.=><view wx:if={{score >= 90}}>优秀</view> <view wx:elif={{score >= 90}}>优秀</view>
3.=>hidden为true的隐藏 ,为false的时候显示 ,使用hidden的时候组件依然存在,只是没有显示,而使用wx:if组件跟本就没有被创建出来,当需要频繁切换的时候,推荐使用hidden
4.=>wx:for 一般用于列表数据:<view wx:for="{{list}}"> {{item}} <view> :item默认为列表数据中的每一项
5.=>block标签作用(不是组件):在使用wx:if,wx:for等指令的时候常常是一组标签配合使用,此时我们可以用block来包裹,也可以用view,但是使用view会创建额外的属性
6.=>wx:for-item , wx:for-index一般用于多层遍历,需要使用多个item和index,此时就要重命名来使用
<block wx:for="{{nums}}" wx:for-item='n'> {{n}} </block>
7.=>列表渲染key:使用wx:for时会报警告,这个提示告诉我们,可以添加一个key提高性能
为什么?大概阐述就是:没有key时,一旦涉及改变,被改变的元素以及后面的元素全部会被重新改变渲染,有key时,会识别复用的元素,元素会插入,而不是直接替换后面所有
wxs:
1.在wxml中是不能直接调用page中定义的函数的 {{ myfun( xxx) }}:错误 ,但是在某些情况我们需要过滤某些数据的时候,就需要使用wxs
2.定义一些公共方法,供其他地方调用,比如转换时间戳
3.使用:(详细步骤可看文档)根目录下创建wxs文件夹,创建wxs文件,书写函数,导出,在需要使用的页面或者组件中按需导入对应的方法即可
9.事件-对象-传递参数-冒泡和捕获
事件:
1.某些组件会有自己特性的事件类型,大家可以在使用组件时具体查看对应的文档
比如input有bindinput / bindblur / bindfocus 等 scroll-view有bindscrolltowpper / bindscrolltolower 等 更多的事件查看文档
事件对象:
当某个事件触发时,会产生一个事件对象,并且这个对象被传入到回调函数中,事件对象有哪些常见的属性呢?
type 事件类型
timeStamp 页面打开事件触发经过的事件
target 触发事件的组件的一些属性值集合 :记录产生事件的元素
currentTarget 当前组件的一些属性值集合 :记录触发事件的元素
detail 额外的信息(点击的位置等)
touches 触摸事件,当前停留在屏幕中的触摸点信息的数组 :记录多个手指触摸
changeedTouches 触摸事件,当前变化的触摸点信息的数组 :本来有一个手指,再增加一个手指,触发一次
事件的传递参数:
有三个含有文本内容的view,我们需要点击获取view中的文本,如何获取?
首先,小程序中,不能再点击事件中直接传入 ,而是要使用data-xxx=‘xxx’ 例:data-index=‘{{index}}’ 在js中取值:event.currentTarget.dataset;
事件冒泡和事件捕获:
1.监听事件冒泡和捕获:capture-bind:tap ( 必须使用: ) bind:tap
2.使用bind:一层层传递 catch:阻止事件的传递
10.组件化开发
一.组件化开发:
1.新建components目录,创建components组件
=>当创建组件的时候,.json中会默认加上属性"component": true (此属性代表这是自定义组件,不要随意删除)
2.使用自定义组件
=> 先在需要使用的页面或者组件的.json文件下的usingComponents下定义需要使用的组件才可以正常使用 { '使用时的组件名': ’调用的组件路径‘ }
二.使用自定义组件和细节:
1.自定义组件的标签名只能包含 小写字母,中划线 ,下划线 (一般使用中划线, 因为一些官方组件使用的也是中划线:scroll-view)
2.自定义组件中也能使用其他自定义组件,步骤和在页面中一样
3.在app.json添加usingComponents属性,可以做到全局注册,其他页面和组件直接使用
三.组件的样式细节:
1.在使用class来修改样式的时候,默认会有一个隔离,使页面和组件的样式相互不冲突,所以为了样式不错乱,一般不使用id、属性、标签选择器
2.如何让组件和页面样式能够被单向或者相互影响,在组件的js文件中,options属性下设置styleIssolation:’xxx‘ (具体查看文档)
11.给组件传递数据和样式
1.很多时候,组件内的展示内容,并不是在组件内写死的,而是由使用者来决定
=> 页面可以向组件传递 : 数据(properties) 样式(externalClasses) 标签(slot)
=> 组件向页面传递他发生的行为 : 自定义事件
2.传递数据的具体步骤:
=>1.在自定义组件中的properties中定义一个属性 title:String ,此属性可以直接在组件中用{{}}调用使用 , 然后再父组件中传入title属性值 <cpn title="哈哈哈" />
=>2.上面那种定义方式是最简单切无默认值的,可以设置对象值 title:{ type:String ,value:‘默认值’ ,observer:function(){...} } observer可以监听title的每次改变
3.传递样式的具体步骤:
=>1.给组件的标签添加一个样式titleclass
=>2.这个样式并不是自定义组件写的,而是由父组件传入 ,在自定义组件中定义一个内置属性来接收传入的样式:externalClasses:['titleclass'] (externalClasses与properties同级)
=>3.在父组件调用时,传入我们需要定制的样式 <cpn titleclass="red" /> <cpn titleclass="ool" />
=>4.传入的red/ool代表父组件中的类名 .red{color:red; } .ool {font-size:18px}
=>这样,自定义组件就成功使用了父组件中传入的样式
4.组件向外传递事件-自定义事件
=>由子组件发出,父组件接收,子组件传递的数据,默认在event当中可打印出 (具体使用时查看文档,和vue很像)
12.获取组件对象的方式
1.在组件外部修改组件数据,核心就是调用组件内部的this.setData({ }) => 组件对象.setData({})
2.获取组件对象 : this.selectComponent('class/id') (文档搜索selectComponent)
13.插槽slot
1.组件的插槽是为了让我们封装的组件更加具有扩展性,让使用者决定组件内部的一些内容到底展示什么
2.插槽的使用:
=>单个插槽,直接在自定义组件中使用<slot></slot>
=>多个插槽:
=>在自定义组件中给每一个插槽都添加一个name属性 <slot name=“slot1”></slot>
=>必须在component对象中添加一个选项:options options:{ multipleSlots:true }
=>使用的时候 <view slot="slot1"></view>
14.总结Component构造器
总结Component构造器:
1.properties:让使用者传入数据
2.data:定义组件内部的初始化数据
3.methods:用于定义组件内部的函数 (page页面中,函数方法可直接写在data下面,组件里不行,必须写在methods下)
4.options:组件的配置选项
5.externalClasses:外界给组件传入额外的样式
6.observers:可以监听properties/data的改变
7.pageLifetimes:页面生命周期 (查看文档)
8.lefetimes:组件生命周期 (查看文档)
15.小程序的网络请求
wx.request({
url: 'http://123.207.32.32:8000/api/xxx',
method:'post' //不设置默认get
data:{
type:'sell',
page:1
},
success:function(res){
console.log(res);
},
fail:function(err){
console.log('获取失败')
}
})
除了url,method,data,success等属性,还有很多其他属性,具体查看文档
网络请求的封装:
新建js文件,使用promise封装小程序网络请求api,导出方法,在需要的地方直接调用
export default function request(options) {
return new Promise((resolve, reject) => {
wx.request({
url: options.url,
method: options.method || 'get',
data: options.data || {},
success: resolve,
fail: reject
})
})
}
使用:
import request from '../../services/network.js'
request({
url:'http://123.207.32.32:8000/api/m3/recommend'
}).then(res=>{
console.log(res)
})
16.弹窗,分享,以及登陆流程
1.弹窗
官方文档 => API => 界面 => 交互
wx.showToast:显示提示框 (可设置时间,文本,icon,蒙版)
wx.showModal:显示模态框 (可以设置标题,内容,以及点击确定和取消的回调函数,也可以设置只有确定按钮,和更改按钮文本)
wx.showLoading:显示加载框 (需主动调用 wx.hideLoading 才能关闭提示框,一般切换页面,加载数据,请求数据的时候使用)
wx.showActionSheet:显示操作菜单 (设置弹出菜单,和菜单项,也有回调函数)
17.小程序中的分享
小程序文档 => 框架接口 => 页面 => page => onShareAppMessage
调用小程序api:相当于页面生命周期:
onShareAppMessage:function(options){
return:
}
分享按钮:
<button open-type="share"> 分享</button>
18.小程序的登陆流程
官方流程:
1.调用wx.login获取code
2.调用wx.request发送code到我们自己的服务器(我们自己的服务器会返回一个登陆态的标识,比如token)
=>这个code客户端不需要用,是需要发送给服务端的,wx.request()发送code
=>服务端拿到 code + appid + appsecret (后两个可在小程序控制台拿到),将这三个通过接口发送给微信官方 服务器,微信服务器就会返回session_key + appid
=>服务端自定义登陆态 与 oppenid ,session_key关联 (项目可能除了微信登陆还需要账号密码)
=>服务器返回自定义登陆态 (token)
3.将登陆态的标识token进行存储(可保存在storage),以便下次使用
4.请求需要登陆态标识的接口时,携带token
=>请求一些需要登陆的接口时,就需要携带token
登陆伪代码演示:
//1.先从缓存中取出token,如果没有,就需要重新登陆
const token = wx.getStorageSync(token)
//2.判断token是否有值
if(token && token.length !==0){
//此时已经有token,验证token是否过期
wx.request({
url: 'xxxx',
header:{
token
},
success:res =>{
if(!res.data.errCode){
this.globalData.token = token
}else{
//重新进行登陆操作,可封装成一个方法,到时候直接调用方法
}
},
fail:err=>{
}
})
}else{
//登陆操作
wx.login({
//code只有五分钟的有效期
success: (res) => {
//1.获取code
const code = res.code;
//2.将code发送给我们的服务器
wx.request({
url: 'http://123.207.32.32:8000/api/m3/login',
method: 'post',
data: {
code
},
success: (res) => {
//1.取出token
const token = res.data.token
//2.将token保存到全局globalData中 :当别的页面或组件需要获取的时候=> const app=getApp() => app.globalData.token
this.globalData.token = token
//3.放到对象中,关闭小程序再开又要重新登陆,所以我们要记录到本地存储当中
wx.setStorageSync('token', token)
}
})
}
})
}
19.页面跳转,跳转时数据传递
页面跳转有两种方法:
1.通过navigator组件
2.通过wx的API跳转
=>1.通过navigator组件:
还有很多常用的属性,具体可以查看文档
<navigator url="xxxx/xxx">跳转到详情页</navigator>
=>跳转过程中数据的传递
<navigator url="xxxx/xxx ?name=why&age=18'>跳转到详情页</navigator>
=>如何在跳转的页面中拿到传过来的数据?
在页面生命周期函数onload中的默认参数options中可获取到
onLoad:function(options){
console.log(options)
}
=>如何在跳转页面的时候修改数据
可以通过getCurrentPages来获取所有的页面,然后使用页面对象的setData({})函数来修改
=>2.通过代码跳转页面跳转
xxx(){
wx.navigaTo({ url:'xxxx?...'})
...还有很多种方式的跳转,具体查看文档
}
来源:oschina
链接:https://my.oschina.net/u/4415089/blog/4274429