微信小程序
1.小程序普通网页的区别
运行环境不同
网页运行在浏览器环境中
小程序运行在微信环境中
api不同
小程序无法调用原生的 DOM 和 BOM 中的API
可以调用微信环境提供的API
开发模式不同
网页:浏览器+编辑器
小程序:1.申请小程序开发账号
2.安装小程序开发者工具
3.创建和配置小程序项目
2.注册-获取AppID
AppID在开发-开发设置-开发者ID
3.了解微信开发者工具
提供的主要功能:
快速创建小程序
代码查看和编辑
对小程序进行调试
小程序的预览和发布
下载: 推荐下载安装最新的 稳定版
可以创建 小程序 小游戏 代码片段 公众号网页
4.创建小程序
创建时需要用到AppID
可以 预览 可以 真机调试
5.文件 项目结构
pages --文件夹-存放小程序所有页面
-index --文件夹-页面1
-index.js -当前页面js脚本
-index.json -当前页面配置文件,如窗口外观
-index.wxml -当前页面的html
-index.wxss -当前页面的css
utils --文件夹-存放工具性质的模块
app.js --小程序 入口文件
app.json --小程序 全局配置文件
app.wxss --小程序 全局样式
project.config.json --项目的配置文件
sitemap.json --配置小程序及其页面是否允许被微信索引
6.四个JSON文件的作用
7.新建页面
在app.json 中的pages数组添加正确的路径并保存,自动添加文件
调整app.json 中的pages数组的前后顺序,第一个是首页
8.wxml 和 html 区别
div - view
span - text
img - image
a - navigator
<a hraf="/pages/home/home"></a>
->->->
<navigator url="/pages/home/home"></navigator>
9.wxss 和 css 区别
CSS中需要手动进行像素单位换算,例如 rem
WXSS 在底层支持新的尺寸单位 rpx,在不同大小的屏幕上小程序会自动进行换算
WXSS 仅支持部分 CSS 选择器,常见的都支持
10.小程序通信模型
1.渲染层(wxml+wxss) 逻辑层(js)
2.微信客户端
3.服务器
上面三个都是通过微信客户端进行转发,经过客户端进行通信
11.小程序启动过程
1.下载小程序代码包
2.解析 app.json 全局配置
3.执行 app.js 入口文件,调用 App() 创建小程序实例
4.渲染小程序
5.小程序启动完成
12.页面渲染过程
1.加载解析页面的 .json 配置文件
2.加载页面的 .wxml 模板和 .wxss 样式
3.执行页面 .js 文件,调用Page()创建页面实例
4.页面完成渲染
13.小程序 - 组件
9 大类:
1.视图容器
view -类似div
scroll-view -滚动视图
swiper 和 swiper-itme -轮播
text -文字 selectable属性开启可以长按选中
rich-tetx - 属性nodes=“html渲染”
button - 可以通过open-type属性调用客服、转发、授权等
image - 默认300px*240px
2.基础内容
3.表单组件
4.导航组件
5.媒体组件
6.map 地图组件
7.canvas画布组件
8.开放能力
9.无障碍访问
14.API
分3大类
1.事件监听 API - on 开头 wx.onWindowResize()
2.同步API - Sync 结尾 wx.setStorageSync()
3.异步API - 网络请求 wx.requst()
15.权限管理需求
管理员
运行者
开发者
-体验者
数据分析者
16.版本
开发版本
体验测试版本
审核中版本
正式版
17.发布
先在开发者工具 中 上传
在管理后台 可以看见 上传的 版本
提交审核
发布
- 推广 在 管理后台 / 基本信息里有二维码
- 运营数据 在 管理后台 / 统计中,
或 统计中扫码 小程序数据助手
18.数据绑定
内容{{}} 属性 src=“{{}}”
data 中申明
this.setData 更改方式:
this.setData({
i:this.data.i + 1
})
19.事件绑定
tap 手机触摸后离开-点击 方式:bindtap 或 bind:tap 传参data-*=“” 获取e.target.dataset.
input 文本框输入事件 方式:bindinput 或 bind:input 绑定值 value=“{{}}” 获取值 e.detail.value
cahnge 状态改变事件 方式:bindcahnge 或 bind:cahnge
传参 通过 属性 data-info=“22” data-**=“{{22}}” 不写{{}}是字符串 写是数字
e.target.dataset.info 获取事件的参数值
e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的 view 组件
20.条件传染
wx:if="{{}}"
wx:elif="{{}}"
wx:else
--<block> 可以包裹多个view 不会渲染block元素 只是包裹性质的容器
hidden=“{{}}” true 隐藏 false 显示
21.列表渲染
wx:for=“{{arr}}” wx:key="***"不用写{{}}
自动就可以使用 index item
改名 wx:for-index="index11" wx:for-item="itemName"
22. wxss
rpx 所有设备屏幕 宽度 等分为 750份 =750rpx
@import样式导入 @import “/a/a/a.wxss”;
局部样式和全局样式冲突 局部权重一样或大于,局部会覆盖全局 全局权重高就覆盖局部
22. 全局配置
app.json > window 对象 -部分也可以在单独页面的json中设置
导航栏
下拉刷新
上拉触底 -默认50
app.json > tabBar 对象
tabBar 底部菜单 -菜单的路由在app.json > pages[] 中需要放在 最前面
23.数据请求
请求 https 且不能使用ip地址 在后台一个月最多修改5次 request 合法域名
wx.request({
url: 'https://aip.baiduce.com', //仅为示例,并非真实的接口地址
method: 'GET',
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success (res) { // 成功
console.log(res.data)
},
fail (res) { // 失败
console.log(res.data)
},
complete (res) { // 请求完成
console.log(res.data)
},
})
24.页面导航
1.声明式导航
页面上声明一个<navigator url=‘/a/a’ open-type=‘navigate / switchTab’>组件,点击跳转
url 需要以 / 开头
open-type 值为switchTab 导航到tab页面
值为navigate (默认值) 导航到其他页面
值为navigateBack + delta=“1”(默认可以不写) 后退
传参 ?a=1&b=2
2.编辑式导航
调用小程序导航api,实现跳转
导航到tab页面 wx.switchTab({
url: '/a/a'
})
导航到其他页面 wx.navigateTo({
url: '/a/a' 传参/a/a?a=1&b=2
})
后退 wx.navigateBack() 默认{delta:2}
3.获取参数
在onLoad中接收
onLoad: function(option) {
option就是参数对象,转存到data中可用this.data.**
}
25.生命周期
分两类:
应用生命周期
小程序重启动 - 运行 - 销毁 的过程
在 App({}) 中声明
onLaunch :function(options){} 初始化完成时,全局只触发一次
onShow :function(options){} 小程序启动,或从后台进入前台显示触发
onHide :function(){} 小程序从前台进去后台
onError :function(error){} 小程序发生脚本错误或 API 调用报错时触发
页面生命周期
页面的加载 - 渲染 - 销毁 的过程
在Pages({})中声明
onLoad :function(query){} 监听页面加载。 一个页面只调用一次
onShow :function(){} 监听页面显示
onReady :function(){} 监听页面初次渲染完成。 一个页面只调用一次
onHide :function(){} 监听页面隐藏
onUnload :function(){} 监听页面卸载。 一个页面只调用一次
自定义组件的生命周期函数
created 组件实例刚刚创建时执行 不能调用setData
attached 组件实例进入页面节点树时执行 初始化完毕,可以请求数据
ready 组件在视图成布局完成后执行
moved 在组件实例被移动到节点树另一个位置时执行
detached 在组件实例被从页面节点树一处时
error 到组件方法抛出错误时
组件内监听所在页面的生命周期
pageLifetimes:{
show:function(){}, // 所在页面被展示
hide:function(){}, // 所在页面被隐藏
resize:function(size){}, // 所在页面尺寸变化
}
26.wxs
在wxml中创建<wxs src="../a/a" m><wxs>
27.自定义组件
新建Components文件夹创建a
引用 {
“usingComponents”: {
“name组件名”: “/components/a”
}
}
使用 <name组件名></name组件名>
在 app.json 引用 全局 在页面的 json 中引用是局部
****组件和页面的区别****
1. 组件的 .json 文件中需要声明 “conponent”:true
2. 组件的 .js 文件中调用的是Component()函数,建议方法名以下划线开头 --其他 ps:页面是Page(),app是App()
3. 组件中的事件函数需要定义到 methods 节点中,页面的函数在同级就行
4. 全局的样式 在组件中 无效 ,但是只有class选择会被隔离,其他不受影响,会根据权重被覆盖
*组件类有样式隔离特性,如需要能控制组件内部样式使用
在.js 中 Component({option:{stylesolation:'isolaed'}})
或 在json中'stylesolation':'isolaed'
stylesolation:默认值-启用-isolaed / 页面去影响组件 apply-shared / 组件和页面都会影响 shared
<name组件名 max=“10”></name组件名>
自定义组件接收参数
propreties:{
第一种 没有默认值
max:Number
第二种 可以设置默认值
max:{
type:Number,
value:10
}
}
****data和propreties区别****
用法相同,都是可读可写
data更倾向于存储私有数据
properties更倾向于存储外界传递到组件中的数据
数据监听器 observers
observers:{
‘a,b’ 或 ‘obj1.a,obj2.b’ :function(a的新值,b的新值){}
// 属性太多时可以使用**通配符来监听
‘obj.**’:function(newobj){ //newobj.a //newobj.b }
}
27.自定义组件 - 父子组件之间的通信
1.属性绑定 父传子
<f count="1"><f>
<c>{{count}}<c>
properties:{count:Number}
2.事件绑定 子传父
<f count="1" bing:sync="syncCount"><f>
syncCount(e){
this.setData({
count: e.detail.value1
})
}
<c>{{count}}<c>
properties:{count:Number}
// 数据修改后,去触发自定义事件,将值同步给父级
this.triggerEvent('sync-自定义事件名称', {参数-value1:this.properties.count})
3.获取组件实例 方式
父 通过获取子组件实例去访问数据或方法
let child = this.selectComponent("id或class / .class")
child.setData({
count: child.properties.count+1
})
27.自定义组件 - 插槽
<!-- 组件模板 -->
<view class="wrapper">
<view>这里是组件的内部节点</view>
<slot></slot>
</view>
<!-- 引用组件的页面模板 -->
<view>
<component-tag-name>
<!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
<view>这里是插入到组件slot中的内容</view>
</component-tag-name>
</view>
默认 组件 是只允许 一个 插槽
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
<!-- 组件模板 -->
<view class="wrapper">
<slot name="before"></slot>
<view>这里是组件的内部细节</view>
<slot name="after"></slot>
</view>
<!-- 引用组件的页面模板 -->
<view>
<component-tag-name>
<!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
<view slot="before">这里是插入到组件slot name="before"中的内容</view>
<!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
<view slot="after">这里是插入到组件slot name="after"中的内容</view>
</component-tag-name>
</view>
27.自定义组件 - behaviors 类似于vue的mixins
可以实现相同代码的共享
每个 behaviors 可以包含 属性、数据、生命周期函数、方法。 组件引用时会被合并到组件中
每个组件都可以引用 behaviors ,behaviors也可以引用其他 behaviors
// a.js
// 调用Behavior()方法,创建实例对象,并共享出去
module.exports = Behavior({
// 属性节点
properties: {},
// 私有数据节点
data: {}
// 事件处理函数 和 自定义方法 节点
methods: {},
behaviors: [其他]
})
// 使用
var myBehavior = require('../a')
Component({
behaviors: [myBehavior]
})
组件 和 behaviors 字段 可以 同名
28.npm包
不支持依赖 Node.js 内置库的包
不支持依赖 浏览器内置对象 内置库的包
不支持依赖 C++插件库 的包
Vant Weapp 有赞团队开源UI包
1. 初始化 npm init -y 获得package.json
2. 安装 npm
3. 构建 npm:工具 --> 构建 npm ,完成后在本地设置 中 开启 npm 支持
4.修改 app.json
29. 数据共享 MobX
创建 strore
在页面使用
在组件使用
30.分包
主包 + 分包
独立分包
分包预下载
uni-app
1.创建 uni-app 项目
1.下载并安装 HBuilderX
2.安装 scss/sass 编译
https://ext.dcloud.net.cn/plugin?name=compile-node-sass
3.新建 uni-app 项目
选择 uni-ui项目 (内置uni-ui的项目模板)
┌─components uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置小程序的全局样式、生命周期函数等
├─manifest.json 配置应用名称、appid、logo、版本等打包信息
└─pages.json 配置页面路径、页面窗口样式、tabBar、navigationBar 等页面类信息
4.运行至 微信开发者工具
在 manifest.json 中设置 AppID
配置 微信开发者工具 安装地址
在微信开发者工具中,通过 设置 -> 安全设置 面板,开启“微信开发者工具”的服务端口
运行到小程序模拟器
ps:运行的小程是编译后的,修改需要在 HBuilderX 中修改 uniapp 的原始代码
5. Git 管理项目
根目录中新建 .gitignore 忽略文件
/node_modules
/unpackage/dist
ps:由于我们忽略了 unpackage 目录中仅有的 dist 目录,
因此默认情况下, unpackage 目录不会被 Git 追踪,为了让 Git 能够正常追踪 unpackage 目录,
按照惯例,我们可以在 unpackage 目录下创建一个叫做 .gitkeep 的文件进行占位
git init
git add .
git commit -m "init project"
2.登录 退出登录
1.登录
1.首先我们是需要去调用uni.getUserProfile()去获取用户信息的,得到一些登录接口相关的一些数据
2.再去调用uni.login()这个api去获取code字段
3.结合以上这两个api获取的一些数据组合成接口所需要的参数,然后通过调用后端的接口去得到用户的token
2.退出登录
清楚保存的个人信息及token ,并请求后端接口
3.页面的跳转
1.标签跳转 <navigator url="...?key=value">页面跳转</navigator>
1.保留当前页面,可跳转到非 tabBar 页面,使用uni.navigateBack可以返回到原页面(可传参)
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
2.关闭当前页面,跳转到应用内的某个页面。不可打开tabbar页面 (可传参)
uni.redirectTo({
url: 'test?id=1'
});
3.关闭所有页面,打开到应用内的某个页面。可打开tabbar页面(可传参)
uni.reLaunch({
url: 'test?id=1'
});
4.跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。(不可传参)
uni.switchTab({
url: '/pages/index/index'
});
5.关闭当前页面,返回上一页面或多级页面
uni.navigateBack({
delta: 2 //返回的页面数
});
navigateTo, redirectTo 只能打开非 Tab 页面,可传参。
switchTab 只能打开 Tab 页面,不可传参。
reLaunch 可以打开任意页面,可传参。
接收方式
onLoad: function (option) {
//option为object类型,会序列化上个页面传递的参数
console.log(option.key1); //输出 value1
console.log(option.key2); //输出 value2
}
4.微信支付
// 1. 创建订单 pinia == vuex
// 1.1 组织订单的信息对象
// 1.2 发起请求创建订单
// 1.3 得到服务器响应的“订单编号”
// const orderNumber = res.message.order_number
// const orderNumber = HMDD2020091000000001949
// 2. 订单预支付
// 2.1 发起请求获取订单的支付信息
// 2.2 预付订单生成失败
// 2.3 得到订单支付相关的必要参数
// const payInfo = res2.message.pay
const payInfo = {
nonceStr: 'IYKIc5iscUgZIfxj',
package: 'prepay_id=wx011604003115645ec1be4d48174ea70000',
paySign: 'AD04ED5A386B52864E176A5DF26CF436',
signType: 'MD5',
timeStamp: String(Date.now())
}
// 3. 发起微信支付
// 3.1 调用 uni.requestPayment() 发起微信支付
// 3.2 未完成支付
// 3.3 完成了支付,进一步查询支付的结果
// 3.4 检测到订单未支付
// 3.5 检测到订单支付完成
uni.requestPayment(payInfo)