zoukankan      html  css  js  c++  java
  • 2020年小程序开发-云开发技术总结

    2020年注定是不平凡的一年,一场冠状疫情的爆发,让人们突然认识到生命的可贵,人们对生命重新有了新的认识。谱写了太多的悲伤,太多难过,太多的眼泪和辛酸。珍惜当下,敬畏生命,敬畏自然。

    下面围绕这些规范写内容

    • 文章的创新型

    • 文章的实用性

    • 代码的可借鉴性

    • 代码的规范度

    小程序云开发入门到实践:

    在这里插入图片描述

    wx.cloud.init({
      // env 参数:
      //   env 参数
      //   小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
      //   此处请填入环境 ID, 环境 ID 可打开云控制台查看 如不填则使用默认环境(第一个创建的环境)
      // env: 'my-env-id',
      traceUser: true,
    })
    
    wx.cloud.init({
      env: 'da-da',
      traceUser: true,
    })
    

    在这里插入图片描述

    云函数的配置与部署

    1.下载安装node.js,node.js是在服务端运行JavaScript的运行环境,云开发所使用的服务端环境是node.js,npm是Node包管理器,通过npm可以方便的安装云开发所使用的依赖包。

    node --version
    npm --version
    打开电脑终端(Windows电脑为cmd命令提示符,Mac电脑为终端Terminal)
    

    如果用淘宝镜像cnpm

    sudo npm install -g cnpm --registry=https://registry.npm.taobao.org
    
    cnpm --version
    

    上传到云存储的文件都有一个全网唯一的fileID,fileID只用于小程序内部,可以将fileID传入到SDK就可以对文件进行下载,删除,获取文件信息等操作,非常方便。

    <image src="fileID"></image>
    

    体验一下函数的调用:

    可以获取用户的openid,用户在小程序里有独一无二的openid,相同的用户在不同的小程序openid也不同,因此我们可以用openid来区分用户,可以使用云函数的Cloud.getWXContext()来获取用户的openid

    获取用户信息:

    <button 
      open-type="getUserInfo" 
      bindgetuserinfo="onGetUserInfo"
      class="userinfo-avatar"
      style="background-image: url({{avatarUrl}})"
      size="default"
    ></button>
    
    onLoad: function() {
      // 获取用户信息
      wx.getSetting({
        success: res => {
          if (res.authSetting['scope.userInfo']) {
            // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
            wx.getUserInfo({
              success: res => {
                this.setData({
                  avatarUrl: res.userInfo.avatarUrl,
                  userInfo: res.userInfo
                })
              }
            })
          }
        }
      })
    },
    
    onGetUserInfo: function(e) {
      if (!this.data.logged && e.detail.userInfo) {
        this.setData({
          logged: true,
          avatarUrl: e.detail.userInfo.avatarUrl,
          userInfo: e.detail.userInfo
        })
      }
    },
    

    小程序的open-data可以用于展示微信用户的信息,可以在miniprogram目录index文件夹下的index.wxml文件:

    <open-data type="userAvatarUrl"></open-data>
    <open-data type="userNickName"></open-data>
    <open-data type="userGender" lang="zh_CN"></open-data>
    <open-data type="userCity" lang="zh_CN"></open-data>
    <open-data type="userProvince" lang="zh_CN"></open-data>
    <open-data type="userCountry" lang="zh_CN"></open-data>
    

    学习小程序开发-云开发我觉得挺好,下面总结一下:

    小程序是一种新的开放能力,开发者可以快速地开发一个小程序,小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。

    第一,速度快,无需下载安装,加载速度快于HTML5,微信登录,随时可用;第二,无需适配,一次开发,多端兼容,免除了对各种手机机型的适配;第三,支持直接或app分享给微信好友和群聊;第四,可达到近乎原生app的操作体验和流畅度,在离线状态亦可使用;第五,用完即走,随手可得,通过扫码,长按,微信搜索,公众号,好友推荐等方式快速获取服务,用完即走;第六,低门槛,已有公众号的组织可快速注册,可快速生成门店小程序。

    小程序的技术发展过程:

    HTML5:能力很少;体验差;强烈依赖于开发者的素质

    H5+JSSDK:无法管控;安全问题;依赖开发者素质

    小程序:强管理;统一开发体验

    小程序语言:

    渲染层:WXML+WXSS

    逻辑层:JavaScript

    配置:JSON

    小程序设计规范:

    友好:重点突出,流程明确

    清晰:导航明确,减少等待,异常反馈

    便捷:减少输入,避免误操作,操作流畅

    统一:视觉统一,WeUI

    小程序运营规范:

    账号信息:名称描述清晰,与功能一致,材料真实

    服务类目:类目与页面内容一致,便捷可用

    功能:完整可用,无推荐、排行榜,无搜索小程序,不互推

    数据:获取用户数据时需告知,不得私下收集用户数据

    一般如果你打开一个小程序项目报错如下:

    未找到入口app.json文件,或者文件读取失败,请检查后重新编译。

    别怕是因为你需要了解小程序文件结构:

    小程序包含一个描述整体程序的app和多个描述各自页面的page。

    app.js是小程序逻辑,app.json是小程序公共设置,app.wxss是小程序公共样式表。

    什么是组件,组件是以某种方式对业务逻辑和功能进行封装。

    slot

    component.wxml
    
    <!--组件模板-->
    <view class="wrapper">
     <view>组件的内部节点</view>
     <slot></slot>
    </view>
    
    page.wxml
    // 引用组件的页面模板
    <view>
     <component-tag-name>
      <view>插入到组件slot中的内容</view>
     <component-tag-name>
    </view>
    

    多slot

    component.js
    
    Component({
     options: {
      multipleSlots: true // 在组件定义时的选项中启用多slot支持
     },
     properties: { },
     methods: { }
    })
    
    component.wxml
    
    // 组件模板
    <view class="wrapper">
     <slot name="before"></slot>
     <view>组件的内部细节</view>
     <slot name="after"></slot>
    </view>
    
    // 引用组件的页面模板
    page.wxml
    <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>
    

    说说云开发是什么?

    云开发是微信团队联合腾讯云提供的原生Serverless云服务,致力于帮助更多的开发者快速实现小程序业务的开发,快速迭代。

    一行代码创建数据:

    db.collection('todos').add({
     data: {
      description: 'learn cloud dadaqianduan.cn',
      done: false
     },
     success(res){
      console.log(res)
     }
    })
    

    一行代码查询数据

    db.collection('todos').doc('todoidentifiant-aleatoire').get({
     success(res) {
      console.log(res.data)
     }
    })
    

    云开发QuickStart界面:

    在这里插入图片描述

    点击获取openid:

    在这里插入图片描述

    跟着提示操作可以查看:

    在这里插入图片描述

    点击上传图片

    在这里插入图片描述

    在这里插入图片描述

    前端操作数据库

    在这里插入图片描述

    新增记录
    onAdd: function() {
     const db = wx.cloud.database()
     db.collection('counters').add({
      data: {
       count: 1
      },
      success: res => {
       // 在返回结果中会包含新创建的记录的_id
       this.setData({
        counterId: res._id,
        count: 1
       })
       wx.showToast({
        title: '新增记录成功',
       })
       console.log('新增')
      },
      fail: err => {
       wx.showToast({
        icon: 'none',
        title: '新增失败'
       })
       console.error('失败')
      }
     })
    }
    

    onAdd方法会往counters集合新增一个记录,新增如下格式的一个JSON记录:

    {
      "_id": "数据库自动生成记录ID字段",
      "_openid": "数据库自动插入记录创建者的openid",
      "count": 1
     }
    
    // 查询
     onQuery: function() {
     const db = wx.cloud.database()
     // 查询当前用户所有的 counters
     db.collection('counters').where({
      _openid: this.data.openid
     }).get({
      success: res => {
       this.setData({
        queryResult: JSON.stringify(res.data, null, 2)
        })
        console.log('')
       },
       fail: err => {
        wx.showToast({
         icon: 'none',
         title: '失败'
        })
        console.log('');
       }
      })
     }
    
    // 更新
    onCounterInc: function() {
     const db = wx.cloud.database()
     const newCount = this.data.count + 1
     db.collection('counters').doc(this.data.counterId).updata({
      data: {
       count: newCount
      },
      success: res => {
       this.setData({
        count: newCount
       })
      },
      fail: err=>{
       icon: 'none',
       console.error('')
      }
     })
    },
    
    onCounterDec:function() {
     const db = wx.cloud.database()
     const newCount = this.data.count - 1
      db.collection('counters').doc(this.data.counterId).updata({
      data: {
       count: newCount
      },
      success: res => {
       this.setData({
        count: newCount
       })
      },
      fail: err=>{
       icon: 'none',
       console.error('')
      }
     })
    }
    

    删除功能

    onRemove: function() {
        if (this.data.counterId) {
          const db = wx.cloud.database()
          db.collection('counters').doc(this.data.counterId).remove({
            success: res => {
              wx.showToast({
                title: '删除成功',
              })
              this.setData({
                counterId: '',
                count: null,
              })
            },
            fail: err => {
              wx.showToast({
                icon: 'none',
                title: '删除失败',
              })
              console.error('[数据库] [删除记录] 失败:', err)
            }
          })
        } else {
          wx.showToast({
            title: '无记录可删,请见创建一个记录',
          })
        }
      },
    

    快速创建云函数

    // 云函数入口函数
    exports.main = async (event, context) => {
      console.log(event)
      console.log(context)
      return {
        sum: event.a + event.b
      }
    }
    

    开发云项目,进行QuickStart小程序改造:

    需要把miniprogram文件夹下的pages,images,components,style文件夹里的文件,文件夹都要情况,app.wxss里的样式代码都要清空,将app.json的pages配置项设置为:

    "pages": [
      "pages/index/index"
    ],
    

    云开发项目目录:

    project // 你的小程序项目
    ├── cloudfunctions //云函数根目录
    │   └── login //login云函数目录,可以通过右键云函数根目录来新建
    ├── miniprogram //你原有的小程序文件存放的目录
    └── project.config.json 
    

    在project.config.json添加miniprogramRoot配置

    "cloudfunctionRoot": "cloudfunctions/",
    "miniprogramRoot":"miniprogram/",
    

    小程序的文件结构

    在这里插入图片描述
    在这里插入图片描述

    设置小程序窗口表现

    "window": {
      "backgroundTextStyle": "light",
      "navigationBarBackgroundColor": "#fff",
      "navigationBarTitleText": "WeChat",
      "navigationBarTextStyle": "black"
    },
    

    底部都有一个带有小图标的切换tab,icon 大小限制为40kb,建议尺寸为81px * 81px,注意格式要是png哦

    小程序的根目录:

    ├── image  
    ├── pages 
    ├── utils 
    ├── app.js
    ├── app.json
    ├── app.wxss
    ├── project.config.json
    ├── sitemap.json
    

    相对路径与绝对路径

    ./ 代表当前目录 <img src=”./img/icon.jpg” /> 等同于<img src=”img/icon.jpg” />
    
    ../ 代表上一级目录
    
    / 指的是当前根目录,是相对目录;<img src=”/img/icon.jpg” />
    

    使用uniCloud

    首先将cli项目导入HBuilderX,在项目根目录(src同级)创建cloudfunctions-aliyun或者-tcb目录,然后打开src/manifest.json,在基础配置,uni-app应用表示,处点击重新获取。

    <template>
      <view class="content">
        <view class="btn-list">
          <button type="primary" @click="fun">test</button>
        </view>
      </view>
    </template>
    
    <script>
    export default {
        data() {
            return {
                imageSrc: ''
            }
        },
        methods:{
            fun:function () {
                console.log('函数运行......');
                uni.showLoading();
                uniCloud.callFunction({
                    name:"add",
                    data:{
                        name:"graceUI",
                        age : 20
                    }
                }).then((res)=>{
                    uni.hideLoading();
                    console.log(res);
                    var msg = res.result;
                    uni.showToast({
                        title:msg.msg
                    })
                });
            }
        }
    }
    </script>
    <style>
    .btn-list{margin:25rpx;}
    </style>
    

    uniapp搭建云开发服务项目
    在这里插入图片描述

    创建云服务空间,右键打开cloudfunctions 创建云服务空间 会打开web控制台

    在这里插入图片描述

    创建的云函数,所有操作都是右键上传或者部署云函数

    在这里插入图片描述

    上面讲到uniCloud,那么什么是uniCloud呢?

    uniCloud是Dcloud联合阿里云,腾讯云,为uniapp的开发者提供的基于serverless模式和js编程的云开发平台

    uniCloud的好处在于用熟悉的js,轻松搞定前台整体业务。不管用什么服务器运维,弹性扩容,防DDos攻击,全都不需要操心

    其实客户端调用云函数,如下:

    uniCloud.callFunction()//调用
    

    **云开发api-**云开发API

    wx.cloud
    wx.cloud.database()
    wx.cloud.database().command
    wx.cloud.database().command.aggregate
    

    提前发起权限设置

    wx.authorize({
      scope: 'scope.record',
      success () {
        // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
        wx.startRecord()
      }
    })
    

    1.云开发api分类

    2.云开发api初始化方法

    3.云开发api使用注意事项

    初始化 服务端
    npm install --save wx-server-sdk
    
    const cloud = require('wx-server-sdk')
    cloud.init({
     env: 'test-x' // 环境id
    })
    

    云开发的初始化选项支持传入一个Object,指定各个服务使用的默认环境

    云开发api使用注意事项:

    1.云开发api同时支持callback风格和promise风格

    2.云开发api初始化时如果没有设置id,默认使用先创建的那个

    3.在服务端可以借助云开发sdk内置的getWXContext来获取到用户的身份信息

    云开发数组查询

    const db = wx.cloud.database();
    const _ = db.command;
    
    db.collection("todos")
    .where({
     progress: _.in([0,100])
    })
    .get({
     success: console.log,
     fail: console.error
    });
    

    Index.js

    const db = wx.cloud.database();
    const _ = db.command
    Page({
     query: function() {
      console.log('query')
      db.collection('data')
      .where({
       count: _.nin([1,3,4])
      })
      .get().then(console.log)
     }
    })
    

    了解网络状态

    wx.getNetworkType({
      success(res) {
        console.log(res)
      }
    });
    所在的手机当前的网络状态是WiFi、3G、4G、5G
    

    获取设备信息

    wx.getSystemInfo({
      success (res) {
        console.log("设备的所有信息",res)
        console.log(res.model)
        console.log(res.pixelRatio)
        console.log(res.windowWidth)
        console.log(res.windowHeight)
        console.log(res.language)
        console.log(res.version)
        console.log(res.platform)
      }
    })
    获取用户手机的微信版本、操作系统及版本、屏幕分辨率、设备的型号与品牌、基础库版本等信息。
    

    页面链接跳转

    wx.navigateTo({
      url: '/pxxx'
    })
    
    wx.navigateBack({
      delta: 1
    })
    返回页面的上一层
    

    显示消息提示框

    wx.showToast({
      title: '弹出成功',
      icon: 'success',
      duration: 1000
    })
    

    设置当前页面的标题

    wx.setNavigationBarTitle({
      title: 'xxxx'
    })
    

    打开文件选择器上传文件

    wx.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success (res) {
        const tempFilePaths = res.tempFilePaths
      }
    })
    

    小程序上获取用户信息的四种模式

    wx.login -> 获取code仅可用于获取openid, unionid 和session_key

    button -> 用户首次需使用按钮模式,提示用户主动点击按钮,方可获取用户信息

    wx.getUserInfo -> 用户首次授权后,调用该接口可以获取用户信息,openid和unionid,需调用session_key解密后方可获得

    open-data -> 仅可用于展示用户数据,js逻辑层无法获取

    小程序云开发:

    云函数:wx.cloud.callFunction;数据库:wx.cloud.database;文件存储:wx.cloud.uploadFile

    第一步创建云开发,其目录结构:

    云函数: cloudfunctions

    前端代码:miniprogram

    图片等资源: images

    页面目录: pages

    全局配置: app.js - app.json

    全局样式文件: app.wxss

    项目配置文件:project.config.json

    项目里使用创建的环境,在app.js文件配置

    //app.js
    App({
      onLaunch: function () {
        if (!wx.cloud) {
          console.error('请使用 2.2.3 或以上的基础库以使用云能力')
        } else {
          wx.cloud.init({
            // env 参数说明:
            //   env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
            //   此处请填入环境 ID, 环境 ID 可打开云控制台查看
            //   如不填则使用默认环境(第一个创建的环境)
            env: 'my-env-id',
            traceUser: true,
          })
        }
    
        this.globalData = {}
      }
    })
    

    b

    其实调用云函数文件:

    sum() {
     wx.cloud.callFunction({
      name: 'sum',
      data: {
       a: 2,
       b: 5
      }
     }).then(res=>{
      console.log(res);
     }).catch(err=>{
      console.log(err);
     });
    }
    

    获取当前用户openid:

    <view>云函数</view>
    <button bindtap="getOpenId">获取当前用户openid</button>
    
    getOpenId() {
     wx.cloud.callFunction({
      name: 'login'
     }).then(res=>{
      console.log(res);
     }).catch(err=>{
      console.log(err);
     })
    }
    

    批量删除的代码是怎么写的呢,如下:

    const cloud = require('wx-server-sdk')
    cloud.init()
    const db = cloud.database();
    
    // 云函数入口函数
    
    exports.main = async(event, context) => {
     try{
      return await db.collection('user').where({
       name: 'jeskson'
      }).remove()
     }catch(e){
      console.log(e);
     }
    }
    
    getDelete() {
     wx.cloud.callFunction({
      name: 'bataDelete',
     }).then(res=>{
      console.log(res);
     }).catch(err=>{
      console.error(err);
     })
    }
    

    云开发模式:

    小程序端-》原生接口-》云开发:云数据库,云函数,云存储,云调用,HTTP API

    创建数据库:

    可以在uniCloud中直接创建,也可以通过node.js的后台代码来创建,在uniapp中,为了安全起见,是不允许客户端直接调用数据库,而是通过客户端调用云函数,元函数调用数据库的形式

    数据库和集合的引用:

      const db=uniCloud.database();
      const ban=db.collection('集合名');//集合名就是数据表的名称
      db.createCollection(collectionName)//创建集合
    

    数据库的增删改查

      const db=uniCloud.database();
      const ban=db.collection('集合名');
      
      ban.get().then(res=>{
      console.log(res)
      }).catch(msg=>{
      console.log(msg)
      });
      //获取集合中的数据,promise写法
      
      ban.get({sucess:(res)=>{
      console.log(res)
      },
      fail:(msg)=>{
      console.log(msg)
      }
      });
      //第二种写法
      //这里只简单的介绍,详细的可查看 官方文档
      ban.where({
        name:"查询的name",
        index:查询的下标等  
      }).get().then(res=>{
      console.log(res)
      }).catch(e=>{
      console.log(msg)
      });
      
      //添加
      ban.add({
        data:{
            id:要添加的id,
            name:要添加的name
        }
      }).then(res=>{
      console.log(res)
      }).catch(e=>{
      console.log(msg)
      });
      
    //更新
      ban.doc('id').update({
        data:{
          name:'要替换的属性名'
        }
      }).then(res=>{
      console.log(res)
      }).catch(e=>{
      console.log(msg)
      });
      
      ban.doc('id').set({
        data:{
          name:'要替换的属性名',
          id:要替换的id名
        }
      }).then(res=>{console.log(res)}).catch(e=>{console.log(msg)});
      
    //删除数据,只能每次删除一条
      ban.doc('id').remove({ }).then(res=>{
      console.log(res)
      }).catch(e=>{
      console.log(msg)
      });
    

    云存储:uploadFile(Object object)

    uni.chooseImage({
     count: 1,
     success: (res) => {
      console.log(res);
      var path=res.tempFilePaths[0];//获取当前图片的路径
      uniCloud.uploadFile({
       filePath: path, // 当前图片路径
       cloudPath: 'img', // 文件名
       success: (res1) => {
        console.log(res1);
       }
      })
     }
    })
    
    // promise写法
    const result = await uniClound.uploadFile({
     filePath: filePath
    });
    

    deleteFile(Object object) 删除云端文件

      // promise写法
    uniCloud
      .deleteFile({
        fileList: ['云储存的ID'];//字符串类型的数组
      })
      .then(res => {});
    
    // callback写法
    uniCloud.deleteFile(
      {
        fileList: ['云储存的ID'],
        success(){},
        fail(){},
        complete(){}
      }
    );
    

    客户端调用云函数:

      //index.js云函数文件
      'use strict'; 
      uniCloud.init();
      
      const db=uniCloud.database();
      exports.main = async (event, context) => {
        return new Promise((resolve,reject)=>{
        db.collection('banner').get().then(res=>{
            resolve(res);
        }).catch(msg=>{
            reject(msg);
        })
      })
    };
    
      onLoad() {
              uniCloud.callFunction({//客户端调用云函数,云函数调用数据库
                  name:'index',
                  success:(res)=> {
                      console.log(res);
                      var ban=res.result.data[0].banner;
                      console.log(ban);
                  }
              })
      },
    

    uni-app使用微信小程序云函数的步骤

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pjvvk2Ps-1608288184261)(https://ask8088-private-1251520898.cn-south.myqcloud.com/developer-images/article/1435798/rgc2ip4hr1.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1608280202;1608287402&q-key-time=1608280202;1608287402&q-header-list=&q-url-param-list=&q-signature=6c56359dd6766739d405b78df9588f34cd62e8ae)]

    修改manifest.json

    "mp-weixin" : {
            /* 小程序特有相关 */
            "appid" : "4555xxxxxxxx",
            "cloudfunctionRoot": "./functions/", 
            "setting" : {
                "urlCheck" : false
            },
            "usingComponents" : true
        }
    

    安装copy-webpack-plugin插件

    npm install -save copy-webpack-plugin;
    

    讲列表索引:

    <view wx:for="{{newstitle}}" wx:key="*this">
      {{item}}
    </view>
    

    其中

    *this表示在for循环中的item本身,而{{item}}的item是默认的。
    
    <view wx:for-items="{{newstitle}}" wx:for-item="title" wx:key="*this">
      {{title}}
    </view>
    
    1. block并不是一个组件,只是一个包装元素,不会在页面中做任何渲染,只接受控制属性
    !0  // 返回true
    !true  // 返回false
    !false  // 返回true
    !''  // 返回true
    !'yes'  // 返回false
    !["ok"] // 返回false
    !{} // 返回false
    !!true   // 返回true
    !!{}     // 返回true,
    !!false  // 返回false
    !!""     // 返回false
    

    hidden属性:

    <view wx:if="{{false}}">组件不显示不渲染</view>
    <view hidden="{{true}}">组件不显示</view>
    <view hidden>组件不显示</view>
    <view hidden="{{false}}">组件显示</view>
    

    audio组件,是音频组件:

    • src:要播放音频的资源地址
    • poster:默认控件上的音频封面的图片资源地址
    • name:默认控件上的音频名字
    • author:默认控件上的作者名字

    video组件,是表示视频的组件:

    • autoplay:是否自动播放
    • loop:是否循环播放
    • muted:是否静音播放
    • inital-time:指定视频初始播放位置,单位是秒
    • controls:是否显示默认播放控件

    地图:

    <map
      id="myMap"
      style=" 100%; height: 300px;"
      latitude="{{latitude}}"
      longitude="{{longitude}}"
      markers="{{markers}}"
      covers="{{covers}}"
      show-location
    ></map>
    
    latitude: 2xxx.5xxxx3,
    longitude: 1xx.xxx28,
    markers: [{
      id: 1,
      latitude: xxx2.5xxxxx,
      longitude: 1xxx.xxx28,
      title: '深圳xxx'
    }],
    
    在地图上标记多个点
    
    markers: [{
      id: 1,
      latitude: xxx2.5xxxxx,
      longitude: 1xxx.xxx28,
      title: '深圳xxx'
      },
      {...
    
    1. callout:点击marker出现气泡callout、以及气泡上的label
    2. circle:在地图上显示圆,比如用于显示方圆几公里
    3. polygon:指定一系列坐标点,比如圈出实际的范围
    4. polyline:指定一系列坐标点,比如跑步的路线

    转发功能:

    onShareAppMessage: function (res) {
      if (res.from === 'button') {
        console.log(res.target)
      }
      return {
        title: '云开发',
        path: "pages/home/home",
        imageUrl:"https://happ.jpg",
        success: function (res) {
            // 转发成功
        },
        fail: function (res) {
            // 转发失败
        }
      }
    },
    

    自定义顶部导航栏

    "window":{
      "navigationStyle":"custom"
    }
    

    小程序的客服

    <button open-type="contact"></button>
    

    web-view承载网页的容器。

    <web-view src="https://mp. zxxx"></web-view>
    

    获取用户信息

    <button open-type="getUserInfo">弹出授权弹窗</button>
    

    消息弹框

      wx.showToast({
        title: '成功',
        icon: 'success',
        duration: 2000
      })
      
      title
      icon:只有三个选项,success、loading、none
      duration:提示延迟的时间 1.5秒
    

    弹出模态对话框

      wx.showModal({
        title: '学习',
        content: '学习',
        showCancel: true,
        confirmText: '确定',
        success(res) {
          if (res.confirm) {
            console.log('用户点击了确定')
          } else if (res.cancel) {
            console.log('用户点击了取消')
          }
        }
      })
      
      title属性不是必填
      content属性也不是必填
      showCancel默认值就是true
      confirmText默认值为确定
    

    手机振动

    手机振动API分两种,一种是长振动,一种是短振动

      wx.vibrateLong({
        success(res) {
          console.log(res)
        },
        fail(err) {
          console.error(err)
        },
        complete() {
          console.log('振动完成')
        }
      })
    

    弹出操作菜单

      wx.showActionSheet({
        itemList: ['1', '2', '3', '4'],
        success(e) {
          console.log(e.tapIndex)
        }
      })
    

    页面路由

    redirectTo 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
    navigateTo 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面
    
    navigateBack 关闭当前页面,返回上一页面或多级页面。
    
    switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
    reLaunch 关闭所有页面,打开到应用内的某个页面
    

    生命周期

    App() 必须在 app.js 中调用,必须调用且只能调用一次

    App({
      onLaunch: function (options) { //监听小程序初始化
      },
      onShow:function(options){      //监听小程序启动或切前台
      },
      onHide:function(){      //监听小程序切后台
      },
      onError:function(msg){     //错误监听函数     
      },
      onPageNotFound:function(){ //页面不存在监听函数
      },
      onUnhandledRejection:function(){//未处理的 Promise 拒绝事件监听函数   
      },
      onThemeChange:function(){//监听系统主题变化
      }
    })
    

    页面的生命周期函数:

    Page({
      data: {//页面的初始数据
      },
      onLoad: function(options) {//监听页面加载
      },
      onShow: function() {//监听页面显示
      },
      onReady: function() {//监听页面初次渲染完成
      },
      onHide: function() {//监听页面隐藏
      },
      onUnload: function() {//监听页面卸载
      },
      onPullDownRefresh: function() {//监听用户下拉动作
      },
      onReachBottom: function() {//页面上拉触底事件的处理函数
      },
      onShareAppMessage: function () {//用户点击右上角转发
      },
      onPageScroll: function() {//页面滚动触发事件的处理函数
      },
      onResize: function() {//页面尺寸改变时触发
      },
      onTabItemTap:function(){//当前是 tab 页时,点击 tab 时触发
      }
    })
    

    onLaunch与onShow

    onLaunch是监听小程序的初始化,初始化完成时触发,全局只会触发一次

    onShow是在小程序启动,或从后台进入前台显示时触发,也就是它会触发很多次

    正在加载中

    App({
      onLaunch: function () {
        wx.showLoading({
          title: "正在加载中",
        })
      },
      globalData: {
    
      }
    })
    
    App({
      onLaunch: function () {
        wx.showLoading({
          title: "正在加载中",
        })
      },
      onShow (options) {
        wx.hideLoading({
          success: (res) => {
            console.log("加载完成,所以隐藏掉了")
          },
        })
      },
      globalData: {
    
      }
    })
    

    小程序打开场景值

    App({
      onLaunch: function (options) {
        console.log('打印小程序启动时的参数',options)
      },
    })
    
    path: "" //页面路径
    query: {} //页面的参数
    referrerInfo: {} //来源小程序、公众号或 App 的 appId
    scene: 1047 //场景值
    shareTicket: //带 shareTicket 的转发可以获取到更多的转发信息,例如群聊的名称以及群的标识 openGId
    

    了解wx.login、wx.getSetting

    App({
      onLaunch: function () {
        wx.login({
          success(res){
            console.log('wx.login得到的数据',res)
          }
        })
     
        wx.getSetting({
          success(res){
            console.log('wx.getSetting得到的数据',res)
          }
        })
      },
     
      globalData: {
        userInfo: null
      }
    })
    

    获取用户信息wx.getUserInfo

    首先需要判断用户是否允许

    wx.getSetting({
      success(res){
        console.log('wx.getSetting得到的数据',res)
        if (res.authSetting["scope.userInfo"]){
          wx.getUserInfo({
            success(res){
              console.log("wx.getUserInfo得到的数据",res)
            }
          })
        }
      }
    })
    

    UserInfo

    用户信息

    属性

    string nickName

    用户昵称

    string avatarUrl

    用户头像图片的 URL。

    number gender

    用户性别

    string country

    用户所在国家

    string province

    用户所在省份

    string city

    用户所在城市

    string language

    显示 country,province,city 所用的语言

    globalData

    wx.getUserInfo({
      success(res){
        console.log("wx.getUserInfo得到的数据",res)
        this.globalData.userInfo = res.userInfo
      }
    })
    

    Promise调用方式

    wx.getNetworkType() 
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.log(err)
      })
    

    云函数入门

    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV, 
    })
    exports.main = async (event, context) => {
      const sum = event.a + event.b
      return sum
    }
    

    云函数的调用

    wx.cloud.callFunction({
      name: 'sum',    
      data: {        
        a: 15,
        b: 23,
      }
    }).then(res => {
      console.log("云函数返回的结果",res)
    }).catch(err => {
      console.log("云函数调用失败",err)
    })
    

    wx-server-sdk是微信小程序服务器端的SDK

    SDK包括用于微信免鉴权的私有协议、云数据库、云存储、云调用等基础能力,因此每一个云函数都会使用到wx-server-sdk这个Node包。

    云函数的初始化

    const cloud = require('wx-server-sdk')
    cloud.init({
      env: 'x' //换成你的云函数envId
    })
    
    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV //注意它不是字符串,不要加引号
    })
    cloud.DYNAMIC_CURRENT_ENV标志的是云函数当前所在的环境
    
    const cloud = require('wx-server-sdk')
    cloud.init({
      env:cloud.DYNAMIC_CURRENT_ENV 
    })
    exports.main = async (event, context) => {
      const {width,height} = event
      console.log("长方形的周长与面积",[(width+height)*2,width*height])
      return {
        circum:(width+height)*2,
        area:width*height
      }
    }
    

    云数据库入门

    wx.cloud.database().collection('集合名').where({
      _id:'记录的id'
    }).update({
      "字段名":"字段值"
    })
    

    wx.chooseImage()

    <button bindtap="chooseImg">选择图片</button>
    <image mode="widthFix" src="{{imgurl}}"></image>
    <view>上传的图片</view>
    
    chooseImg:function(){
      const that=this
      wx.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success(res) {
          const imgurl = res.tempFilePaths
          that.setData({
            imgurl
          })
        }
      })
    },
    

    count:可以选择的照片数量,默认为9张

    sourceType:选择图片的来源,album就是图片可以来自手机相册;而camera是可以来自手机拍照

    sizeType

    所选的图片的尺寸,original为原图,compressed为压缩图

    tempFilePaths为临时文件的路径列表tempFiles为临时文件列表

    image组件有默认宽度300px、高度225px

    上传多张照片

    data: {
        imgurl:[],
    },
    <view wx:for-items="{{imgurl}}" wx:for-item="item" wx:key="*this">
      <image mode="widthFix" src="{{item}}"></image>
    </view>
    

    获取图片信息

    wx.getImageInfo()
    
    chooseImg:function(){
      let that=this
      wx.chooseImage({
        count: 9,
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success(res) {
          const imgurl = res.tempFilePaths
          console.log('chooseImage回调打印的res',res)
          that.setData({
            imgurl
          })
          wx.getImageInfo({
            src: res.tempFilePaths[0],
            success(res){
              console.log('getImageInfo回调打印的res',res)
            }
          })
        }
      })
    },
    

    wx.previewImage()预览

    previewImg:function(){
      wx.previewImage({
        current: '',
        urls: this.data.imgurl,
      })
    },
    

    保存图片到相册

    saveImg:function(e){
      wx.saveImageToPhotosAlbum({
        filePath: "/images/xx.jpg",
        success(res) { 
          wx.showToast({
            title: '保存成功',
          })
        }
      })
    }
    

    压缩图片

    wx.compressImage()

    上传文件

    chooseFile: function () {
      let that = this
      wx.chooseMessageFile({
        count: 5,
        type: 'file',
        success(res) {
          console.log('上传文件的回调函数返回值',res)
        }
      })
    },
    

    上传地理位置

    chooseLocation: function () {
      let that= this
      wx.chooseLocation({
        success: function(res) {
          const location=res
          that.setData({
            location
          })
        },
        fail:function(res){
          console.log("获取位置失败")
        }
      })
    },
    
    <map style=" 100%; height: 300px;"
      latitude="{{location.latitude}}"
      longitude="{{location.longitude}}"
      show-location
    ></map>
    

    下载文件

    downloadFile(){
      const that = this
      wx.downloadFile({
        url: 'https://h.jpg',
        success (res) {
          console.log("成功回调之后的res对象",res)
          if (res.statusCode === 200) {//如果网络请求成功
            that.setData({
              downloadFile:res.tempFilePath
            })
          }
        }
      })
    },
    
    downloadFile(){
      const downloadTask = wx.downloadFile({
        url: 'https://xxx.jpg', 
        success (res) {
          if (res.statusCode === 200) {
            that.setData({
              downloadFile:res.tempFilePath
            })
          }
        }
      })
    
      downloadTask.onProgressUpdate((res) => {
        console.log('下载进度', res.progress)
        console.log('已经下载的数据长度', res.totalBytesWritten)
        console.log('预期需要下载的数据总长度', res.totalBytesExpectedToWrite)
      })
    },
    

    预览文档wx.openDocument()

    openDoc(){
      wx.downloadFile({
        url: 'https://x1.pdf', 
        success (res) {
          console.log("成功回调之后的res对象",res)
          if (res.statusCode === 200) {
            wx.openDocument({
              filePath: res.tempFilePath,
              success: function (res) {
                console.log('打开文档成功')
              },
              fail:function(err){
                console.log(err)
              }
            })
          }
        }
      })
    },
    

    保存文件与文件缓存wx.saveFile

    保存文件则是把图片由临时文件移动到本地存储里

    先调用wx.downloadFile再调用wx.saveFile将文件缓存的路径存储到页面的data对象

    调用wx.openDocument打开这个路径

    downloadPDF(){
      const that = this
      wx.downloadFile({
        url: 'https://xx.pdf', 
        success (res) {
          console.log("成功回调之后的res对象",res)
          if (res.statusCode === 200) {
            wx.saveFile({
              tempFilePath: res.tempFilePath,
              success (res) {
                console.log(res)
                that.setData({
                  savedFilePath:res.savedFilePath
                })
    
              }
            })
          }
        }
      })
    },
    
    openPDF(){
      const that = this
      wx.openDocument({
        filePath:that.data.savedFilePath,
        success: function (res) {
          console.log('打开文档成功')
        },
        fail:function(err){
          console.log(err)
        }
      })
    }
    

    获取已保存的缓存文件列表

    wx.getSavedFileList({
      success (res) {
        console.log(res.fileList)
      }
    })
    

    获取缓存文件的信息

    获取临时文件的信息,使用的是wx.getFileInfo

    获取缓存文件调用的信息,使用的则是wx.getSavedFileInfo

    wx.getSavedFileInfo({
      filePath:"http://.pdf",//这是缓存文件的路径
      success(res){
        console.log(res)
      }
    })
    

    文件管理器

    wx.getFileSystemManager()来获取全局唯一的文件管理器

    const fs =  wx.getFileSystemManager()
    

    文件管理器主要管理的就是wx.env.USER_DATA_PATH目录里的文件

    const fs =  wx.getFileSystemManager()
    
    //创建一个文件夹
    fs.mkdir({
      dirPath:wx.env.USER_DATA_PATH+"/cloudbase",
      success(res){
        console.log(res)
      },
      fail(err){
        console.log(err)
      }            
    })
    
    //读取文件夹下有哪些文件,会返回文件夹内文件列表
    fs.readdir({
      dirPath:wx.env.USER_DATA_PATH,
      success(res){
        console.log(res)
      },
      fail(err){
        console.log(err)
      }  
    })
    
    //新建一个文本文件test,并往文件里写入数据
    fs.writeFile({
      filePath:wx.env.USER_DATA_PATH+"/cloudbase"+"/test",
      data:"dadaqianduan.cn",
      encoding:"utf8",
      success(res){
        console.log(res)
      }
    })
    
    //新增一些内容
    fs.appendFile({
      filePath:wx.env.USER_DATA_PATH+"/cloudbase"+"/test",
      data:"dadaqianduan.cn 达达前端",
      encoding:"utf8",
      success(res){
        console.log(res)
      }
    })
    
    //读取test文本文件里的内容
    fs.readFile({
      filePath:wx.env.USER_DATA_PATH+"/cloudbase"+"/test",
      encoding:"utf-8",
      success(res){
        console.log(res)
      }
    })
    
    chooseImage:function() {
      const that = this
      wx.chooseImage({
        count: 1,
        success(res) {
          that.setData({
            tempFilePath: res.tempFilePaths[0]
          })
        }
      })
    },
    saveImage:function() {
      const that = this
      wx.saveFile({
        tempFilePath: this.data.tempFilePath,
        success(res) {
          that.setData({
            savedFilePath: res.savedFilePath
          })
          wx.setStorageSync('savedFilePath', res.savedFilePath)
        },
      })
    },
    
    onLoad: function (options) {
      this.setData({
        savedFilePath: wx.getStorageSync('savedFilePath')
      })
    },
    

    模块化与引入模块

    const formatTime = date => {
      const year = date.getFullYear()  //获取年
      const month = date.getMonth() + 1  //获取月份,月份数值需加1
      const day = date.getDate()  //获取一月中的某一天
      const hour = date.getHours() //获取小时
      const minute = date.getMinutes()  //获取分钟
      const second = date.getSeconds() //获取秒
     
      return [year, month, day].map(formatNumber).join('/') + ' ' +
       [hour, minute, second].map(formatNumber).join(':') 
    }
     
    const formatNumber = n => {  //格式化数字
      n = n.toString()
      return n[1] ? n : '0' + n 
    }
     
    module.exports = { 
      formatTime: formatTime,
      formatNumber: formatNumber
    }
    
    const util = require('../../utils/util.js')
    

    微信支付

    绑定微信支付商户号

    callPay(){
      wx.cloud.callFunction({
        name: 'pay',
        success: res => {
          console.log(res)
          const payment = res.result.payment
          wx.requestPayment({
            ...payment,
            success (res) {
              console.log('支付成功', res) 
            },
            fail (err) {
              console.error('支付失败', err) 
            }
          })
        },
        fail: console.error,
      })
    },
    

    pay云函数

    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV
    })
    
    exports.main = async (event, context) => {
      const res = await cloud.cloudPay.unifiedOrder({
        "body": "zzzzz",
        "outTradeNo" : "1xxxxxxxxxx", //不能重复,否则报错
        "spbillCreateIp" : "127.0.0.1", //就是这个值,不要改
        "subMchId" : "xxxxxxxxxxx",  //你的商户ID或子商户ID
        "totalFee" : 100,  //单位为分
        "envId": "xxxxxxxx",  //你的云开发环境ID
        "functionName": "paysuc",
        "nonceStr":"fffffffffffffff",  //随便弄的32位字符串,建议自己生成
        "tradeType":"JSAPI"   //默认是JSAPI
      })
      return res
    }
    

    调用cloudPay.queryOrder()来查询订单的支付状态

    调用cloudPay.refund()来对已经支付成功的订单发起退款

    新建一个queryorder的云函数

    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV,
    })
    exports.main = async(event, context) => {
      const res = await cloud.cloudPay.queryOrder({
        "sub_mch_id":"xxxxxxxx",
        "out_trade_no":"xxxxxxxxx", //商户订单号,需是云支付成功交易的订单号
        // "transaction_id":"xxxxxxxxxxxxxxxxxxxxx",  //微信订单号可以不必写
        "nonce_str":"xxxxxxxxxxxxxxxxxxxxxxx" //任意的32位字符
      })
      return res
    }
    
    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV,
    })
    exports.main = async(event, context) => {
      const res = await cloud.cloudPay.refund({
        "sub_mch_id":"xxxxxxxxxx",
        "nonce_str":"xxxxxxxxxxxxxxxx",
        "out_trade_no":"xxxxxxxxxxxxxx",//商户订单号,需是云支付成功交易的订单号
        "out_refund_no":"xxxxxxxxxxxxxx",//退款单号,可以自定义,建议与订单号相关联
        "total_fee":100,
        "refund_fee":20,
      })
      return res
    }
    

    在这里插入图片描述

    发订阅消息,需要调用接口wx.requestSubscribeMessage

    callPay(){
      wx.cloud.callFunction({
        name: 'pay', 
        success: res => {
          console.log(res)
          const payment = res.result.payment
          wx.requestPayment({
            ...payment,
            success (res) {
              console.log('支付成功', res) 
              this.subscribeMessage()
            },
          })
        },
      })
    },
    subscribeMessage() {
      wx.requestSubscribeMessage({
        tmplIds: [
          "xxxxxx-xx-x",//订阅消息模板ID
        ],
        success(res) {
          console.log("订阅消息API调用成功:",res)
        },
        fail(res) {
          console.log("订阅消息API调用失败:",res)
        }
      })
    },
    

    自动回复文本消息和链接

    <button open-type="contact" >进入客服</button>
    
    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV,
    })
    exports.main = async (event, context) => {
      const wxContext = cloud.getWXContext() 
      try {
        const result = await cloud.openapi.customerServiceMessage.send({
          touser: wxContext.OPENID,
          msgtype: 'text',
          text: {
            content: 'xxxxxxx'
          }
        })
        
        const result2 = await cloud.openapi.customerServiceMessage.send({
          touser: wxContext.OPENID,
          msgtype: 'text',
          text: {
            content: 'xxxxx'
          }
        }) 
    
        return event    
      } catch (err) {
        console.log(err)
        return err
      }
    }
    

    自动回复链接

    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV,
    })
    exports.main = async (event, context) => {
      const wxContext = cloud.getWXContext() 
      try {
        const result = await cloud.openapi.customerServiceMessage.send({
          touser: wxContext.OPENID,
          msgtype: 'link',
          link: {
            title: 'xxxxxxx',
            description: 'xxxxxx',
            url: 'https://xxxxxxx根据关键词来回复用户t.com/',
            thumbUrl: 'https://xxxxxxxm/love.png'
          }
        }) 
      return event    
    
      } catch (err) {
        console.log(err)
        return err
      }
    }
    

    根据关键词来回复用户

    const cloud = require('wx-server-sdk')
    cloud.init({
      env: cloud.DYNAMIC_CURRENT_ENV,
    })
    exports.main = async (event, context) => {
      const wxContext = cloud.getWXContext() 
      const keyword = event.Content
      try {
        if(keyword.search(/xxxx/i)!=-1){
          const result = await cloud.openapi.customerServiceMessage.send({
            touser: wxContext.OPENID,
            msgtype: 'link',
            link: {
              title: 'xxxxx',
              description: 'xxxxx',
              url: 'https://xxx.com/',
              thumbUrl: 'https://xxxx.png'
            }
          })  
        } 
        return event
      } catch (err) {
        console.log(err)
        return err
      }
    }
    

    获取微信步数

    getWeRunData(){
      wx.getWeRunData({
        success: (result) => {
          console.log(result)
        },
      })
    }
    

    订阅消息

    subscribeMessage() {
      wx.requestSubscribeMessage({
        tmplIds: [
          "xxxxxxxxxxxx",//模板
          "xxxxxxxxxxxx",
          "xxxxxxxxxx
        ],
        success(res) {
          console.log("订阅消息API调用成功:",res)
        },
        fail(res) {
          console.log("订阅消息API调用失败:",res)
        }
      })
    },
    

    云开发登陆

    检查是否登录

    <script>
    	global.isLogin = function() {
    		try {
    			var openid = uni.getStorageSync('openid');
    		} catch (e) {
    
    		}
    		if (openid === '') {
    			return false
    		} else {
    			return {
    				openid
    			}
    		}
    	};
    	export default {
    		onLaunch: function() {
    			console.log('App Launch')
    			wx.cloud.init({
    				traceUser: true
    			});
    		}
    	}
    </script>
    

    登陆页面

    <template>
    	<view>
    		<!-- #ifdef MP-WEIXIN -->
    		<button class='bottom' type='primary' open-type="getUserInfo"
    		 withCredentials="true" lang="zh_CN" @getuserinfo="wxGetUserInfo">
    			授权登录
    		</button>
    		<!-- #endif -->
    	</view>
    </template>
    <script>
    	const db = wx.cloud.database();
    	export default {
    		data() {
    			return {}
    		},
    		methods: {
    			wxGetUserInfo(msg) {
    				console.log(msg)
    				
    				var that = this;
    				if (!msg.detail.iv) {
    					uni.showToast({
    						title: '您取消了授权,登录失败',
    						icon: 'none'
    					});
    					return false
    				}
    				
    				uni.showLoading({
    				    title: '加载中'
    				});
    				
    				uni.login({
    					provider: 'weixin',
    					success: function(loginRes) {
    					
    						console.log(loginRes)
    						that.getOpenid(msg);
    					},
    					fail: function(r) {
    						console.log(r)
    					}
    				})
    				
    			},
    			getOpenid(msg) {
    				var that = this;
    				
    				wx.cloud.callFunction({
    					name: 'getOpenid',
    					complete: res => {
    						console.log('openid: ', res);
    						try {
    							uni.setStorageSync('openid', res.result.openId);
    						} catch (e) {
    						}
    						that.saveToDb(msg, res.result.openId)
    					},
    				});
    				
    			},
    			
    			saveToDb(msg, openid) {
    				console.log(openid)
    				
    				db.collection('user').where({
    					_openid: openid
    				}).get().then(res => {
    				
    					console.log(res)
    					
    					if (res.errMsg === 'collection.get:ok') {
    					
    						if (res.data.length === 0) {
    							db.collection('user').add({
    								data: {
    									...msg.detail.userInfo,
    									_openid: res.result.openId
    								}
    							}).then(res => {
    								console.log(res);
    							});
    						}
    						
    						uni.hideLoading();
    						
    						uni.showToast({
    							title: '授权成功',
    							icon: 'success'
    						});
    						
    						setTimeout(() => {
    							uni.navigateBack();
    						}, 1500);
    					} else {}
    				})
    
    			}
    		},
    		onLoad() {
    
    		}
    	}
    </script>
    

    总结

    以上就是今天要讲的内容,本文仅仅简单介绍了小程序开发-云开发技术总结,感谢阅读,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友。感谢转发分享,点赞,收藏哦!

  • 相关阅读:
    Steal 偷天换日 题解(From luoguBlog)
    Hibernat之关系的处理多对多
    Hibernat之关系的处理一对一处理
    Hibernat之关系的处理一对多/多对一
    Hibernate 一对多注解 mappedby 作用
    hibernate之使用Annotation注解搭建项目
    暑假学习第八周
    暑假学习第七周
    java学习第六周
    暑假学习第五周
  • 原文地址:https://www.cnblogs.com/dashucoding/p/14186059.html
Copyright © 2011-2022 走看看