微信小程序云开发之云数据库入门

微信小程序云开发之云数据库入门

介绍

开发者可以使用云开发开发微信小程序、小游戏,无需搭建服务器,即可使用云端能力。
其基础能力数据库,是一个JSON数据库,作用是无需自建数据库,就可以在微信小程序前端操作数据库,也能在云函数中读写数据库。

前置条件

  • 在新建项目是一定要勾选开启云服务
  • 在微信开发者工具中点击云开发构建集合。
    微信小程序云开发之云数据库入门

注意事项

数据库 API 分为小程序端和服务端两部分,小程序端 API 拥有严格的调用权限控制,开发者可在小程序内直接调用 API 进行非敏感数据的操作。对于有更高安全要求的数据,可在云函数内通过服务端 API 进行操作。云函数的环境是与客户端完全隔离的,在云函数上可以私密且安全的操作数据库。

简言之:读写数据权限方面,微信小程序最低,云函数和云数据库一样高。

如果我们需要给予小程序相应权限,也是有办法的。我们可以在云开发控制台中设置微信小程序读取权限来达到自身项目的需求。
微信小程序云开发之云数据库入门

实例

该实例包含数据库开发全过程,涉及链接 获取集合 增删改查 检索,新建好名称为user的集合就能运行,供大家借鉴参考。(增删改查权限如果云开发控制台没有设置,有可能报错,设置一下即可)

废话不说,源码献上

demo.wxml


<!--index.wxml-->
<view class="container">
  <!-- 用户 openid -->
  <view class="userinfo">
    <button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo" class="userinfo-avatar" style="background-image: url({{avatarUrl}})" size="default"></button>
    <view class="userinfo-nickname-wrapper">
      <button class="userinfo-nickname" bindtap="onGetOpenid">点击获取 openid</button>
    </view>
  </view>
  <!-- 增加数据 -->
  <view class="uploader">
    <view bindtap="addData" class="uploader-text">
      <text>增加数据</text>
    </view>
    <view class="page-body">
      <form catchsubmit="formSubmit" catchreset="formReset" hidden="{{isFormHidden}}">
        <!-- 开关
          <view class="page-section page-section-gap">
            <view class="page-section-title">switch</view>
            <switch name="switch" />
          </view> -->
        <!-- <view class="section">
          <view class="section__title">性别</view>
          <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
            <view class="picker">
              性别: {{array[index]}}
            </view>
          </picker>
        </view> -->
        <!-- 单选
          <view class="page-section page-section-gap">
            <view class="page-section-title">radio</view>
            <radio-group name="radio">
              <label>
                <radio value="radio1" />选项一</label>
              <label>
                <radio value="radio2" />选项二</label>
            </radio-group>
          </view> -->
        <!-- 多选
          <view class="page-section page-section-gap">
            <view class="page-section-title">checkbox</view>
            <checkbox-group name="checkbox">
              <label>
                <checkbox value="checkbox1" />选项一</label>
              <label>
                <checkbox value="checkbox2" />选项二</label>
            </checkbox-group>
          </view> -->
        <!-- 滑动选择
          <view class="page-section page-section-gap">
            <view class="page-section-title">slider</view>
            <slider value="50" name="slider" show-value></slider>
          </view> -->
        <!-- 输入框 -->
        <view class="page-section">
          <view class="page-section-title">
            <input class="weui-input" name="userName" placeholder="请输入用户名称" />
          </view>
        </view>
        <!-- 输入框 -->
        <view class="page-section">
          <view class="page-section-title">
            <input class="weui-input" name="itCard" placeholder="请输入昵称" />
          </view>
        </view>
        <!-- 输入框 -->
        <view class="page-section">
          <view class="page-section-title">
            <input class="weui-input" name="phone" placeholder="请输入电话" />
          </view>
        </view>
        <!-- 输入框 -->
        <view class="page-section">
          <view class="page-section-title">
            <input class="weui-input" name="email" placeholder="请输入邮箱" />
          </view>
        </view>
        <!-- 提交 -->
        <view class="btn-area">
          <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">提交</button>
          <button style="margin: 30rpx 0" type="primary" formType="submit">Submit</button>
          <button style="margin: 30rpx 0" formType="reset">Reset</button>
        </view>
      </form>
    </view>
  </view>
  <!-- 查看数据 -->
  <view class="uploader">
    <view bindtap="seeData" class="uploader-text">
      <text>查看数据</text>
    </view>
    <view class="uploader-text" wx:for="{{user}}" wx:key="key">
      <text>{{item.userName}}</text>
    </view>
  </view>
  <!-- 修改数据 -->
  <view class="uploader">
    <view bindtap="updata" class="uploader-text">
      <text>修改数据</text>
    </view>
    <view class="page-body">
      <form catchsubmit="updatasubmit" catchreset="updatareset" hidden="{{isupdataform}}">
        <view class="btn-area">
          <input name="userName" placeholder="重新输入姓名"></input>
        </view>
        <view class="btn-area">
          <button style="margin:30rpx 0" type="primary" formType="submit">更新</button>
          <button style="margin:30rpx 0" type="warn" formType="reset">重置</button>
        </view>
      </form>
    </view>
  </view>
  <!-- 删除数据 -->
  <view class="uploader">
    <view bindtap="deleteData" class="uploader-text">
      <text>删除最近一条数据</text>
    </view>
    <view class="uploader-text" wx:for="{{users}}" wx:key="key">
      <text>{{item.userName}}</text>
    </view>
  </view>
  
</view>

demo.js


//index.js
const app = getApp()

//获取数据库环境引用
const db = wx.cloud.database({
  env: "输入自己的数据库环境,也可不输入,不输入默认查找当前环境"
})

//链接数据库中的集合
const pave = db.collection("PavmentRecord")
const user = db.collection("user")

// util.js
//格式化日期,输出格式为y-m-d h m s
const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 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].map(formatNumber).join(‘:‘)   //返回年月日,时分秒
}

//转换int类型为string
const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : ‘0‘ + n
}


Page({
  data: {
    avatarUrl: ‘../../images/user-unlogin.png‘,
    userInfo: {},
    logged: false,
    takeSession: false,
    requestResult: ‘‘,
    isFormHidden: true,
    isupdataform: true,
    users: {},
    array: [‘男‘, ‘女‘],
    cloud: ‘‘
  },
  onShareAppMessage() {
    return {
      title: ‘picker-view‘,
      path: ‘page/component/pages/picker-view/picker-view‘
    }
  },
  onLoad: function () {
    if (!wx.cloud) {
      wx.redirectTo({
        url: ‘../chooseLib/chooseLib‘,
      })
      return
    }
    var that = this
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting[‘scope.userInfo‘]) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              that.setData({
                avatarUrl: res.userInfo.avatarUrl,
                userInfo: res.userInfo
              })
            }
          })
        }
      }
    })
  },
  bindPickerChange: function (e) {
    console.log(‘picker发送选择改变,携带值为‘, e.detail.value)
    this.setData({
      index: e.detail.value
    })
  },
  onGetUserInfo: function (e) {
    if (!this.data.logged && e.detail.userInfo) {
      this.setData({
        logged: true,
        avatarUrl: e.detail.userInfo.avatarUrl,
        userInfo: e.detail.userInfo
      })
    }
  },
  onGetOpenid: function () {
    // 调用云函数
    wx.cloud.callFunction({
      name: ‘login‘,
      data: {},
      success: res => {
        console.log(‘[云函数] [login] user openid: ‘, res.result.openid)
        app.globalData.openid = res.result.openid
        wx.navigateTo({
          url: ‘../userConsole/userConsole‘,
        })
      },
      fail: err => {
        console.error(‘[云函数] [login] 调用失败‘, err)
        wx.navigateTo({
          url: ‘../deployFunctions/deployFunctions‘,
        })
      }
    })
  },
  //增加数据
  addData: function () {
    this.setData({
      isFormHidden: false
    })
  },
  getPhoneNumber: function (e) {
    console.log(e)
  },
  //提交表单
  formSubmit(e) {
    const ur = e.detail.value;
    console.log("提交表单信息如下:")
    console.lot(ur)
    var date = formatTime(new Date());
    console.log(date)
    pave.add({
      data: {
        userName: ‘test‘,
        userPhone: ‘15239942334‘,
        diseaseName: "test",
        symCom: "test",
        recordTime: date,
        payMoney: 100.0
      },
    }).then(res => {
      console.log(res)
    }).catch(function (e) {
      console.log(e)
    })
  },
  //重置表单
  formReset(e) {
    console.log(‘form发生了reset事件,携带数据为:‘, e.detail.value)
    this.setData({
      chosen: ‘‘
    })
  },
  //查看数据
  seeData(e) {
    user.get().then(
      res => {
        console.log(res.data)
        this.setData({
          user: res.data
        })
      }
    )
  },
  //修改数据
  updata(e) {
    this.setData({
      isupdataform: false
    })
  },
  updatasubmit(e) {
  //查找user集合中id为以下数据的值,可以在e中获取,这里我简单写了一个。
    user.where({
      "_id": ‘dc277a235f081fc20009534043d370cc‘
    }).set({
      data: {
        "userName": e.data.userName
      },
      success: function (res) {
        console.log("更新成功:" + res)
      }
    })
  },
  updatareset(e) {
    this.setData({
      chosen: ‘‘
    })
  },
  deleteData(e) {
    var that
    wx.cloud.callFunction({
      name: ‘deleteData‘,
      data: {
        object: ‘user‘,
        id: ‘a7d38b365f0852c2000c0a3b0b7aae7a‘
      }
    }).then(res => {
      console.log(res)
      that = res.data
    })

  }
})


demo.wxss


/**index.wxss**/
page {
  background: #f6f6f6;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}
.userinfo, .uploader, .tunnel {
  margin-top: 40rpx;
  height: 140rpx;
  width: 100%;
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-left: none;
  border-right: none;
  display: flex;
  flex-direction: row;
  align-items: center;
  transition: all 300ms ease;
}
.userinfo {
  padding-left: 120rpx;
}
.userinfo-avatar {
  width: 100rpx;
  height: 100rpx;
  margin: 20rpx;
  border-radius: 50%;
  background-size: cover;
  background-color: white;
}
.userinfo-avatar[size] {
  width: 100rpx;
}
.userinfo-avatar:after {
  border: none;
}
.userinfo-nickname {
  font-size: 32rpx;
  color: #007aff;
  background-color: white;
  background-size: cover;
  text-align: left;
  padding-left: 0;
  margin-left: 10px;
}
.userinfo-nickname::after {
  border: none;
}
.userinfo-nickname-wrapper {
  flex: 1;
}
.uploader, .tunnel {
  height: auto;
  padding: 0 0 0 40rpx;
  flex-direction: column;
  align-items: flex-start;
  box-sizing: border-box;
}
.uploader-text, .tunnel-text {
  width: 100%;
  line-height: 52px;
  font-size: 34rpx;
  color: #007aff;
}
.uploader-container {
  width: 100%;
  height: 400rpx;
  padding: 20rpx 20rpx 20rpx 0;
  display: flex;
  align-content: center;
  justify-content: center;
  box-sizing: border-box;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.uploader-image {
  width: 100%;
  height: 360rpx;
}
.tunnel {
  padding: 0 0 0 40rpx;
}
.tunnel-text {
  position: relative;
  color: #222;
  display: flex;
  flex-direction: row;
  align-content: center;
  justify-content: space-between;
  box-sizing: border-box;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.tunnel-text:first-child {
  border-top: none;
}
.tunnel-switch {
  position: absolute;
  right: 20rpx;
  top: -2rpx;
}
.disable {
  color: #888;
}
.service {
  position: fixed;
  right: 40rpx;
  bottom: 40rpx;
  width: 140rpx;
  height: 140rpx;
  border-radius: 50%;
  background: linear-gradient(#007aff, #0063ce);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
  display: flex;
  align-content: center;
  justify-content: center;
  transition: all 300ms ease;
}
.service-button {
  position: absolute;
  top: 40rpx;
}
.service:active {
  box-shadow: none;
}
.request-text {
  padding: 20rpx 0;
  font-size: 24rpx;
  line-height: 36rpx;
  word-break: break-all;
}


demo.json


{
  "usingComponents": {},
  "navigationBarTitleText":"数据操作"
}


更多微信小程序相关查看我的程序员提升专栏,有需要请评论区留言。

微信小程序云开发之云数据库入门

上一篇:(用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正


下一篇:C#开发微信门户及应用(2)--微信消息的处理和应答