一、云开发
wxml
<!--pages/index/index.wxml-->
<view class="container">
<input type="text" model:value="{{phone}}" bindinput="input" placeholder="请输入账号"/>
<input type="text" model:value="{{pass}}" bindinput="input" placeholder="请输入密码"/>
<image src="{{img}}"></image>
<button bindtap="chooseImage">选择图片</button>
<button bindtap="addFile">add-file</button>
<button bindtap="add">add</button>
<button bindtap="get">get</button>
<button bindtap="update">update</button>
<button bindtap="remove">remove</button>
</view>
<view wx:for="{{arr}}">
{{item.phone}}--- <image src="{{item.fileID}}"></image>
<button size="mini" bindtap="getOne" data-id="{{item._id}}">详情</button>
<button size="mini" bindtap="updateOne" data-id="{{item._id}}">修改</button>
</view>
js
// 1)获取数据库的引用
let db = wx.cloud.database()
// console.log(db);
Page({
/**
* 页面的初始数据
*/
data: {
phone:"",
pass:"",
arr:[],
img:""
},
onShow(){
this.get()
},
input(){},
add(){
// 获取输入值
let phone = this.data.phone
let pass = this.data.pass
// 执行添加数据
db.collection('a-c').add({
data:{
// 字段名称:存储的数据
phone:phone,
pass:pass
},
success:res=>{
console.log(res);
if(res._id){
wx.showToast({
title: '添加成功',
})
this.get()
}
}
})
},
get(){
// 小程序端获取 数据最多只能返回20条
// 云函数端获取 数据做多只能返回100条
// 获取多条数据 {}
db.collection('a-c').where({}).get({
success:res=>{
console.log(res);
this.setData({
arr:res.data
})
}
})
},
getOne(e){
// console.log(e);
let id = e.target.dataset.id
// doc _id
db.collection('a-c').doc(id).get({
success:res=>{
console.log(res);
}
})
},
update(){
// 修改多条 where{}.update局部更新
db.collection('a-c').where({"pass":"11"}).update({
data:{
pass:"123"
},
success:res=>{
console.log(res);
}
})
},
updateOne(e){
let id = e.target.dataset.id
// 修改一条 doc(_id).update()/set()重新设置
db.collection('a-c').doc(id).update({
data:{
pass:"11"
},
success:res=>{
console.log(res);
}
})
// db.collection('a-c').doc(id).set({
// data:{
// pass:"11"
// },
// success:res=>{
// console.log(res);
// }
// })
},
remove(){
// 删除多条 where({}).remove()
db.collection("a-c").where({"pass":"123"}).remove()
.then(res=>{
console.log(res);
})
},2.云函数
一次最多可以获取100条数据,小程序端20条
可以直接返回openid----用户的唯一标识,appid等
小程序调用云函数:
remove(){
// 调用云函数
wx.cloud.callFunction({
name:"remove",//云函数名称
data:{//传参
collection:"a-c",
where:{"pass":"123"}
},
success:res=>{
console.log(res);
}
})
}云函数端--运行在云端的代码--后台代码
本地代码:每次修改记得上传到云端
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: "dev-wmunf"
})
// 云函数入口函数
exports.main = async (event={}, context) => {
// event 接收传递的参数 context 云函数的运行情况
// const wxContext = cloud.getWXContext()
let db = cloud.database()
// 删除多条 必须放在云函数段删除
let res = await db.collection(event.collection).where(event.where).remove()
return {
res,
event, //默认注入appid openid
}
}3.云存储
1.先获取临时图片路径
chooseImage(){
// 调用 图片选择的api
wx.chooseMedia({
count: 1,
success:(res)=> {
// console.log(res.tempFiles[0].tempFilePath)
// tempFilePath可以作为img标签的src属性显示图片
this.setData({
img:res.tempFiles[0].tempFilePath
})
}
})
},2.上传并添加
addFile(){
if(!this.data.img)return;
// 处理后缀名
// http://tmp/lAuUCuVuzgXR0af76f9a39ef41a9f9057741d4ca427c.jpeg
let extName = this.data.img.split(".").pop()
// console.log(extName);
// return
// 处理云端路径
let cloudPath = "web0712/"+new Date().getTime()+"."+extName
// 1)调用 文件上传的api
wx.cloud.uploadFile({
cloudPath,
filePath:this.data.img,
success:res=>{
console.log(res);
if(res.fileID){
// 2)文件id 存到数据里
// ==============
// 执行添加数据
db.collection('a-c').add({
data:{
// 字段名称:存储的数据
phone:this.data.phone,
pass: this.data.pass,
fileID:res.fileID
},
success:result=>{
console.log(result);
if(result._id){
wx.showToast({
title: '添加成功',
})
this.get()
}
}
})
}
}
})
}二、behaviors
behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 “mixins” 或 “traits”。
每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个 behavior ,behavior 也可以引用其它 behavior
示例:自己提取公共代码 common.js
module.exports = Behavior({
properties:{
},
data:{
a:1,
b:0
},
methods:{
add(){
this.setData({
a:2
})
}
}
})xx.js 页面使用
// pages/test/test.js
let myBehavior = require("../../common/common.js")
Component({
behaviors:[myBehavior],
data:{
sum:1
},
methods:{
}
})三、computed计算属性
computed | 微信开放文档 文档地址
1.1概述
computed是小程序自定义组件扩展 behavior,在小程序组件中,计算属性 computed 和监听器 watch 的实现。在 data 或者 properties 改变时,会重新计算 computed 字段并触发 watch 监听器。目前针对的是component构造器
1.2扩展计算属性安装
在小程序端根目录 执行命令
1.npm init -y 2.npm install --save miniprogram-computed 3.构建npm---【点击工具--构建npm】 4.使用npm---【点击详情--本地设置--使用npm模块】
1.3computed 基本用法
test.wxml
<view>{{a}}+{{b}}={{sum}}</view>
<button bindtap="add">add</button>
test.js
// pages/test/test.js
let myBehavior = require("../../common/common.js")
let com = require("miniprogram-computed").behavior
Component({
behaviors:[myBehavior,com],
data:{
sum:1
},
computed:{
// sum(data){
// // 不能访问this
// return data.a+data.b
// }
},
// watch:{
// "a,b":function(a,b){
// console.log(a,b);
// this.setData({
// sum:a+b
// })
// }
// },
observers:{
"a,b":function(a,b){
console.log(a,b);
this.setData({
sum:a+b
})
}
},
methods:{
}
})1.4computed vs watch
从原理上说, watch 的性能比 computed 更好;但 computed 的用法更简洁干净。
此外, computed 字段状态只能依赖于 data 和其他 computed 字段,不能访问 this 。如果不可避免要访问 this ,则必须使用 watch 代替。
1.5watch vs observers
无论字段是否真的改变,
observers都会被触发,而watch只在字段值改变了的时候触发,并且触发时带有参数。
四、工程优化
1.分包
文档地址:分包加载 | 微信开放文档
某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时==按需进行加载==。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。
主包:必须包含启动页面,tabbar,公共的资源 脚本文件
分包:一个分包不超过2M
普通分包:依赖于主包内容----加载普通分包之前,先加载主包内容
独立分包:不依赖主包内容和其他分包。-----只加载自己分包内的资源优势
1.在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。 2.单个分包/主包大小不能超过 2M,整个小程序所有分包大小不超过 20M,能够将工程大小扩充到20M 3.对小程序进行分包,可以优化小程序首次启动的下载时间,以及在多团队共同开发时可以更好的解耦协作。
1.1.配置分包结构
app.json
"subPackages": [
{
"root": "pagesA",
"pages": [
"dog/dog"
]
},
{
"root": "pagesB",
"pages": [
"apple/apple",
"banana/banana"
],
"name": "fruit",
"independent": true
}
],
1.2.独立分包
app.json
"subPackages": [
{
"root": "pagesA",
"pages": [
"dog/dog"
]
},
{
"root": "pagesB",
"pages": [
"apple/apple",
"banana/banana"
],
"name": "fruit",
"independent": true //设置独立分包
}
],问题:
console.log('b分包-apple');
// 问题:直接打开独立分包 获取不到全局实例
// 解决:allowDefault:true 允许获取到空对象 可以往全局实例中添加值
let app = getApp({allowDefault:true})//
app.isLogin = true //当App被调用时,默认实现中定义的属性会被覆盖合并到App中
console.log(app);1.3.分包预下载
app.json
"preloadRule": {
"pages/weui/weui":{
"packages": ["fruit"],
"network": "all"
}
}2.基础库低版本兼容
兼容 | 微信开放文档 文档地址
小程序的功能不断的增加,但是旧版本的微信客户端并不支持新功能,所以在使用这些新能力的时候需要做兼容。
2.1版本号比较
比较方法【参考官方】
fun(){
// const version = wx.getSystemInfoSync().SDKVersion
// if (this.compareVersion(version, '2.10.4') >= 0) {
// wx.getUserProfile({
// desc: '完善资料',
// success:res=>{
// console.log(res);
// }
// })
// } else {
// // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
// wx.showModal({
// title: '提示',
// content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
// })
// }
},
compareVersion(v1, v2) {
v1 = v1.split('.')
v2 = v2.split('.')
const len = Math.max(v1.length, v2.length)
while (v1.length < len) {
v1.push('0')
}
while (v2.length < len) {
v2.push('0')
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i])
const num2 = parseInt(v2[i])
if (num1 > num2) {
return 1
} else if (num1 < num2) {
return -1
}
}
return 0
},2.2API 存在判断 (常见)
if (wx.getUserProfile) {
wx.getUserProfile({
desc: '完善资料',
success:res=>{
console.log(res);
}
})
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}2.3wx.canIUse
console.log(wx.canIUse('showModal.object.editable'));3.骨架屏使用
骨架屏是页面的一个空白版本,通常会在页面完全渲染之前,通过一些灰色的区块大致勾勒出轮廓,待数据加载完成后,再替换成真实的内容。通常在小程序中,我们需要手工维护骨架屏的代码,当业务变更时,同样需要对骨架屏代码进行调整。为了开发的便利,开发者工具提供了自动生成骨架屏代码的能力。
先去project.config.json设置配置,在去生成骨架屏代码
骨架屏 | 微信开放文档 文档地址
五、发布上线
完善小程序资料(头像 名称 服务类目 简介) 1.检查代码包大小 2M 使用分包 2.切换成真实的appid, 3.检查请求的接口是否是合法的域名--在小程序后台配置过域名 4.点击上传-生成开发版本,设置体验版,交给测试人员 5.提交审核(驳回,修改代码继续提交,成功了就提交发布,就可以生成线上版本了,所有人可以访问)