一、云开发
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.提交审核(驳回,修改代码继续提交,成功了就提交发布,就可以生成线上版本了,所有人可以访问)