微信小程序布局、功能实现、常用组件、云开发汇总

1. 基础知识

小程序中,不需要主动来引入样式文件;
尺寸单位

rpx根据屏幕宽度进行自适应,规定所有屏幕宽为750rpx
在这里插入图片描述
以前用的px像素,最好改成rpx,百分比也可以;

在这里插入图片描述

1.1 框架介绍

微信小程序布局、功能实现、常用组件、云开发汇总_第1张图片

1.2 组件介绍

text相当于web的span标签,行内元素,不会换行;

view相当于web的div标签,块级元素、会换行;

checkbox就是以前的复选框标签,使用bool类型充当属性,checked

  • 字符串和花括号之间一定不要存在空格,否则会导致识别失败;

block,占位符的标签,写代码的时候可以看到这标签存在,页面渲染,小程序会把它移除掉;当循环某些数据,如果不想额外地加一层外边的标签,就用上block标签占位;


小程序中使用less,原生小程序不支持less

vscode+Easy Less

vscode设置中加入以下配置:

"less.compile":{
"outExt":	".wxss"
}

1.3 绑定数据

WXML页面里的动态数据,都是来自js文件Page的data,数据绑定就是通过双大括号{{}}将变量包起来,在WXML页面里将数据值显示出来;


快捷键
微信小程序布局、功能实现、常用组件、云开发汇总_第2张图片

1.3.1 组件属性绑定

微信小程序布局、功能实现、常用组件、云开发汇总_第3张图片
控制属性绑定
微信小程序布局、功能实现、常用组件、云开发汇总_第4张图片
关键字绑定
在这里插入图片描述

1.4 同步异步

一定要注意小程序中的异步问题,有的语句逻辑没问题,但是异步执行时达不到预期结果!

debug


小程序tabBar不显示的原因分析:

在微信小程序中启动页面一定要包含在tabBar中,并且启动页必须是tabBar的list属性中的第一个元素,才能正常显示,我就是没有把启动页面放进去,所以tabBar一直显示不出来;


value抓取的是字符串 我怎么转换成数字类型?

你要先判断value里面是不是全部为数字字符串,如果是则用parseInt()parseFloat()或者number()进行转换,汉字或者英文字母是没法转为数字类型的


微信小程序报错:Cannot read property ‘forceUpdate‘ of undefined
微信小程序布局、功能实现、常用组件、云开发汇总_第5张图片

2. 常用组件

2.1 image

  • image组件默认宽度320px、高度240px
  • 支持懒加载;
  • 小程序内使用的图片小于2M,所以最好用外网图片;
    微信小程序布局、功能实现、常用组件、云开发汇总_第6张图片
    scaleToFill强行裁剪,而aspectFit保持纵横比,完全显示长边;
    微信小程序布局、功能实现、常用组件、云开发汇总_第7张图片
    2,4常用,自己试了,没问题;

注意,top、bottom这些都是在box里面图片的位置;

小程序自动支持懒加载,就是滑到这里再加载lazy-load;图片懒加载,在即将进入一定范围(上下三屏)时才开始加载,默认false

2.2 swiper

swiper轮播图,滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为;

如何控制好轮播图的大小:

  • 得到原图大小:a像素 x b像素;

  • wxss设定

    swiper {
        width: 100%;
        height: calc(100vw*b/a);
    }
    
    image {
        width: 100%;
    }
    
  • 设定image根据宽度自适应调整

换机型也同比例变化!
微信小程序布局、功能实现、常用组件、云开发汇总_第8张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第9张图片

2.3 navigator

微信小程序布局、功能实现、常用组件、云开发汇总_第10张图片在这里插入图片描述
注意url要把里面的变成反斜杠/,并且page前加一个/,删除后缀;

轮播图页面

跳转到首页

微信小程序布局、功能实现、常用组件、云开发汇总_第11张图片

2.4 button

https://developers.weixin.qq.com/miniprogram/dev/component/button.html
微信小程序布局、功能实现、常用组件、云开发汇总_第12张图片
现在只有企业级小程序才能获取用户手机号!

实现获取用户信息:

getUserProfile方法:

<button class="login-bn" type='primary' size="mini" open-type="getUserProfile" bindtap='getUserProfile'> 
    <image src='/assets/images/me.png'>image>
    <text>\n授权登录text>
  button>
 getUserProfile: function (e) {
    wx.getUserProfile({
      desc: '业务需要',
      success: res => {
      	//拿到信息处理业务
      }
    })
  },

微信小程序布局、功能实现、常用组件、云开发汇总_第13张图片
实现联系客服,绑定客服后需要客户关注那个接收信息的公众号!

2.5 picker

picker滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器(mode=selector),时间选择器(mode=time),日期选择器(mode=date),默认是普通选择器。

微信小程序布局、功能实现、常用组件、云开发汇总_第14张图片
https://www.php.cn/xiaochengxu-404796.html
我的实现:选择距离范围

<view>
  <view>
    可签到范围
  view>
  <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
    <view>当前选择:{{array[index]}}view>
  picker>
view>
  data: {
    index: 0,
    array: ['50m', '100m', '200m', '500m'],
    },
  bindPickerChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
    index: e.detail.value
    })

在这里插入图片描述


起止时间设定

<view>
  <view>选择时间view>
  <picker mode="time" value="{{start_time}}" bindchange="bindStartTimeChange">
    <view>开始时间:{{start_time}}view>
  picker>
  <picker mode="time" value="{{end_time}}" bindchange="bindEndTimeChange">
    <view>结束时间:{{end_time}}view>
  picker>
view>
  data: {
    // 时间选择
    start_time: '07:00',
    end_time: '09:00'
  },
    // 起止时间确定函数
  bindStartTimeChange: function (e) {
    console.log("开始时间", e.detail.value);
    this.setData({
      start_time: e.detail.value
    })
  },
  bindEndTimeChange: function (e) {
    console.log("结束时间", e.detail.value);
    this.setData({
      end_time: e.detail.value
    })
  }

微信小程序布局、功能实现、常用组件、云开发汇总_第15张图片

2.6 radio

单项选择器组件
微信小程序布局、功能实现、常用组件、云开发汇总_第16张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第17张图片

2.7 form

就是把switch、picker、radio等组件封装起来,其实没什么很大的意义,可能我还不会用,暂时就感觉提交和重置有些用;
注意重置函数 formReset() 应该先 setData() 把数据都设置为初始值,然后 this.onLoad() 重新加载页面!

  formReset(e) {
    // console.log("重置",e.detail.value);
    this.setData({
      // 活动名
      name: "",
      // 距离范围
      index: 0,
      array: ['50m', '100m', '200m', '500m', '1000m'],
      distance: "50m",
      // 周期
      cycle: "",
      isOnce: true,
      //日期选择
      date: new Date().toLocaleDateString(),
      // 时间选择
      start_time: '07:00',
      end_time: '09:00',
      // 位置信息
      address: "",
      m_name: "",
      m_latitude: null,
      m_longitude: null,
    })
    this.onLoad()
  }

debug

想要通过 变量控制 隐藏/显示 某个按钮,必须把变量放在按钮所在的 view 里面,否则隐藏后,里面即使没有按钮,也会出现view框空着


3. 常用方法

3.1 wx:for


列表渲染wx:for

wx:for="{{数组或者对象}}" wx:for-item="循环项的名称" wx:for-item="循环项的索引"

<view>
    <view wx:for="{{list}}" wx:for-item="item" wx:for-index="index">
        索引:{{index}}->值:{{item.name}}
    view>
view>

wx:key="唯一值"来提高性能

wx:key绑定一个普通的字符串的时候,那么这个字符串名称,肯定是循环数组中的对象的唯一属性;

wx:key="*this"表示你的数组是一个普通数组,*this表示循环项,比如[1,2,3,44,5]或者['111',223,'ew ds ']

出现数组嵌套循环时,注意一下绑定的名称不要重名;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OK6s7jyf-1617103052486)(微信小程序功能.assets/image-20210323142858318.png)]

对象单层循环wx:for="{{数组或者对象}}",默认item表示对象的值;

最好把itemindex改成valuekey

Page({
  /**
   * 页面的初始数据
   */
  data: {
    msg:"hello world",
    person:{
      age:74,
      height:145,
      weight:200,
      name:"富婆"
    },
    isChecked:false,
    list:[
      {
        id:1,
        name:"猪八戒"
      },
      {
        id:2,
        name:"天蓬元帅"
      },
      {
        id:3,
        name:"悟能"
      }

    ]
  },
}
<view>
    <view wx:for="{{list}}">索引:{{index}}->值:{{item.name}}view>
    <view wx:for="{{person}}">{{index}}->{{item}}view>
view>

添加block标签后索引:{{index}}->值:{{item.name}}
微信小程序布局、功能实现、常用组件、云开发汇总_第18张图片

3.2 页面跳转

保留当前页面,跳转到应用内的某个页面

wx.navigateTo({
  url: 'index'
})

关闭当前页面,跳转到应用内的某个页面

wx.redirectTo({
   url: 'index'
})

关闭所有页面,打开到应用内的某个页面

wx.reLaunch({
  url: 'index'
})

跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

wx.switchTab({
  url: '/index'
})

3.3 wx.showxxxxx

wx.showToast 提示框 如果icon不设置为"none"则会显示对勾,表示成功;

wx.showToast({
         title: '失败',//提示文字
         duration:2000,//显示时长
         mask:true,//是否显示透明蒙层,防止触摸穿透,默认:false  
         icon:'success', //图标,支持"success"、"loading"  
         success:function(){ },//接口调用成功
         fail: function () { },  //接口调用失败的回调函数  
         complete: function () { } //接口调用结束的回调函数  
      })

wx.showModual提示框,有确定 取消 按钮的提示框,有标题和内容;

wx.showModal({
         title: '删除图片',
         content: '确定要删除该图片?',
         showCancel: true,//是否显示取消按钮
         cancelText:"否",//默认是“取消”
         cancelColor:'skyblue',//取消文字的颜色
         confirmText:"是",//默认是“确定”
         confirmColor: 'skyblue',//确定文字的颜色
         success: function (res) {
            if (res.cancel) {
               //点击取消,默认隐藏弹框
            } else {
               //点击确定
               temp.splice(index, 1),
               that.setData({
                  tempFilePaths: temp,
               })
            }
         },
         fail: function (res) { },//接口调用失败的回调函数
         complete: function (res) { },//接口调用结束的回调函数(调用成功、失败都会执行)
      })

wx.showLoading()
微信小程序布局、功能实现、常用组件、云开发汇总_第19张图片
注:wx.showLoading 应与 wx.hideLoading 配对使用

wx.hideLoading(Object object)
隐藏 loading 提示框

wx.showActionSheet(Object object)
显示操作菜单
微信小程序布局、功能实现、常用组件、云开发汇总_第20张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第21张图片

3.4 获取时间戳

Date.now()可以获取,但不是序列形式,就是这种1617246508998
详细的就是下面:

var myDate = new Date();

myDate.getYear();        //获取当前年份(2位)

myDate.getFullYear();    //获取完整的年份(4位,1970-????)

myDate.getMonth();       //获取当前月份(0-11,0代表1月)

myDate.getDate();        //获取当前日(1-31)

myDate.getDay();         //获取当前星期X(0-6,0代表星期天)

myDate.getTime();        //获取当前时间(从1970.1.1开始的毫秒数)

myDate.getHours();       //获取当前小时数(0-23)

myDate.getMinutes();     //获取当前分钟数(0-59)

myDate.getSeconds();     //获取当前秒数(0-59)

myDate.getMilliseconds();    //获取当前毫秒数(0-999)

myDate.toLocaleDateString();     //获取当前日期

var mytime=myDate.toLocaleTimeString();     //获取当前时间

myDate.toLocaleString( );        //获取日期与时间

注意myDate.toLocaleString( )得到的是带上午、下午的日期和时间,如果要转换成Fri Apr 02 2021 07:00:30 GMT+0800 (中国标准时间)这种进行时间的比较,就要这么做:

// 得到当前时间并格式化
var TIME=util.formatTime(new Date())
let time=String(TIME)
console.log(time);
console.log(new Date(time));

3.5 wx.chooseLocation

选择位置,进去时默认当前位置,这个貌似不用腾讯地图的SDK也能实现

  onChangeAddress: function (e) {
    wx.chooseLocation()
      .then(res => {
        // res既包含 address信息,也包含经纬度信息(经纬度需要返回以计算距离)
        // console.log(res);
        // res.name为地址名称  
        // console.log(res.name);
        this.setData({
          m_name: res.name,
          address: "( " + res.address + " )",
          m_latitude: res.latitude,
          m_longitude: res.longitude
        })
        // console.log(this.data.m_latitude, this.data.m_longitude);
      })
  },

3.6 wx.setData

// index.js
Page({
  data: {
    text: 'init data',
    num: 0,
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data' // 不要直接修改 this.data
    // 应该使用 setData
    this.setData({
      text: 'changed data'
    })
  },
  changeNum: function() {
    // 或者,可以修改 this.data 之后马上用 setData 设置一下修改了的字段
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },
  changeItemInArray: function() {
    // 对于对象或数组字段,可以直接修改一个其下的子字段,这样做通常比修改整个对象或数组更好
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }
})


4. 自定义组件

微信小程序布局、功能实现、常用组件、云开发汇总_第22张图片
某些模块某些代码可以重用时,可复用的组件!

  • 新增组件

  • 找到要放入这个组件的页面,进入json文件导入:

    {
      "usingComponents": {
        "Tabs": "../../components/Tabs/Tabs"
      }
    }
    
  • wxml里面把这个组件当作标签使用

这里涉及到CSSflex布局,我放下面大章节吧;
微信小程序布局、功能实现、常用组件、云开发汇总_第23张图片

  methods: {
    handleItemTap: function (e) {
      // console.log(e)
      // 获取索引
      const index = e.currentTarget.dataset.index;
      // 获取data的原数组
      let list = this.data.tabs;
      //循环处理
      list.forEach((v, i) => i == index ? v.isActive = true : v.isActive = false);

      this.setData({
        tabs: list
      })

    }
  }
<view class="tabs">
    <view class="tabs_title">
        
        <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="handleItemTap" data-index="{{index}}">
            {{item.name}}
        view>
    view>
    <view class="tabs_content">内容view>
view>

微信小程序布局、功能实现、常用组件、云开发汇总_第24张图片

  • [ ].forEach遍历数组的时候,修改了v,也会导致原数组被修改;
  • 对复杂类型进行解构时,复制一份变量的引用而已,最严谨的做法重新拷贝一份数组,在对这个数组的备份进行处理let xxx=JSON.parse();不要直接修改this.data.数据

父(页面)向子(组件)传递数据
微信小程序布局、功能实现、常用组件、云开发汇总_第25张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第26张图片
Tabs.js的方法中,我要拿到 data 区的数据,但是这里我把它放在了 properties 区,是不是就不能拿到了,实际上可以拿到 它会先在 data 区查找 找不到再去 properties 区;


现在这种情况就是,父传给子,子修改了,但是没传给父,看这个 appdata 里面的 tabs 并没有发生变化,说明子没给父传递最新的数据;
微信小程序布局、功能实现、常用组件、云开发汇总_第27张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第28张图片
所以这里我修改 子把索引传给父 父再得到索引进行处理 处理函数写在父的 js 文件里;(按道理也能子处理完列表 再传给父列表 )

触发属性名=‘bind’+事件名 然后再等于一个回调函数;这个回调函数在父的 js 中应该被定义;

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210330192144637.png微信小程序布局、功能实现、常用组件、云开发汇总_第29张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第30张图片

5 JavaScript

5.1 功能实现

5.1.1 获得两日期间所有日期

  getBetweenDateStr: function () {
  	// start 和 end 作为参数
    var start='2021-01-01';
    var end= '2021-03-01';
    var result = [];
    var beginDay = start.split("-");
    var endDay = end.split("-");
    var diffDay = new Date();
    var dateList = new Array;
    var i = 0;
    diffDay.setDate(beginDay[2]);
    diffDay.setMonth(beginDay[1] - 1);
    diffDay.setFullYear(beginDay[0]);
    result.push(start);
    while (i == 0) {
      var countDay = diffDay.getTime() + 24 * 60 * 60 * 1000;
      diffDay.setTime(countDay);
      dateList[2] = diffDay.getDate();
      dateList[1] = diffDay.getMonth() + 1;
      dateList[0] = diffDay.getFullYear();
      if (String(dateList[1]).length == 1) {
        dateList[1] = "0" + dateList[1]
      };
      if (String(dateList[2]).length == 1) {
        dateList[2] = "0" + dateList[2]
      };
      result.push(dateList[0] + "-" + dateList[1] + "-" + dateList[2]);
      if (dateList[0] == endDay[0] && dateList[1] == endDay[1] && dateList[2] == endDay[2]) {
        i = 1;
      }
    };
    console.log(result);
    return result;
  },

5.1.2 日期、时间与字符串的转换

https://blog.csdn.net/haeasringnar/article/details/81223966

var new_date_str = '2017-07-07'.replace(/-/g, '/')
var newdate = new Date(new_date_str)
console.log(newdate)//可以输出对应的日期对象,注意传入字符串也可以是'2017-7-7'
	//日期随便放,时间有就行
	// 先把-用/代替
    var new_time_str1 = '2017-07-07 07:00:00'.replace(/-/g, '/')
    var new_time_str2 = '2017-07-07 09:00:00'.replace(/-/g, '/')
    var new_time_str = '2017-07-07 08:59:00'.replace(/-/g, '/')
	// 转换成时间格式
    var newtime1 = new Date(new_time_str1)
    var newtime2 = new Date(new_time_str2)
    var newtime = new Date(new_time_str)
    console.log(newtime1) //可以输出对应的时间对象,注意这里传入的日期可以忽略,随便输入即可,但时间要给定。
    console.log(newtime2) //可以输出对应的时间对象,注意这里传入的日期可以忽略,随便输入即可,但时间要给定。
    console.log(newtime) //可以输出对应的时间对象,注意这里传入的日期可以忽略,随便输入即可,但时间要给定。
    console.log(newtime > newtime1);

5.2 字符串操作

substring
stringObject.substring(start,stop)
不取最后一位字符的操作就是stringObject.substring(start,stringObject.length-1)

5.3 逻辑判断

判断某个变量是否有值,可以直接用if(xxxx)判断,因为 js 中,没有值亦为 false;

5.4 数组操作

5.4.1 快速创建数据列表 Array().fill()

Array(5).fill({name:'linda', age: 18, sex: 1})

//结果
[ { name: 'linda', age: 18, sex: 1 },
  { name: 'linda', age: 18, sex: 1 },
  { name: 'linda', age: 18, sex: 1 },
  { name: 'linda', age: 18, sex: 1 },
  { name: 'linda', age: 18, sex: 1 } ]

5.4.2 从json数组中查找出满足指定条件的数据

filter()
微信小程序布局、功能实现、常用组件、云开发汇总_第31张图片

var employeesData = [
  { name: "王小明", mobile: "13900008789" },
  { name: "陈霞", mobile: "13900008789" },
  { name: "张悦", mobile: "13900008789" }
]
 
var queryData = employeesData.filter(function(fp) {
  return fp.name === "王小明"
})
console.log(queryData)

注意:queryData是一个数组,并且对它的操作相当于对原数组的操作
js对json数组的操作-查、删、改、增

debug


微信小程序提示 this.setData is not a function 解决方案之一:是因为此时的 this 已不再是全局的 this
微信小程序布局、功能实现、常用组件、云开发汇总_第32张图片


微信小程序如何修改指定的 json 数据?

https://segmentfault.com/q/1010000011018876/a-1020000011023388#
微信小程序布局、功能实现、常用组件、云开发汇总_第33张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第34张图片


传多个参数给另一个页面时,一定要用 & 把参数分割开!


6 CSS

6.1 引入 iconfont

如何在阿里巴巴矢量库中引用相应图标:

  • 进入网站https://www.iconfont.cn/

  • 选择自己要用的图标并加购;

  • 创建项目然后选择Font class,点击查看在线链接;

  • 生成代码,在浏览器中打开,全选复制;

  • 在小程序的 styles 文件夹中 创建 iconfont.wxss 文件,将刚刚复制的粘贴到里面;
    微信小程序布局、功能实现、常用组件、云开发汇总_第35张图片
    怎么引用:

  • 全局 app.wxss 中导入 @import "./styles/iconfont.wxss"

  • 然后就可以在项目任意 .wxml文件里面使用:
    在这里插入图片描述
    注意 iconfont 是母体,class 里面必须先写这个 再写后面你要用的名称!
    在这里插入图片描述

6.2 flex布局

6.2.1 介绍

http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
flex 弹性容器
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目";
微信小程序布局、功能实现、常用组件、云开发汇总_第36张图片
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis);主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end;

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size;

6.2.2 容器属性

容器的属性
以下6个属性设置在容器上:

flex-direction
flex-direction属性决定主轴的方向(即项目的排列方向)。

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

微信小程序布局、功能实现、常用组件、云开发汇总_第37张图片
它可能有4个值。

row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。

flex-wrap
flex-wrap属性
默认情况下,项目都排在一条线(又称"轴线")上;flex-wrap属性定义,如果一条轴线排不下,如何换行?
微信小程序布局、功能实现、常用组件、云开发汇总_第38张图片

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

它可能取三个值。

(1)nowrap(默认):不换行。

微信小程序布局、功能实现、常用组件、云开发汇总_第39张图片
(2)wrap:换行,第一行在上方。
微信小程序布局、功能实现、常用组件、云开发汇总_第40张图片
(3)wrap-reverse:换行,第一行在下方。
微信小程序布局、功能实现、常用组件、云开发汇总_第41张图片
flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap;


.box {
  flex-flow:  || ;
}

justify-content
justify-content属性定义了项目在主轴上的对齐方式;

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

微信小程序布局、功能实现、常用组件、云开发汇总_第42张图片
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右:

flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

align-items
align-items属性定义项目在交叉轴上如何对齐;

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

微信小程序布局、功能实现、常用组件、云开发汇总_第43张图片
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。

flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

align-content
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用;

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

微信小程序布局、功能实现、常用组件、云开发汇总_第44张图片
该属性可能取6个值:

flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。

6.2.3 项目属性

项目的属性
以下6个属性设置在项目上:
order
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0;

.item {
  order: ;
}

在这里插入图片描述
flex-grow
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大;

.item {
  flex-grow: ; /* default 0 */
}

微信小程序布局、功能实现、常用组件、云开发汇总_第45张图片
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍;
flex-shrink
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小;

.item {
  flex-shrink: ; /* default 1 */
}

微信小程序布局、功能实现、常用组件、云开发汇总_第46张图片
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小;
负值对该属性无效。

flex-basis
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
  flex-basis:  | auto; /* default auto */
}

它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

flex
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。


.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

align-self
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

微信小程序布局、功能实现、常用组件、云开发汇总_第47张图片
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

6.3 功能实现

6.3.1 input标签中使输入文本向右偏移

https://blog.csdn.net/wyll19980812/article/details/115453910

debug


微信小程序修改整个页面背景色

注意这个page不要加.
微信小程序布局、功能实现、常用组件、云开发汇总_第48张图片


7 HTML

debug

8. 常用功能实现

8.1 本地缓存保持登录

目的:防止进入页面时每次都要提示登录,记住用户登录状态
关键是 从缓存中获取wx.getStorageSync('user'),存入缓存:wx.setStorageSync('user', res.userInfo),
如果缓存没有该字段,可以直接判 false ;

  onLoad: function (options) {
    // 把本地缓存的用户信息给 user 变量
    let user = wx.getStorageSync('user')
    console.log(user);
    // 如果存在本地缓存,直接赋值
    if (user) {
      this.setData({
        user_name: user.nickName,
        user_avator_url: user.avatarUrl,
        show_button: false
      })
    }
    // 如果没有,则要用户登录,并缓存至本地
    else {
      var that = this;
      wx.showModal({
        title: '提示',
        content: '您尚未登录,请问是否立即登录',
        success: function (res) {
          if (res.confirm) {
            // 点击确定,调用信息函数
            that.getUserProfile()
          } else {
            console.log('点击取消回调')
          }
        }
      })
    }
  },
  getUserProfile: function () {
    wx.getUserProfile({
      desc: '授权登录以使用签到功能',
      success: res => {
        // console.log(res.userInfo);
        // 添加至本地缓存,在Storage中可查看
        wx.setStorageSync('user', res.userInfo),
          this.setData({
            show_button: false,
            user_name: res.userInfo.nickName,
            user_avator_url: res.userInfo.avatarUrl
          })
        this.onLoad()
      }

    })
  },

8.2 轮播图

本地的轮播图,亦可以用云上的数据!

  • 拿到轮播图API接口;

  • 建立轮播图数组;

  • 在 onLoad 里,发送异步请求获取轮播图数据, wx.request ,设置不校验域名合法性(详情-本地设置-勾选不校验合法域名)最好做一个后台接口,或者使用云开发

  • 拿到数据赋给轮播图数组;

  • 图片大小和 swiper 大小适应调整
    微信小程序布局、功能实现、常用组件、云开发汇总_第49张图片
    微信小程序布局、功能实现、常用组件、云开发汇总_第50张图片

8.3 调用腾讯地图API

  1. 申请开发者密钥(key):申请密钥

  2. 开通webserviceAPI服务:控制台 -> key管理 -> 设置(使用该功能的key)-> 勾选webserviceAPI -> 保存

    (小程序SDK需要用到webserviceAPI的部分服务,所以使用该功能的KEY需要具备相应的权限)

  3. 下载微信小程序JavaScriptSDK,微信小程序JavaScriptSDK v1.1 JavaScriptSDK v1.2

  4. 安全域名设置,在小程序管理后台 -> 开发 -> 开发管理 -> 开发设置 -> “服务器域名” 中设置request合法域名,添加https://apis.map.qq.com;


简单定位

获取当前位置

  1. 先得到经纬度并逆向解析
   // 引入SDK核心类
   var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');
   var qqmapsdk;
   Page({
     data: {
       latitude: '',
       longitude: ''
     },
     onLoad: function () {
       // 实例化API核心类
       qqmapsdk = new QQMapWX({
         key: 'MC2BZ-AYGLS-ID5OG-6VDXT-CBI5F-KYBOQ'
       });
     },
     onShow: function () {
       var that = this;
       // 调用接口
       wx.getLocation({
         type: 'wgs84',
         success: function (res) {
           console.log(res);
           //逆向解析
           qqmapsdk.reverseGeocoder({
             location: {
               latitude: res.latitude,
               longitude: res.longitude
             },
             success: function (result) {
               console.log(result);
               console.log(result.result.address);
               that.setData({
                 latitude: result.result.location.lat,
                 longitude: result.result.location.lng
               })
             }
           })
   
         }
       })
   
     }
   })
  1. 在 page 上显示当前位置

    把 latitude 和 longitude 就是刚刚得到的经纬度 传到组件上 然后用小程序内置地图显示;


带页面跳转选择位置的定位

https://segmentfault.com/a/1190000014833073

需求分析: 一些小程序打开后,以文字形式显示用户所在位置,如果用户觉得不准,可以打开地图,在地图上自己选择位置,选择完成后,显示的用户的位置会发生变化.今天我们就来看一下如何实现这个功能

// index.wxml
// 显示位置信息(默认显示自动定位后的位置信息)
<view class='address' bindtap='onChangeAddress'>
  {{address}}
view>
// 点击这块可以改变位置(改为自己确定后的地址)
// index.js
var QQMapWX = require('../../libs/qqmap-wx-jssdk.js'); // 首先引入腾讯地图的API
var qqmapsdk;

Page({
  /**
   * 页面的初始数据
   */
  data: {
    address: "", // 地址信息
    src:"" ,
    m_latitude: null,
    m_longitude: null
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

    /*
        判断是第一次加载还是从position页面返回
        如果从position页面返回,会传递用户选择的地点
        如果不是从position页面返回,而是第一次进入,则会自动定位用户的位置,显示用户的位置
    */
    if (options.address != null && options.address != '') {
      //设置变量 address 的值
      this.setData({
        address: options.address
      });
    } else {
      // 实例化API核心类
      qqmapsdk = new QQMapWX({
        //此key需要自己申请
        key: 'MNXBZ-G5TWD-GY...'
      });
      var that = this;
      // 调用接口
      qqmapsdk.reverseGeocoder({
        // 这里没有写location选项,是因为默认就是当前位置
        success: function (res) {
          // 获取默认下的地址
          that.setData({
            address: res.result.address
          });
        },
        fail: function (res) {
          //console.log(res);
        },
        complete: function (res) {
          //console.log(res);
        }
      });
    },
    // 点击跳转至
    onChangeAddress: function (e) {
        wx.navigateTo({
          url: "/pages/position/position"
        });
      }
  }
// position.wxml
<view class="page-body">
  <view class="page-section page-section-gap">
    <map id="qqMap" style="width: 100%; height: 300px;" latitude="{{latitude}}" longitude="{{longitude}}" show-location>map>
  view>
view>
// position.js
var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');
var qqmapsdk;
Page({
  data: {
    latitude: 0,//地图初次加载时的纬度坐标
    longitude: 0, //地图初次加载时的经度坐标
    name:"" //选择的位置名称
  },
  onLoad: function () {
    // 实例化API核心类
    qqmapsdk = new QQMapWX({
      key: 'MNXBZ-G5TWD-GYF42-HHZJL-2W2J3-PVBX4'
    });
   
    this.moveToLocation();   
  },
  //移动选点
  moveToLocation: function () {
    var that = this;
    // 打开地图选择位置
    wx.chooseLocation({
      success: function (res) {  
        // res.name为地址名称  
        console.log(res.name);    
        //选择地点之后返回到原来页面
        wx.navigateTo({
          url: "/pages/index/index?address="+res.name
        });
      },
      fail: function (err) {
        console.log(err)
      }
    });
  }
});

这里我稍作了改进,就是我不仅仅要返回 address 还要把 name、latitude、longitude 都返回,我开始想 打包成 json 包整体返回,但是发现这样就把 json 转换成了字符串 麻烦,后来在网上找到了 携带多参数的页面调整解决方案:
小程序wx.navigateTo跳转时传多个参数及获取
就是这个 & 害得我忙活了这么久

moveToLocation: function () {
    var that = this;
    // 打开地图选择位置
    wx.chooseLocation({
      success: function (res) {
        // res既包含 address信息,也包含经纬度信息(经纬度需要返回以计算距离)
        console.log(res);
        // res.name为地址名称  
        // console.log(res.name);
        //选择地点之后返回到原来页面
        wx.navigateTo({
        	// 多个参数一定要以 & 分割
          url: "/pages/addActivity/addActivity?address=" + res.address + "&latitude=" + res.latitude + "&longitude=" + res.longitude+"&name="+res.name
        });
      },
      fail: function (err) {
        console.log(err)
      }
    });
  }

以下为我的实现:目的是在 location 页选择位置后 能将 名称、地址、经纬度这些信息 返回给上一页
微信小程序布局、功能实现、常用组件、云开发汇总_第51张图片
在这里插入图片描述

// pages/addActivity/addActivity.wxml
<view class='address' bindtap='onChangeAddress'>
  {{name}}{{address}}
view>
// pages/addActivity/addActivity.js
var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');
var qqmapsdk;
Page({

  /**
   * 页面的初始数据
   */
  data: {
    address: "", // 地址信息
    name: "",
    m_latitude: null,
    m_longitude: null
  },

  onLoad: function (options) {
    // console.log(options);
    // 如果我从location页面得到了地址参数,那么直接显示
    if (options.address != null && options.address != '') {
      this.setData({
        name: options.name,
        address: '( ' + options.address + ' )',
        m_latitude: options.latitude,
        m_longitude: options.longitude
      })
    } else {//如果初次加载,此时地址为空,我要获得当前地址
      // 实例化API核心类
      qqmapsdk = new QQMapWX({
        key: 'MC2BZ-AYGLS-ID5OG-6VDXT-CBI5F-KYBOQ'
      });
      var that = this;
      // 调用接口
      qqmapsdk.reverseGeocoder({
        // 这里没有写location选项是因为默认就是当前位置
        success: function (res) {
          that.setData({
            address: '( ' + res.result.address + ' )',
            name: res.result.formatted_addresses.recommend,
            m_latitude: res.result.location.lat,
            m_longitude: res.result.location.lng
          });
        },
        fail: function (res) {
          // console.log(res);
        },
        complete: function (res) {
          // console.log(res);
        }
      })
    }
  },
  // 点击跳转至选择地址页面
  onChangeAddress: function (e) {
    wx.navigateTo({
      url: "/pages/position/position"
    });
  },
  // 获得活动名称
  getActivityName: function (e) {

  },

  onShow: function () {

  },
})

position.js 就是上面写了的那个

8.4 触底加载第二页数据

数据量足够多,且现实的20条数据比屏幕要长(把 view 的height 调高点即可)

有页面触底事件处理函数

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    console.log("加载更多");
  },

数据库方法 collection().skip(n)跳过n条数据;collection().limit(n)限制每一页显示n条数据;

完整代码:

  onReachBottom: function () {
    // 滑动页面加载
    console.log("加载更多");
    wx.cloud.database().collection('address-book')
      .skip(this.data.page_num * 20)
      .get()
      .then(res => { //请求成功
        // console.log("请求成功", res);
        console.log(res);
        this.setData({
          list: this.data.list.concat(res.data),
          page_num: this.data.page_num + 1
        })
        if (res.data.length == 0) {
          wx.showToast({
            title: '已全部加载完成',
          })
        }
      })
      .catch(err => { //请求失败
        console.log("请求失败");
      })
  },

8.5 日历功能实现

见我的文章:微信小程序实现日历功能(附加签到、迟到、未签的状态显示)

8.6 扫码功能

  // 扫码签到
  handleScanSignIn: function () {
    wx.scanCode({
      //人到才能扫码,所以禁止相册扫码
      onlyFromCamera: true,
      scanType: ['barCode', 'qrCode', 'datamatrix', 'pdf417'],
      success: res => {
        // 需要完善,扫管理员给出的码才算签到成功
        if (res.errMsg == 'scanCode:ok') {
          wx.showToast({
            icon: '',
            title: '签到成功'
          })
        }
      },
      fail: res => {
        // 接口调用失败
        wx.showToast({
          icon: 'none',
          title: '签到失败,请稍后再试!'
        })
      },
      complete: res => {
        // 接口调用结束
        console.log(res)
      }
    });
  },

8.7 地图标记一系列点marker以及范围画圈circles

参考我的文章:
微信小程序在地图上标点 markers & 画圈显示范围 circles

debug


小程序地图组件一进去自己的定位不在页面正中间
微信小程序布局、功能实现、常用组件、云开发汇总_第52张图片


7. 云开发

7.1 数据库


数据库表 => 集合,集合须为拼音、英文,不能是汉字;

数据库查不到东西可能使权限没开;
微信小程序布局、功能实现、常用组件、云开发汇总_第53张图片
进入控制台是管理员,而模拟小程序的使用却不是管理员;
微信小程序布局、功能实现、常用组件、云开发汇总_第54张图片
传统方法容易出现 this 指向的问题;
微信小程序布局、功能实现、常用组件、云开发汇总_第55张图片
推荐新写法;


数据库数据导入导出
微信小程序布局、功能实现、常用组件、云开发汇总_第56张图片


7.1.1 新增记录

addItem: function () {
    db.collection('tm_vehicle_info').add({ // .add() 在集合上新增记录
      data: {
        vehicle_id: 4,
        vehicle_name: 'Jeep',
        model_code: 2,
        speed: 690,
        image_url: '/images/vehicle/Jeep.png',
      },
      success: res => {
        console.log(res)
      },
      fail: err => {
        wx.showToast({
          icon: "none",
          title: '插入记录失败',
        })
        console.log(err)
      }
    })
  }

7.1.2 更新数据

update 可以搭配 where 使用,但是 set 不能;update和set是只更新data域提供的数据,该记录其它字段不发生变化!
set的好处就是 有就修改 没有则新增!

  testFunction: function () {
    wx.cloud.database().collection('address-book').where({
      _id: "1"
    }).update({
      data:{
        tel:"12345678912"
      }
    })
  },

所以 索引_id最好是open_id,这样可以直接将微信用户和数据库用户绑定!

7.1.3 获得表的所有数据(分页突破20限制)

https://blog.csdn.net/wyll19980812/article/details/115443374

7.2 云函数

7.2.1 云函数优势


优势
以获取openid为例,php需要很多步:
微信小程序布局、功能实现、常用组件、云开发汇总_第57张图片
而云函数只需要两三步;
微信小程序布局、功能实现、常用组件、云开发汇总_第58张图片
获得的云数据库记录条数也有优势:
微信小程序布局、功能实现、常用组件、云开发汇总_第59张图片
云函数属于管理端,在云函数中运行的代码拥有受限的数据库读写权限和云文件读写权限。需特别注意,云函数运行环境即是管理端。与云函数中的传入的openld对应的微信用户是否是小程序的管理员/开发者无关。

7.2.2 云函数使用


初始化
微信小程序布局、功能实现、常用组件、云开发汇总_第60张图片
微信小程序布局、功能实现、常用组件、云开发汇总_第61张图片

// 云函数入口文件
const cloud = require('wx-server-sdk')

// 云函数初始化
cloud.init({
  // env: 'cloud1-0gbwed2xdbe13cb4' 固定云开发环境
  env: cloud.DYNAMIC_CURRENT_ENV //动态获取当前云开发环境
})

微信小程序布局、功能实现、常用组件、云开发汇总_第62张图片


云函数调用
每个用户的 openid 都不一样,在创建商品时,可以是管理员1创建,也可以管理员2创建,openid 得以区分;
对于已经部署了的云函数,可以这样调用

  onLoad: function (options) {
    wx.cloud.callFunction({
    	// 云函数名 getData
      name: "getData",
      success(res) {
        console.log("请求成功",res);
      },
      fail(err) {
        console.log("请求失败",res);
      }
    })
  },

返回以下信息:
微信小程序布局、功能实现、常用组件、云开发汇总_第63张图片
注意 用 then 和 catch 更方便;
其中就包括 openid ;

微信小程序布局、功能实现、常用组件、云开发汇总_第64张图片
云函数返回大量数据,而本地只能返回部分;
万一数据库中有几百条怎么整?


云函数获取数据
云函数只要有改动就要重新部署, 否则还是用的之前的版本;
云函数里面有云函数的写法,比如不用wx写法!
在这里插入图片描述
使用云函数时,都能够对数据库进行更新,而小程序直接操作云数据库时只能管理员创建更新,除非修改权限!

7.2.3 向云函数传递数据

要传递的数据在callFunction 中 以data的形式传递,云函数会用 event 来接受数据!

// 通过云函数 addRecord 向 activity-list 传递记录
let parameter = {
  _name: this.data.name,
  _address: this.data.address,
  _distance: this.data.distance,
  _start_time: this.data.start_time,
  _end_time: this.data.end_time,
  _latitude: this.data.m_latitude,
  _longitude: this.data.m_longitude
}
console.log(parameter);
wx.cloud.callFunction({
    name: "addRecord",
    data: parameter
  })
  .then(res => {
    console.log("访问成功");
  })

7.2.4 云函数创建集合

Database.createCollection(collectionName: string): Promise
创建集合,如果集合已经存在会创建失败,参数就一个collectionName: string

const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
exports.main = async (event, context) => {
  return await db.createCollection('todos')
}

微信小程序布局、功能实现、常用组件、云开发汇总_第65张图片

7.2.5 云函数批量添加数据

在小程序端不能批量添加
只能使用for循环添加,但是容易造成资源用量爆表
在云函数中可以实现批量添加

//云函数
var a={age:22},b={age:23}
var list=[a,b]
db.collection('age').add({data:list}).then()
//这样就行了

7.2.6 云函数获取表的长度

exports.main = async (event, context) => {
  return cloud.database().collection('address-book').count()

}

返回
在这里插入图片描述

7.2.7 导出数据到excel表

https://www.imooc.com/article/292184?block_id=tuijian_wz#comment

自己修改后的代码:
js代码

Page({
  data: {
    person_list: [],
    fileUrl: "",
  },
  toExcel: function () {
    // console.log(this.data.person_list);
    wx.cloud.callFunction({
        name: "toExcel",
        data: {
          userdata: this.data.person_list
        }
      })
      .then(res => {
        console.log("保存成功", res);
        this.getFileUrl(res.result.fileID)
      })
      .catch(err => {

      })
  },
  //获取云存储文件下载地址,这个地址有效期一天
  getFileUrl: function (fileID) {
    wx.cloud.getTempFileURL({
        fileList: [fileID]
      })
      .then(res => {
        console.log("文件下载链接", res.fileList[0].tempFileURL);
        this.setData({
          fileUrl: res.fileList[0].tempFileURL
        })
        wx.showModal({
            title: "提示",
            content: "excel文件下载链接:" + this.data.fileUrl,
            confirmText: "复制链接"
          })
          .then(res => {
            if (res.confirm) {
              // 点击确定,复制下载链接
              this.copyFileUrl()
            } else {
              console.log("用户取消");
            }
          })
      })
      .catch(err => [])
  },
  //复制excel文件下载链接
  copyFileUrl: function () {
    wx.setClipboardData({
        data: this.data.fileUrl,
      })
      .then(res => {
        wx.getClipboardData({
          success: (option) => {
            console.log("复制成功", res.data);
          },
        })
      })
  }
})

wxml代码:

<view class="excel-button">
  <button bindtap="toExcel">导出至excel表button>
view>

云函数getData代码:

// 云函数入口文件
const cloud = require('wx-server-sdk')

// 云函数初始化
cloud.init({
  // env: 'cloud1-0gbwed2xdbe13cb4' 固定云开发环境
  env: cloud.DYNAMIC_CURRENT_ENV //动态获取当前云开发环境
})
// 云函数入口函数
exports.main = async (event, context) => {
  return cloud.database().collection('address-book').get()
}

云函数toExcel代码,注意toExcel需要安装node-xlsx类库(node类库),在该函数中打开终端,输入npm install node-xlsx即可
微信小程序布局、功能实现、常用组件、云开发汇总_第66张图片

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  // env: 'cloud1-0gbwed2xdbe13cb4' 固定云开发环境
  env: cloud.DYNAMIC_CURRENT_ENV //动态获取当前云开发环境
})

//操作excel用的类库
const xlsx = require('node-xlsx');

// 云函数入口函数
exports.main = async (event, context) => {
  try {
    let {
      userdata
    } = event

    //1,定义excel表格名
    let dataCVS = 'attendance.xlsx'
    //2,定义存储数据的
    let alldata = [];
    let row = ['num', 'name', 'state']; //表属性
    alldata.push(row);

    for (let key in userdata) {
      let arr = [];
      arr.push(userdata[key].num);
      arr.push(userdata[key].name);
      if (userdata[key].state == -1) {
        arr.push("未到")
      } else if (userdata[key].state == 0) {
        arr.push("迟到")
      } else {
        arr.push("正常")
      }
      alldata.push(arr)
    }
    //3,把数据保存到excel里
    var buffer = await xlsx.build([{
      name: "mySheetName",
      data: alldata
    }]);
    //4,把excel文件保存到云存储里
    return await cloud.uploadFile({
      cloudPath: dataCVS,
      fileContent: buffer, //excel二进制文件
    })

  } catch (e) {
    console.error(e)
    return e
  }
}

7.3云存储

把图片上传到云存储,拿到 fileId,下次能根据fileId拿到临时url
微信小程序布局、功能实现、常用组件、云开发汇总_第67张图片

  //发布物品的响应事件
  bindSubmitThing: function () {
    var that = this;
    // var studentId = that.data.studentId;
    var studentId = "2016302030120"
    if (!studentId) {
      wx.showModal({
        title: '提示',
        content: '请验证您的学生身份',
        success: function (res) {
          if (res.confirm) {
            console.log('用户点击确定')
            wx.navigateTo({
              url: '../my/my',
            })
          } else if (res.cancel) {
            console.log('用户点击取消')
          }
        }
      })
    } else {
      this.setData({
        buttonLoadingThing: true
      })
      var thingImage = that.data.thingImage; //图片
      var thingName = that.data.thingName; //名字
      var thingConditionIndex = that.data.thingConditionIndex; //成色索引值
      var thingConditions = that.data.thingConditions[thingConditionIndex]; //成色
      var thingCampusIndex = that.data.thingCampusIndex; //校区索引值
      var thingCampus = that.data.thingCampus[thingCampusIndex]; //校区
      var thingDescribe = that.data.thingDescribe || '无备注或描述'; //备注
      var thingPhoneNumber = that.data.thingPhoneNumber; //电话
      var thingPrice = that.data.thingPrice; //价格
      var studentId = that.data.studentId;
      studentId = "2016302030120"

      // 图片上传到云存储,并复制 fileId + 其它信息存到数据库中方便索引,下次查看图像
      var cloudPath = "img/" + new Date().getTime() + "-" + Math.floor(Math.random() * 1000) //云储存的路径及文件名;
      console.log(cloudPath);
      console.log(thingImage);
      wx.cloud.uploadFile({
          cloudPath,
          filePath: thingImage
        })
        .then(res => {
          console.log(res);
          wx.cloud.database().collection('all-things').add({
              data: {
                thingImage: res.fileID,
                thingName: thingName,
                thingConditions: thingConditions,
                thingCampus: thingCampus,
                thingDescribe: thingDescribe,
                thingPhoneNumber: thingPhoneNumber,
                thingPrice: thingPrice,
                studentId: studentId
              }
            })
            .then(res => {
              console.log("加入表 all-things 的res:", res);
              wx.showToast({
                title: '发布成功',
                icon: 'succes',
                duration: 2500,
                mask: true
              })
              that.setData({
                buttonLoadingThing: false,
                thingImage: '',
                thingName: '',
                thingDescribe: '',
                thingPrice: '',
                thingPhoneNumber: '', //电话号码
              })
            })
            .catch(res => {
              console.log(JSON.stringify(res));
              wx.showToast({
                title: '发布失败',
                icon: 'loading',
                duration: 2000
              })
              that.setData({
                buttonLoadingThing: false
              })
            })

        })
        .catch(res => {
          console.log(JSON.stringify(res));
          wx.showToast({
            title: '发布失败',
            icon: 'loading',
            duration: 2000
          })
          that.setData({
            buttonLoadingThing: false
          })
        })
    }
  },

debug


微信小程序update失败的问题
VM820 WAService.js:2 TypeError: {(intermediate value)}.update is not a function
原因是默认数据库权限是管理者可写,所以我们要改成所有人可写,或者在你的json文件上加一个openid 字段,标注你自己的openid


云函数中使用console.log();在控制台不打印结果 解决方案
云函数打印内容不回在控制台显示,而是在云函数的日志中有记录
微信小程序布局、功能实现、常用组件、云开发汇总_第68张图片


云函数打印不出内容,日志中也不显示,解决方案:
需要在console.log(x,123) 标识符:123
微信小程序布局、功能实现、常用组件、云开发汇总_第69张图片


微信小程序遇到的程序异步执行导致数据库读写异常的问题
见我的这篇文章https://blog.csdn.net/wyll19980812/article/details/115423805


Error: tunneling socket could not be established, cause=connect ECO微信小程序本地调试预览出错
微信小程序布局、功能实现、常用组件、云开发汇总_第70张图片

你可能感兴趣的:(前端,小程序,小程序,js,html,css)