小程序学习笔记

小程序学习笔记

1.与网页的不同

1.运行环境不同,网页运行在浏览器的环境,小程序在微信环境中
2.API不同,小程序没有DOM,BOM,但是可以提供各种API进行定位,扫码,支付
3.开发模式不同,小程序开发账号,开发工具
4.不需要下载就可以使用,(实际是包很小 下载很快看不出来下载)

2.项目基本结构

在这里插入图片描述

project.config.json 是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置

setting 中保存了编译相关的配置
projectname 中保存的是项目名称
appid 中保存的是小程序的账号 ID

sitemap.json

微信现已开放小程序内搜索,效果类似于 PC 网页的 SEO。sitemap.json 文件用来配置小程序页面是否允许微信索引。
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索关键字和页面的索引匹配成功的时候,小程序的页面将可能展示在搜索结果中。
(注意: 默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配置文件 project.config.json 的 setting 中配置字段 checkSiteMap 为 false

app.json

在这里插入图片描述

window 设置

用于设置小程序的状态栏、导航条、标题、窗口背景色。

navigationBar系列Value
navigationBarBackgroundColor导航栏背景颜色,如 #000000
navigationBarTextStyle导航栏标题颜色,仅支持 black / white
navigationBarTitleText导航栏标题文字内容
navigationStyle导航栏样式(仅支持以下值:default 默认,custom 自定义,只保留右上角胶囊按钮)
background系列Value (开启下拉刷新显示)
backgroundColor窗口的背景色
backgroundTextStyle下拉 loading 的样式,(仅支持 dark / light)
其他Value
enablePullDownRefresh是否开启全局的下拉刷新(true/false)。(数据更新后关闭下拉刷新:wx.stopPullDownRefresh())
onReachBottomDistance页面上拉触底事件触发时距页面底部距离,50px。

在这里插入图片描述

tabBar 设置

如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

项目Value
color文字默认颜色,仅支持十六进制颜色
selectedColor文字选中时的颜色,仅支持十六进制颜色
backgroundColor背景色,仅支持十六进制颜色
borderStyletabbar 上边框的颜色, 仅支持 black / white
listtab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab
positiontabBar 的位置,仅支持 bottom / top
custom自定义 tabBar,见详情

其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:

项目Value
pagePath页面路径,必须在 pages 中先定义
texttab 上按钮文字
iconPath图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon。
selectedIconPath选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon。

在这里插入图片描述

WXML

WXML是小程序框架设计的一套标签语言,用来构建小程序页面结构,相当于HTML

WXSS

一套样式语言
rpx尺寸单位,只支持部分css选择器
小程序的屏幕固定为750rpx(即750个物理像素)。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

uniapp的rpx计算:750*元素的设计稿大小/设计稿总宽(750/640)
750/750*100=100rpx
750/640*100=117rpx
750/375*100=400rpx 

3.宿主环境

网页运行在浏览器中,小程序运行在微信中

4.通信模型,渲染层和逻辑层

小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。其中,渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。

在这里插入图片描述

6.数据绑定(文本,属性)

// page.js
Page({
  data: {
    message: 'Hello MINA!',
    classname:'active'
  }
})
<view> {{message}} </view>
<view class="{{classname}}"> 123</view>//属性绑定

7.修改数据

普通数据

data: {
    name:'张三'
  },

this.setData({
      name:'李四'
})

对象数据

data: {
    user_info:{
      name: 'li',
      age: 10
    },
    cars:['nio', 'bmw', 'wolks']
},

this.setData({
      ['user_info.age']: 20,
      ['cars[0]']: 'tesla'
})

7.wx:if=" " 判断是否渲染

<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>

8.hidden 控制元素显示隐藏

<view hidden="{{true}}">123</view>
hiddenwx:if
hidden控制display属性,如选项卡控制渲不渲染, 如以上来决定显不显示
有更高的初始渲染消耗if有更高的切换消耗

9.wx:for =" "列表渲染

data:[
{id:'001',message:'a'},
{id:'002',message:'b'}
]
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="id">
  {{idx}}: {{itemName.message}}
</view>

wx:key=" index"和wx:key="*this"的区别

(*this 选中选项可以跟随变化)

*this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字

在这里插入图片描述

在这里插入图片描述

(index 选中选项不跟随变化)

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

10 . < block> 包装元素

并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

wx:if vs hidden

11.template模板引用

用于重复的静态资源,不像component
1.在这里插入图片描述创建tmp组件存放目录,内部包含wxml和wxss文件

2.用template标签定义一个代码片段,使用name属性指定模板的名称

//tmp1.wxml
<template name="a">
<view>
<image src="{{item.img}}"></image>
<text>{{item.name}}</text>
</view>
</template>
<view>111</view>

2.引入模板的样式,使用@import

//page1.wxss
@import '/tmp/tmp1/tmp1.wxss';

3.引入模板结构并且使用

//page1.wxml
<import src="/tmp/tmp1/tmp1"></import>//import:用来引用模板文件里面定义的模板内容块
<include src="/tmp/tmp1/tmp1">//include:用来引用目标文件内除了模板代码块的其他内容,显示<view>111</view> 的内容
<block wx:for="{{list}}" wx:key="id">
<template is="a" data="{{item}}"></template>
</block>

使用 is 属性声明需要的使用的模板利用data属性向模板传入需要的数据信息

12. import和include引用方式

WXML 提供两种文件引用方式 import和include

import可以在该文件中使用目标文件定义的template

<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>

include 可以将目标文件除了 template , wxs外的整个代码引入,相当于是拷贝到 include 位置

<include src="header.wxml"/>//111
<template name="lis">
<view class="lis">
<image src="{{item.img}}"></image>
<text>{{item.name}}</text>
</view>
</template>
<view>111</view>

13.生命周期

小程序生命周期Value
onLaunch小程序初始化。
onShow小程序启动或切前台。
onHide小程序切后台。
onUnlaunch小程序卸载(在getApp()中可以找到)
在这里插入图片描述
页面生命周期函数Value
-------------
onLoad页面加载(只调用一次)
onShow页面显示
onReady页面初次渲染完成(只调用一次)
onHide页面隐藏
onUnload页面卸载(只调用一次)

14.事件

事件Value
tap类似click
input文本框输入(获取值:e.detail.value)
changecheckbox-group中选中项发生改变时,detail = {value:[选中的 checkbox 的value的数组]}
touchstart手指触摸动作开始
touchmove手指触摸后移动
touchcancel手指触摸动作被打断,如来电提醒,弹窗
touchend手指触摸动作结束

阻止事件冒泡catch

除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。

<view catchtap="tapName"> Click me! </view>

事件对象event

eventValue
type事件类型
target触发事件组价的属性值集合
currenttarget事件绑定的当前组件
detail额外信息
touches触摸点信息
targetTouches当前元素目标上的触摸点
changedTouches发生改变的触摸点,几个手指发送了变化
<view id="tapTest" data-hi="Weixin" bindtap="tapName"  mark:id="1001"> Click me! </view>
tapName(e){
e.currentTarget.dataset.hi //Weixin
e.mark.id   //1001
}

绑定数据

方法一:data - 名字=“数据”

(为什么不用target是因为嵌套多了不一定点到元素),注意驼峰命名和-命名会转变
target是触发事件的元素,事件会冒泡到父级元素去,
currentTarget是绑定事件的元素
e.currentTarget.dataset.名字

方法二:mark:名字=“数据”

e.mark.名字
命名不会大小写转换

markdataset
mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值dataset 仅包含一个节点的 data- 属性值。
如果存在同名的 mark ,父节点的 mark 会被子节点覆盖。
在自定义组件中接收事件时, mark 不包含自定义组件外的节点的 mark 。
不会字符和大小写转换会大小写转换

15.组件

项目Value
view相当于div
swiper滑块视图容器,只可放置swiper-item组件(轮播图)
swiper-item仅可放置在swiper组件中,宽高自动设置为100%(滚动列表),scroll-x,scroll-y
scroll-view可滚动视图区域
movable-area可移动区域
movable-view可移动容器,direction=‘all、vertical、horizontal、none’,bindchange拖动过程中触发的事件
text文本(长按选中文本,selectable)
rich-text通过nodes属性把字符串渲染成对应ui结构
button按钮 open-type属性可以调用微信提供的功能
navigator导航相当于a
image图片默认300*240 (mode属性指定模式,scaleToFill宽高拉伸填满,aspectFit图片长边显示,aspectFill图片短边,widthFix宽不变高自适应,heightFix高不变宽自适应)
input输入框
picker从底部弹起的滚动选择器。
picker-view嵌入页面的滚动选择器。其中只可放置 picker-view-column组件,其它节点不会显示。
progress进度条percent(百分比0~100),stroke-width="4"宽度, activeColor="red"已走颜色

swiper
indicator-dots 指示点
indicator-color 指示点颜色
indicator-active-color 当前选中的指示点颜色
autoplay 是否自动切换
interval 自动切换时间间隔
duration 滑动动画时长
circular 是否采用衔接滑动

input
value 输入框的初始内容
type input 的类型
password 是否是密码类型
placeholder输入框为空时占位符
disabled是否禁用
maxlength 最大输入长度,设置为 -1 的时候不限制最大长度
confirm-type设置键盘右下角按钮的文字,仅在type='text’时生效(send 右下角按钮为“发送”,search 右下角按钮为“搜索”,next 右下角按钮为“下一个”,go 右下角按钮为“前往”,done 右下角按钮为“完成”)
bindinput eventhandle键盘输入时触发,
bindconfirm 点击完成按钮时触

movable-view 可移动的视图容器

可移动的视图容器,在页面中可以拖拽滑动。movable-view必须在 movable-area 组件中,并且必须是直接子节点,

项目Value
directionmovable-view的移动方向,属性值有all、vertical(垂直)、horizontal(水平)
xx偏移
yy偏移
bindchange拖动过程中触发的事件,event.detail = {x, y, source}

通过e.detail.source==‘touch’判断是否是拖拽过去的

scroll-view 可滚动视图区域

项目Value
scroll-x允许横向滚动
scroll-y允许纵向滚动
scroll-top设置竖向滚动条位置
scroll-left设置横向滚动条位置
scroll-with-animation在设置滚动条位置时使用动画过渡 1.0.0
refresher-enabled开启自定义下拉刷新
bindrefresherrefresh自定义下拉刷新被触发
refresher-triggered设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
bindscroll滚动时触发,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}
bindscrolltolower滚动到底部/右边时触发

横向滚动

scroll-view要设置 scroll-x=“true” style=" white-space: nowrap;"
子组件设置style=“display: inline-block”

<scroll-view class="t2" scroll-x="true"
 style=" white-space: nowrap; display: flex" >
  <view class="t2" style="display: inline-block"></view>
  <view class="t2" style="display: inline-block"></view>
  <view class="t2" style="display: inline-block"></view>
</scroll-view>

纵向滚动

必须设置高度

 <scroll-view scroll-y >
	<view>1</view>
	<view>2</view>
	<view>3</view>
  </scroll-view>

16.WXS

WXS(WeiXin Script)是小程序的一套脚本语言

创建wxs

//注意:函数内判断是否有值,没有就return要不会报错

function fnA(str){
	if(!str){return}//注意:判断时候有值,没有就return要不会报错
	return str+'A'
}
module.exports = {//导出
//必须用key:value的写法
 fnA:fnA
};

使用

1.引用方式

{{m1.fnA(123)}}
<wxs module="m1" src="/util/1.wxs"></wxs>

页面.wxml中创建+使用

<view>{{wxs1.reverse(123)}}</view>
<wxs module="wxs1">
  function reverse(str){
    if(!str){
      return
    }
    return str+'1111111'
  }
  module.exports={reverse:reverse}
</wxs>

wxs中引入wxs

创建第二个wxs

//2.wxs
function fnB(str){
	return str+'B'
}
module.exports = {
 fnB:fnB
};
//1.wxs 1里面引入2
var fnA=require('./2.wxs')
function fnB(str){
	return str+'B'
}
module.exports = {
 fnB:fnB
 fnA:fnA.fnA
};
//page.wxml
<wxs></wxs>

17. 路由组件navigator

<navigator 	open-type=""  url="/pages/home/home"></navigator>

传参:url=“/pages/home/home?id=10”

open-typeValue
navigate对应 wx.navigateTo 或 wx.navigateToMiniProgram (跳转普通页面)
redirect对应 wx.redirectTo
switchTab对应 wx.switchTab (跳转tabBar页面)
reLaunch对应 wx.reLaunch
navigateBack对应 wx.navigateBack 或 wx.navigateBackMiniProgram

18. API

项目Value
事件监听以on开头监听事件触发 (wx.onWIndowResize())窗口大小
同步以sync结尾 (wx.setStorageSync(‘key’,‘value’))本地存储输入内容
异步类似于jq中的$.ajax,需要success来接收结果(wx.request())网络请求

第一种:路由相关API(跳转页面)

1.wx.navigateTo() 保留当前页面跳转

保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层

    // 隐藏当前页面,跳转非tabBar页面
    // 传值:?后面传入数据多个数据用&链接
    // 取值,在另一个页面onLoad函数参数中取值
    wx.navigateTo({ 
      url: '/pages/page6/page6?id=1001',
    })
  

2. wx.redirectTo()卸载当前页面跳转

卸载当前页面跳转,不允许跳转到 tabbar 页面。

    // 卸载当前页面跳转,不允许跳转到 tabbar 页面。
    wx.redirectTo({
      url: '/pages/page6/page6?id=1002',
    })
  

3.wx.switchTab() 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面

  // 卸载当前页面,跳tabbar页面,不能传参
    wx.switchTab({
      url: '/pages/page1/page1',
    })

4. wx.reLaunch()关闭所有页面,打开到应用内的某个页面,可以打开tabBar页面

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

    //卸载当前页面,跳转应用中任意页面,可穿值
    wx.reLaunch({
      url: '/pages/page4/page4?id=1',
    })

5.wx.navigateBack() 返回页面

关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层。如果 delta 大于现有页面数,则返回到首页。

取值

onLoad: function(options) {
   var objectId = options.objectId
}

区别

项目Value
navigateTo页面不是很多,推荐wx.navigateTo,后退不需要重新渲染
redirectTo相当于重定向跳转,销毁当前的页面
reLaunch销毁内存中所有保留的页面

官方规定小程序最多只能有五个页面同时存在,意思是在不关闭页面的情况下,最多新开五个页面,页面深度为5。
wx.navigateTo会增加页面栈大小,直到页面栈大小为5,wx.redirectTo不会增加页面栈大小;wx.navigateBack会减少页面栈大小,直到页面栈大小为1

第二种:界面相关API(弹窗) 4+2(关闭)

1.wx.showLoading()+ wx.hideLoading()

在这里插入图片描述

 wx.showLoading({
      title: '加载中...',
      mask:true,  // 设置蒙层,下面的东西不能点
    })
    setTimeout(()=>{
      wx.hideLoading()
    },3000)

2.wx.showToast()+wx.hideToast()消息提示框

在这里插入图片描述

    wx.showToast({
      title: '警告',
      icon:'error',
      duration:3000,
      mask:true,
      image:'/images/jd1.png'
    })
    setTimeout(()=>{
      wx.hideToast()
    },1000)

3. wx.showModal()模态框

在这里插入图片描述

//方式一:利用回调函数拿到模态框执行结果
 wx.showModal({
       title:'删除',
       content:'您确认删除吗',
       success:(res)=>{
         if(res.confirm){
          console.log('点击了确认按钮')
         }
       }
     })
 // 方式二:利用promise.then拿到模态框结果
     wx.showModal({
       title:'删除',
       content:"您确定删除吗"
     }).then((res)=>{
       if(res.confirm){
       console.log('点击了确认按钮')
     }})
 // 方式三:利用async和await (onModal加async),因为showModal支持promise,大部分api都支持promise
 async onModal(){ 
  const res= await wx.showModal({
      title:'删除',
      content:"您确定删除吗",
    })
    if(res.confirm){
      console.log('点击了确认按钮')
    }
  },

4.wx.showActionSheet()操作菜单

在这里插入图片描述

不要在按完取消逻辑下写业务逻辑

 async onSheet(){
   const res=await wx.showActionSheet({
      itemList:['1','2','3']
    })
    console.log(res.tapIndex)//用户点击的按钮序号,从上到下的顺序,从0开始
  },

第三组 :界面导航栏相关API 4+1(隐藏)

1. wx.showNavigationBarLoading()+wx.hideNavigationBarLoading()

在这里插入图片描述

	 wx.showNavigationBarLoading()
    setTimeout(()=>{
      wx.hideNavigationBarLoading()
    },3000)

2. wx.setNavigationBarTitle() 设置导航栏新标题

wx.setNavigationBarTitle({
      title: '导航栏新标题',
    })

3.setNavigationBarColor()设置页面导航条颜色

wx.setNavigationBarColor({
        backgroundColor:'#000000',//仅支持 #ffffff 和 #000000
        fontColor:'#ffffff',
        animation: {//动画效果
		    duration: 400,
		    timingFunc: 'easeIn'
		 }
      })

4. wx.hideHomeButton() 隐藏返回首页按钮

在这里插入图片描述

    wx.hideHomeButton()

第四种: 缓存API (Sync同+异)

sync,当数据比较少,不会影响下面的程序的时候用同步

1.wx.setStorageSync() 和wx.setStorage() 存缓存

小程序的setStorageky 可以存任意格式,网页只能存字符串(JSON.stringify)

    wx.setStorageSync('a', 123)
    wx.setStorageSync('obj', {name:123})
  wx.setStorage({
      key:'car',
      data:[{name:'张三',age:12}],
    })

2.wx.getStorageSync() 和wx.getStorage() 取缓存

  const a=  wx.getStorageSync('a')
 //方法一,利用回调函数取数据
	wx.getStorage({
      key:'b',
      success:(res)=>{
        console.log(res.data)
      }
    })
 //方法二:利用promise
    wx.getStorage({key:'b'}).then((res)=>{console.log(res.data)})
 //方式三:async+await
 async get(){
	 const res=await wx.getStorage({key:'car'})
    console.log(res)
 }
    

3.wx.removeStorageSync() 和wx.removeStorage() 移出缓存

   wx.removeStorageSync('a')
	 wx.removeStorage({
      key: 'b',
    })

4.wx.clearStorageSync() 和wx.clearStorage() 清空缓存

  wx.clearStorageSync()
   wx.clearStorage()

背景音乐

在这里插入图片描述

1.页面.js中获取背景音乐管理对象

const bgm=wx.getBackgroundAudioManager()
Page({})

2.后台继续播放音频requiredBackgroundModes

//app.json
{

  "requiredBackgroundModes": ["audio", "location"]
}

在这里插入图片描述

属性

项目Value
src音频的数据源。当设置了新的 src 时,会自动开始播放
startTime音频开始播放的位置(单位:s)。
title音频标题,(必填)
epname专辑名
singer歌手名
coverImgUrl封面图 URL
webUrl页面链接
protocol音频协议。
playbackRate播放速度。范围 0.5-2.0,默认为 1。
duration当前音频的长度(单位:s)
currentTime当前音频的播放位置(单位:s)
paused当前是否暂停或停止。(只读)
buffered音频已缓冲的时间,仅保证当前播放时间点到此时间点内容已缓冲。(只读
 onLoad(options) {
    // 设置src和title
bgm.title="起风了"//名字
bgm.src="http://music.163.com/song/media/outer/url?id=167827.mp3"//音乐地址,用网络地址
bgm.singer="买辣椒也用卷"//歌手名字
bgm.coverImgUrl="https://scpic.chinaz.net/files/pic/pic9/202009/apic27858.jpg"//封面图
bgm.playbackRate=2.0//播放倍速
setTimeout(()=>{
  console.log(bgm.duration)//总时长
  console.log(bgm.currentTime)//当前播放时长
  console.log(bgm.paused)//是否暂停
},5000)
 // 监听背景音乐时间
  // 监听背景音频是否可以播放
  bgm.onCanplay(()=>{
    console.log("音乐可以播放")
  })
  //2.监听有音乐播放
  bgm.onPlay(()=>{
   console.log("音乐在播放")
  })
   //3.监听音乐暂停
   bgm.onPause(()=>{
     console.log("音乐暂停")
    })
    //4.监听音乐播放过程
  bgm.onTimeUpdate(()=>{
    console.log( bgm.currentTime)
   
  })
   //5.监听音乐自然播放结束
   bgm.onEnded(()=>{
    console.log("音乐播完了")
  })
  //6.音频跳转中
  bgm.onSeeking(()=>{
    console.log('音频跳转中,请稍后')
  })
  //7.音乐跳转完成(真机测试)
  bgm.onSeeked(()=>{
    console.log('音频跳转完')
  })
   //8.监听下一首播放(真机测试)
   bgm.onNext(()=>{
    console.log('下一首')
  })
  },


  play(){
    bgm.play()//暂停
  },
  pause(){
    bgm.pause()//播放
  },
  stop(){
    bgm.stop()//停止关闭音乐,从头开始播放
  },
  seek(){
    bgm.seek(200)//跳转播放位置
  },

循环播放
在这里插入图片描述

方法

bgmconst bgm=wx.getBackgroundAudioManager()
bgm.play()播放音乐
bgm.pause()暂停音乐
bgm.seek(number currentTime)跳转到指定位置
bgm.stop()停止音乐
bgm.onCanplay(function callback)监听背景音频进入可播放状态事件。 但不保证后面可以流畅播放
bgm.onWaiting(function callback)监听音频加载中事件。当音频因为数据不足,需要停下来加载时会触发
bgm.onError(function callback)监听背景音频播放错误事件
bgm.onPlay(function callback)监听背景音频播放事件
bgm.onPause(function callback)监听背景音频暂停事件
bgm.onSeeking(function callback)监听背景音频开始跳转操作事件
bgm.onSeeked(function callback)监听背景音频完成跳转操作事件
bgm.onEnded(function callback)监听背景音频自然播放结束事件
bgm.onStop(function callback)监听背景音频停止事件
bgm.onTimeUpdate(function callback)监听背景音频播放进度更新事件,只有小程序在前台时会回调。
bgm.onNext(function callback)监听用户在系统音乐播放面板点击下一曲事件(仅iOS)
bgm.onPrev(function callback)监听用户在系统音乐播放面板点击上一曲事件(仅iOS)

wx.request(Object object)网络请求

小程序必须使用 HTTPS/WSS 发起网络请求
不支持Promise
开发阶段可以在详情——本地设置中——勾选不校验 就可以避开https

在这里插入图片描述

项目Value
url接口地址
data请求的参数
header设置请求的 header
timeout超时时间,单位为毫秒。默认值为 60000
methodHTTP 请求方法(OPTIONS,GET ,POST,DELETE )…
dataType返回的数据格式 (json)返回的数据为 JSON.parse后的
responseType响应的数据类型 (text 响应的数据为文本,arraybuffer 一段二进制数据,用来模拟内存里面的数据)
success接口调用成功的回调函数
fail接口调用失败的回调函数
complete接口调用结束的回调函数(调用成功、失败都会执行)
object.success成功的回调函数
data返回的数据
statusCodeHTTP 状态码
headerHTTP Response Header
cookies返回的 cookies,格式为字符串数组
object.fail失败的回调函数
errMsg错误信息
errnoerrno 错误码

1.发送网络请求

 wx.request({
        url: 'http://t.talelin.com/v2/movie/top250',
        method:'GET',
        data:{
          start:0,count:2
        },
        success:(res)=>{
          console.log('数据',res.data)
        }
      })

使用async发送请求

//request.js
class Base{
  constructor(){
    this.baseUrl='http://t.talelin.com/v2/movie/'//基础路径
  }
  request(url,data={},method="GET"){
    return new Promise((resolve,reject)=>{
      wx.request({
        url: this.baseUrl+url,
        data,
        method,
        success:(res)=>{
          // 获取http状态码 只要以2开头就可以
          const code=res.statusCode
          if(code>=200&&code<300){
            resolve(res.data)
          }else{
             reject(code)
          }
        },
        fail:(err)=>[
          //失败两种,服务器没找到,不允许
          reject (err)
        ],
      })
    })
  }
}
export default Base;
//page.js
import Base from '../../utils/request'
const base=new Base()

  async getData2(){
    const res=await base.request('top250')
    console.log(res)
  },

page页面事件处理函数

onPageScroll(Object object)监听用户滑动页面事件。

 onPageScroll(e){
    console.log(e)
  },

在这里插入图片描述

wx.pageScrollTo(Object object)将页面滚动到目标位置

项目Value
scrollTop滚动到页面的目标位置,单位 px
duration滚动动画的时长,单位 ms
selector选择器(类似于 CSS 的选择器 id,class,子代,后代)
offsetTop偏移距离,需要和 selector 参数搭配使用,可以滚动到 selector 加偏移距离的位置,单位 px
success接口调用成功的回调函数
fail接口调用失败的回调函数
complete接口调用结束的回调函数(调用成功、失败都会执行)
wx.pageScrollTo({
  scrollTop: 0,
  duration: 300
})

获取dom

1.创建查询器

在组件里面用this.createSelectorQuery()
在页面里面用wx.createSelectorQuery()

const query = wx.createSelectorQuery();

2.选择元素

集合:const el=query.selectAll(‘.traffic’)
单个:const el= query.select(‘.tripinfotitlelist’)

3.元素指定内容

//1.全部查询(跟上4.)
el.boundingClientRect(()=>{})

//2.自身查询(就不用写第四个)
el.fields({size:true},res=>{
	console.log(res)//只查询size属性
}).exec()
size:宽高
daraset:自定义dataset
rect:布局 left,top...

//3.canvas节点查询
el.node((res)=>{}).exec()

4.执行查询

 query.exec(function (res) {
          //res就是 所有标签为mjltest的元素的信息 的数组
        
    });

在这里插入图片描述

canvas

<canvas type="2d" class="myCanvas"></canvas>
<button bindtap="onDrawImg">绘制图形</button>
<button bindtap="onDrawImg1">绘制图形1画布变大</button>
 onDrawImg(){
        const query=wx.createSelectorQuery();
        const el=query.select('.myCanvas');
        el.node((res)=>{
          // 获取canvas实例
          const canvas=res.node;
          // 获取画布绘制环境
          const ctx=canvas.getContext("2d");
          // 绘制图形
          ctx.fillStyle="pink";
          ctx.fillRect(50,50,100,100);
          // 画圆
          ctx.arc(100,100,50,0,2*Math.PI);
          ctx.stroke(); // 描边
        });
        query.exec();
      },
onDrawImg1(){
        const query=wx.createSelectorQuery();
        const el=query.select('.myCanvas');
        el.fields({size:true,node:true},(res)=>{
          // 获取canvas实例
          const canvas=res.node;
          // 将画布尺寸设置成跟画板尺寸一样大
          canvas.width=res.width;
          canvas.height=res.height;
          // 获取画布绘制环境
          const ctx=canvas.getContext("2d");
          
          // 画扇形
          ctx.beginPath();
          ctx.moveTo(150,150);
          ctx.arc(150,150,100,0,(45*Math.PI)/180,false);
          ctx.closePath();
          ctx.fill();
        });
        query.exec();
      },

修改画板大小

当画板变大时候,画布会自动拉满,图形就会变形
因此要手动修改大小,h5中width和height写在标签内的原因

下拉刷新和上拉加载

页面的下拉刷新和上拉加载

enablePullDownRefresh:true 下拉刷新

在这里插入图片描述

在这里插入图片描述

enablePullDownRefresh:true 在页面.json 或app.json中设置
在页面Page()构造器中的全局事件onPullDownRefresh()处理逻辑
在json中设置背景的样式

API
(1)wx.startPullDownRefresh()触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致
(2)wx.stopPullDownRefresh()可以停止当前页面的下拉刷新

需要手动设置wx.stopPullDownRefresh() 下拉窗口才会回去

onReachBottom() 监听用户上拉触底事件

onReachBottomDistance:300
在这里插入图片描述
在这里插入图片描述

局部的下拉刷新和上拉加载

<scroll-view 
scroll-top='{{y}}'     //滚动到某个位置
scroll-with-animation   //缓冲滚动到某个位置
scroll-y				//允许纵向滚动
bindscroll="onScroll"   //滚动时候触发:ScrollLeft, scrollTop...
bindscrolltolower="onReachBottom" //触底事件处理函数
refresher-enabled      //开启自定义下拉刷新 
bindrefresherrefresh="onPullDownRefresh" //下拉刷新处理函数
refresher-triggered="{{flag}}"   //下拉刷新的状态控制,用于关闭下拉框

>
 
  <block wx:for="{{list}}" wx:key="*this">
 	 <view class="item">{{item}}</view>
  </block>
</scroll-view>
页面局部(scroll-view)
上拉加载 : onReachBottom()bindscrolltolower=“fn”
下拉刷新(开启): json/“enablePullDownRefresh”: true,refresher-enabled
下拉刷新时间: onPullDownRefreshbindrefresherrefresh=“fn”
关闭下拉刷新: wx.stopPullDownRefresh()refresher-triggered=“{{flag}}”

上传照片

wx.chooseMedia()拍摄或从手机相册中选择图片或视频

项目Value
count最多可以选择的文件个数(默认9个)
mediaType[‘image’, ‘video’]文件类型
sourceType[‘album’, ‘camera’]图片和视频选择的来源
camera仅在 sourceType 为 camera 时生效,使用前置或后置摄像头

object.success 回调函数

tempFiles//	本地临时文件列表
tempFilePath//本地临时文件路径 (本地路径)
size//本地临时文件大小,单位 B
success(res) {
    console.log(res.tempFiles.tempFilePath)
    console.log(res.tempFiles.size)
  }

<button bind:tap="chooseImg">选择本地图片</button>

async chooseImg(){
   const res=await wx.chooseMedia({//默认最多9个
    count:3
   })
   const arr=res.tempFiles.map(item=>{//过滤出照片的地址
     return item.tempFilePath
   })
   console.log(arr)
  },

长按保存图片wx.saveImageToPhotosAlbum(Object object)

bindlongpress=“saveImg”

bindlongpress:手机触摸后超过350ms离开,如果指定回调就用回调,tap事件不会触发
保存图片到系统相册。

  saveImg(e){//长按保存图片
    const src=e.mark.src
    wx.saveImageToPhotosAlbum({
      filePath:src ,
    })
  },

点击预览照片wx.previewImage(Object object)

在新页面中全屏预览图片。预览的过程中用户可以进行保存图片、发送给朋友等操作。

wx.previewImage({
  current: '', // 当前显示图片的 http 链接
  urls: [] // 需要预览的图片 http 链接列表
})

上传文件wx.chooseMessageFile()、

下载图片

onSavePic() {
  // #ifdef MP-WEIXIN
  uni.getImageInfo({
    src: _this.imageUrl, // 图片下载网络地址
    success: function(e) {
      // e.type=png/jpg 扩展名
      // filePathNew: 指定文件下载后存储的路径 (本地路径)
      var filePathNew = wx.env.USER_DATA_PATH + "/" + new Date().valueOf() +'.'+e.type; 
      uni.downloadFile({
        url: _this.imageUrl, 
        filePath: filePathNew,
        success: (res) => {
          if (res.statusCode === 200) {
            uni.saveImageToPhotosAlbum({
              filePath: filePathNew,
              success: function() {
                uni.showToast({title: '保存到相册成功'});
              },
              fail: function(err){}
            });
          }
        }
      });
    },
    complete: function(e) {}
  });
  // #endif
},

下载文档

需要配置合法域名
1.wx.downloadFile()传入路径会返回一个临时文件路径
2.wx.saveFile()保存临时地址
3.wx.openDocument()打开文档

在这里插入图片描述

onOpenDocment() {
  uni.downloadFile({
    url: this.fileUrl,// 网络文档地址
    success: (data) => {
    if (data.statusCode === 200) {
        uni.saveFile({
          tempFilePath: data.tempFilePath, //临时路径
          success: function(res) {
            // 保存路径
            uni.showToast({ title: "文件已保存:"+res.savedFilePath,duration:3000 })
            setTimeout(()=>{
              //打开文档查看
              uni.openDocument({
                filePath:res.savedFilePath,
                success:function(res){
                  console.log('打开文档成功')
                }
              })
            }, 3000);
          }
        });
      }
    },
    fail: (err) => {
      uni.showToast({
        title: '失败请重新下载'
      });
    },
  });
},

自定义组件components

和普通页面的区别
1.组件的json文件要声明component:true
2.组件的js文件调用component()函数,普通页面调用page()
3.组件的方法函数定义在methods中,普通页面和data平级
4.组件生命周期定义在lifetimes

组件样式不受外界影响

修改样式隔离

修改样式隔离app.wxss 或页面的 wxss 中使用了标签名选择器(或一些其他特殊选择器)来直接指定样式,这些选择器会影响到页面和全部组件。通常情况下这是不推荐的做法。指定特殊的样式隔离选项 styleIsolation 。

项目Value
isolated表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
apply-shared表示页面影响自定义组件,但自定义组件不会影响页面;
shared表示页面样式影响自定义组件,自定义组件的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用。)
/写法一
Component({
  options: {
    styleIsolation: 'isolated'
  }
})
//写法二在json中
{
  "styleIsolation": "isolated"
}

1.创建组件文件夹

在这里插入图片描述

2.引入方式(全局+局部)

//全局 app.json中
{
	"usingComponents":{
		"c-text":"components/text/text"
	}
}
//局部 页面.json中
{
	"usingComponents":{
		"c-text":"/components/text/text"
	}
}

3.在页面中使用

<c-text></c-text>

组件间传值

1.父——>子 (自定义属性)

//父
<c-book1 book="{{bookData}}"></c-book1>
//子
  properties: {
    book:Object
  },
  properties: {//完整定义
    book:{
    type:Object,
    value:{}//默认值
    }
  },

流程:父组件绑定自定义属性=要传递是数据,子组件在properties中定义该属性,接收传递下来的数据,讲数据绑定到子组件页面上

2.子——> 父(自定义事件)

//父
<c-book1 wx:if="{{flag}}" book="{{bookData}}" bind:getId="fn"></c-book1>

  fn(e){
    console.log(e.detail)//传来的值
  }
//子
<view class="book" bindtap="onTap">
methods: {
    onTap(){
      //通知父组件事件被触发,携带数据
      this.triggerEvent('getId',{id:id},{bubbles:true})
      // 第一个参数:父组件的事件名字
      //第二个参数:要携带的数据
      //第三参数:是否冒泡
    },
  },

流程:给子组件绑定一个事件,在事件处理程序中利用this.triggerEvent(‘父组件的自定义事件名’,{要传递的数据})激活父组件的自定义事件,在父组件事件处理程序中e.detail拿到数据

组件的生命周期

lifetimes:{}中写

lifetimes:{}Value
created(){}组件实例被创建
attached(){}组件进入页面
ready(){}组件在页面布局完成
moved(){}组件位置发生变化
detached(){}组件在页面销毁
lifetimes:{
    created(){
      console.log('组件实例被创建')
    },
    attached(){
      console.log('组件进入页面')
    },
    ready(){
      console.log('组件在页面布局完成')
    },
    moved(){
      console.log('组件位置发生变化')
    },
    detached(){
      //利用wx:if
      console.log('组件在页面销毁')
    }
  }

组件所在页面的生命周期

pageLifetimes

项目Value
show组件所在页面被展示时执行
hide被隐藏时执行
resize尺寸发生变化时
Component({
	pageLifetimes:{
	    hide(){},
	    show(){},
	    resize(size){}
 	}
})

插槽

单个插槽

单插槽:组件中利用slot标签占位,使用组件在组件内部写子元素。

//组件.wxml
<c-tag content="{{txt1}}">
	<text>+1</text>
</c-tag>
//插槽.wxml
<view>
  <!-- 插槽占位符slot -->
  <slot></slot>
</view>

多个插槽

多插槽:组件利用slot标签的name属性指定插槽名字,使用时候在组件的js中开启多插槽支持 options:{ //开启多插槽 multipleSlots:true },
使用组件时在组件内部写元素用slot="footer"属性区分

//组件.wxml
<c-tag content="{{txt2}}">
  <image src="/images/jd.png" slot="avatar" class="img"></image>
  <text slot="add">+1</text>
</c-tag>
//插槽.wxml
<view>
	<slot name="avatar"></slot>
	<text>{{content}}</text>
	<slot name="add"></slot>
</view>

Behavior({}) 抽离组件公共逻辑(作用于组件)

包含组件的属性和方法,声明周期
一个组价可以有多个behavior,behavior也可以引用behavior

1.创建文件夹

在这里插入图片描述

2.创建behavior文件+共享

export default Behavior({
  //组件公共的属性
  properties:{
    content:String
  },
  //组件的公共的方法
  methods:{
    onTap(){
      console.log(this.properties.content)
    }
  },
  lifetimes:{}
})

组件中使用

import bh from '../behaviors/bh'
Component({
  //整合公共逻辑
  behaviors:[bh]
})

外部样式类

//1.wxml 页面
 <c-tag1 content="tag1的标题" ex-green="green" img="/images/1.jpg"></c-tag1>
 <c-tag1 content="tag1的标题" ex-pink="pink" img="/images/1.jpg"></c-tag1>
//1.wxss 页面
.green{
  background-color: chartreuse !important;
}
.pink{
  background-color: pink !important;
}
// 组件.wxml
 <text class="title ex-green ex-pink" bindtap="onTap">{{content}}</text>
// 组件.js
import bh from '../behaviors/bh'
Component({
  //整合公共逻辑
  behaviors:[bh],
  //接收外部传入的样式类
  externalClasses:["ex-green","ex-pink"],
})

observer/observers 监听器(在组件中使用)

//监听单一值
 properties: {
    a:{
      type:Number,
      value:0,
       observer(newVal,oldVal){
         console.log('新值'+newVal+'旧值'+oldVal)        
       }
    },
    }
//多个属性用,号隔开
 observers:{
    'a,b,obj.c':function(newA,newB,newC){
	 console.log(newA,newB,newC)      
    },
    }
//监听对象的多个属性
 observers:{
    'obj.**':function(newObj){
	 console.log(newObj.a)      
    },
    }

地图

app.json设置

requiredPrivateInfos(有的时候不加也出来了)

详情点链接

//app.json
 "requiredBackgroundModes": ["audio","location"],
  "requiredPrivateInfos": [ "getLocation","choosePoi" ],
  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序位置接口的效果展示"
    }
  }

在这里插入图片描述

wx.getLocation(Object object)获取当前的地理位置、速度

 const res=await wx.getLocation();
       console.log("地理位置",res);
      //  获取当前位置的经纬度
      const {latitude,longitude}=res;
      // 以当前点为中心展开一片地图
      wx.openLocation({
        latitude,
        longitude,
      })

在这里插入图片描述

项目Value
typewgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标
altitude传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度
isHighAccuracy开启高精度定位 (true/false)
highAccuracyExpireTime高精度定位超时时间(ms),指定时间内返回最高精度,该值3000ms以上高精度定位才有效果
success接口调用成功的回调函数
success成功回调Value
latitude纬度,范围为 -90~90,负数表示南纬
longitude经度,范围为 -180~180,负数表示西经
speed速度,单位 m/s
accuracy位置的精确度,反应与真实位置之间的接近程度,可以理解成10即与真实位置相差10m,越小越精确
altitude高度,单位 m

wx.choosePoi()打开 POI 列表选择位置,支持模糊定位(精确到市)和精确定位混选。

success回调Value
type选择城市时,值为 1,选择精确位置时,值为 2
city城市名称
name位置名称
address详细地址
latitude纬度,浮点数
longitude经度,浮点数

在这里插入图片描述

async choosePoint(){
      const res=await wx.choosePoi();
      console.log("您的位置是",res);
    },

wx.openLocation()使用微信内置地图查看位置

在这里插入图片描述

项目Value
latitude纬度
longitude经度
scale缩放比例,范围5~18
name位置名
address地址的详细说明
success接口调用成功的回调函数
wx.getLocation({
 type: 'gcj02', //返回可以用于 wx.openLocation 的经纬度
 success (res) {
   const latitude = res.latitude
   const longitude = res.longitude
   wx.openLocation({
     latitude,
     longitude,
     scale: 18
   })
 }
})

wx.chooseLocation()

wx.chooseAddress()获取用户收货地址。

wx.chooseAddress({
  success (res) {
    console.log(res.userName)//收件人姓名
    console.log(res.postalCode)//邮编
    console.log(res.provinceName)//一级地址
    console.log(res.cityName)//二级地址
    console.log(res.countyName)//三级地址
    console.log(res.detailInfo)//详细地址
    console.log(res.nationalCode)//新选择器详细收获地址
    console.log(res.telNumber)//收获地址国家码
  }
})

请添加图片描述

地图组件map

项目Value
longitude中心经度 1.0.0
latitude中心纬度 1.0.0
markers标记点
circles
polyline路线
<map name="myMap" 
	longitude="{{lng}}" 
	latitude="{{lat}}" 
	markers="{{markers}}" 
	circles="{{circles}}"></map>
showMarker(){//展示标记点
    const marker={
      id:1,
      latitude:this.data.lat,
      longitude:this.data.lng,
      iconPath:'https:....',
      width:30,
      height:30,
    }
    this.setData({
      markers:[marker],
    })
  },
showCircle(){//展示圆圈
    const circle={
      latitude:this.data.lat,
      longitude:this.data.lng,
      radius:200,
    }
    this.setData({
      circles:[circle],
    })
  },

使用腾讯地图

1.登录/注册腾讯地图api

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

3.开通webserviceAPI服务:控制台 ->应用管理 -> 我的应用 ->添加key-> 勾选WebServiceAPI -> 保存

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

复制到小程序里( 这俩那个都行)

在这里插入图片描述

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

在这里插入图片描述

6.页面使用(腾讯地图文档微信小程序JavaScript SDK)

//第一步引入腾讯地图
const QQMap=require('../../utils/qqmap-wx-jssdk')
//实例化腾讯地图
const qqmap=new QQMap({key:'DGKBZ-VZ4CV-CETPR-UDGJ5-CO5V6-****'})

坐标转地址(使用腾讯地图)

 async getAddress(){//坐标转地址
    const res=await wx.getLocation();
    const {latitude,longitude}=res;
//使用腾讯地图将坐标点转为具体地址
    qqmap.reverseGeocoder({
      location:{latitude,longitude},
      success:res=>{
        console.log('当前坐标点对应的地址是',res)
      }
    })
  },

地址转坐标(使用腾讯地图)

  qqmap.geocoder({
      address:'北京市昌平区......',
      success:res=>{
        const {lat:latitude,lng:longitude}=res.result.location;
        //以当前经纬度展开地图
        wx.openLocation({
          latitude,
          longitude
        })
        //利用腾讯地图搜索周边
        qqmap.search({
          keyword:"餐饮",
          location:{latitude, longitude},
          success:res=>{
            console.log('搜索结果',res)
          }
        })
      }
    })

搜索周边地点

//利用腾讯地图搜索周边
        qqmap.search({
          keyword:"餐饮",
          location:{latitude, longitude},
          success:res=>{
            console.log('搜索结果',res)
          }
        })

获得城市列表(使用腾讯地图)

qqmap.getCityList({
      success:res=>{
        console.log("城市列表",res)
      }
      })

登录

在这里插入图片描述

wx.getSetting()获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。

wx.getSetting({
  withSubscriptions: true,
  success (res) {
    console.log(res.authSetting)
    // res.authSetting = {
    //   "scope.userInfo": true,
    //   "scope.userLocation": true
    // }
    console.log(res.subscriptionsSetting)
    // res.subscriptionsSetting = {
    //   mainSwitch: true, // 订阅消息总开关
    //   itemSettings: {   // 每一项开关
    //     SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戏系统订阅消息
    //     SYS_MSG_TYPE_RANK: 'accept'
    //     zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性订阅消息
    //     ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
    //   }
    // }
  }
})

wx.login ()获取登录凭证code

  1. 使用 wx.checkSession 检查当前用户小程序登录态是否有效
  2. 使用 wx.getStorageSync(‘token’) 检查本地缓存中是否保存有后端返回的 token
  3. 如果小程序登录态已失效,或者 token 为空,须先执行登陆流程
  4. wx.login 获取code(code有时效) 并 wx.request 提交 code 给己方服务器
  5. 服务器 提交Appid (小程序编号)+ appSecret(小程序密钥) + code 到微信方服务器 获取 session_key (密匙)& openid(每个用户在每个小程序中的唯一固定编号)
  6. 服务器 根据 session_key & openid 返回 一段密文 到小程序端
  7. 小程序端 wx.setStorage 存储 密文 在后续用户操作需要凭证时 附带该参数
wx.login({
  success (res) {
    if (res.code) {
      //发起网络请求
      wx.request({
        url: 'https://example.com/onLogin',
        data: {
          code: res.code
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

用户第一次登录之后若再次登录,则进行自动登录或登录态过期需要手动授权登录,自动登录需要检查用户信息及登录态是否过期

wx.checkSession(Object object)检查登录态是否过期

//如果app.js中有wx.login就会一直显示success

wx.checkSession({
  success () {
    //session_key 未过期,并且在本生命周期一直有效
  },
  fail () {
    // session_key 已经失效,需要重新执行登录流程
    wx.login() //重新登录
  }
})

获取个人信息wx.getUserProfile(),头像和名字

在这里插入图片描述

wx.getUserProfile({
      desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })

传统开发模式登录流程

  1.获取身份信息
    登录wx.login拿到code码
    wx.login({
      success:(res)=>{
        const code=res.code
        wx.request({
          url:'登录接口',
          data:{code},
          success:(res)=>{
            //获取身份令牌,保存到本地
            const token=res.data.token
            wx.setStorageSync('token',token)
          }
        })
      }
    })
    //获取我的订单列表
    wx.request({
      url:'订单请求地址',
      header:{//因为get在地址栏后面数据不安全,所以在请求头里面携带数据
        token:wx.getStorageSync('token')
      },
      success:(res)=>{
        if(验证通过){
          //返回订单数据
        }else{
          //验证不通过(没有token,token过期,权限不够)
          重新获取token(走上面12-19的步骤)或者换一个权限高的
        }
      }
    })

获取手机号

在这里插入图片描述

getPhoneNumber 返回的 code 与 wx.login 返回的 code 作用是不一样的,不能混用

  • 新版获取手机号不需要login。需要用户自己点击button,返回 加密的手机号,发送code和openid到己方服务器
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
Page({
  getPhoneNumber (e) {
    console.log(e.detail.code)//decf01b9011837d57a60a6cc9....
  }
 

云函数获取身份标识

见下面

云服务

1.打开云服务

如果第一次用需要注册

在这里插入图片描述

2. 初始化云能力, wx.cloud.init()

在这里插入图片描述

//app.js
 onLaunch(){
    // 初始化云能力
    wx.cloud.init({
      env:'lianxi-6g94su9j2e6cd4d9'//id
    })
  }

3.获取数据库

//页面.js
//获取数据库
const db=wx.cloud.database();
//获取集合
const userList=db.collection("userList")

4.操作数据库

(1)增

 userList.add({
      data:{name:"张三",age:"20",sex:"男"}
    })

在这里插入图片描述

(2)删 .remove()

 userList.doc('6842667962df62750a10484a5676d23c').remove()

(3)改

(3.1)更新数据.update()

userList.doc("0a4ec1f962df6289124ce78e2f9a7038").update({
      data:{age:23}
    })

(3.2)重置数据.set()

 userList.doc('6842667962df62750a10484a5676d23c').set({
      data:{age:20}
    })

在这里插入图片描述

没有_openid就只读不能改

(4)查.get()

(4.1)获取全部数据.get()

    const res=await userList.get()
    console.log(res.data)

(4.2)获取某个数据.doc(id)

   const res1=await userList.doc('0a4ec1f962df6289124ce78e2f9a7038').get()
    console.log(res1.data)

(4.3)有条件的查询(查询性别为男的).where()

const res2=await userList.where({
  sex:'男'
}).get()
console.log(res2.data)

(4.4)查询限制个数查询limit(num)

const res3=await userList.limit(3).get()
console.log(res3.data)

(4.5)指定查询起点 .skip(num)

4.4+4.5可以做分页效果

const res4=await userList.skip(2).get()
console.log(res4.data)

(4.6)查询数据并排序 (取年级从小到大排列) (asc升序)(desc降序).orderBy()

const res5=await userList.orderBy('age','asc').get()
console.log(res5.data)

(4.7)筛选查询字段 (取只返回name).field()

const res6=await userList.field({name:true}).get()
console.log(res6.data)
//总结:这几个方法可以任意组合
const res7=await userList.where({ sex:'男'})
.orderBy('age','asc')
.limit(2)
.field({name:true,age:true})
.get()
console.log(res7.data)

数据操作符

//先获取数据操作符
const _=db.command;

//条件可以是范围20岁以上的(_.gt(20)大于20)
	 const res8=await userList.where({ age:_.gt(20)}).get();
    console.log("年级超过20岁的同学",res8.data)

(4.8) 获取数据总数.count()

get() 区别只返回数量,不会返回对象数组
  async onTotal(){
    const res=await userList.count()
    console.log(res)
  },

在这里插入图片描述

云函数

1.在project.config.json中指定云函数的根目录

  "cloudfunctionRoot": "functions/",

在这里插入图片描述

在这里插入图片描述

2.新建云函数

右键新建Node.js云函数

在这里插入图片描述

在这里插入图片描述

3.在新建的云函数index.js中编写代码

4.云能力初始化

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

//云能力初始化
cloud.init({
  env:'lianxi-6g94su9j2e6c****'
})

// 云函数入口函数
//传入的都在event
exports.main = async (event, context) => {
 const s=event.a+event.b
 return s
}

5.写完长传并部署云端安装依赖

在这里插入图片描述

在云函数里操作数据库

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

cloud.init({
  env:'lianxi-6g94su9j2e6cd4d9'
})
//获取数据库
const db=cloud.database()
//获取集合
const userList=db.collection("userList")

// 云函数入口函数
exports.main = async (event, context) => {
  return await userList.get()
}

页面中使用

//可以利用success回调/promise.then/async+await拿到数据
 wx.cloud.callFunction({//要调用的那个云函数
      name:'add',
      data:{a:1,b:3},
      success:(res)=>{//使用回调拿到
        console.log(res)
      }
    })

云函数获取身份标识

 wx.cloud.callFunction({
      name:'getID',
      success:(res)=>{
        console.log(res.result)//和数据库的openid相同
      }
    })
//getID的云函数的index.js
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  return wxContext.OPENID //openid
}

在这里插入图片描述

获取服务器时间db.serverDate()

云存储

在这里插入图片描述

wx.cloud.uploadFile()将本地资源上传至云存储空间

如果上传至同一路径则是覆盖写

项目Value
filePath要上传文件资源的路径
cloudPath云存储路径

上传图片到云内存,并在页面显示出来

 async uploadFiles(){
       const res=await wx.chooseMedia();
        // 获取多张图片路径数组
        const pathArr=res.tempFiles.map(item=>{
          return item.tempFilePath;
        });
        // 创建匹配后缀的正则表达式
        const reg= /\.\w+$/;
        const arr=[];
        pathArr.forEach(path=>{
          // 获取当前这张图片的后缀
         const suffix=reg.exec(path)[0];
         const p= wx.cloud.uploadFile({
            filePath:path,
            cloudPath:`***/img${Math.random()}${suffix}`,//保存到***下的文件夹里面
          })
        arr.push(p)
        })
      //当图片所有图片都成功拿到结果,执行下一次操作
      const result=await Promise.all(arr)//上传多个图片要,都上传完才能拿到所有的
      const imgArr=result.map((item)=>{
        return item.fileID
      })
      this.setData({imgArr})
      },

上传文件

//选择本地文件
      const res = await wx.chooseMessageFile();
      console.log("选择结果", res);
      // 选择上传的第一个文件
      const file = res.tempFiles[0];
      // 拿到该文件的名字和路径
      const { name, path } = file;
      // 将该文件上传至云存储
      const result = await wx.cloud.uploadFile({
        filePath: path,
        cloudPath: "2009b/" + name,
      });
      console.log("上传结果", result);

wx.cloud.downloadFile()下载文件

下载图片或文件

const res=await  wx.cloud.downloadFile({
        fileID:'cloud://lianxi-6***1241440970242.png',})
        //res 拿到一个本地的临时id
      //将下载的图片保存到相册
      wx.saveImageToPhotosAlbum({
        filePath: res.tempFilePath,
      })

      // 打开该文件
      wx.openDocument({
        filePath: path,
      });

wx.cloud.deleteFile()删除文件

 wx.cloud.deleteFile({
        fileList: [
          "cloud://cloud1-7***.docx",
          "cloud://cloud1-7gna5m2cd***.jpg",
        ],
      });

wx.cloud.getTempFileURL()获取真实链接

 async geturl() {
      const res = await wx.cloud.getTempFileURL({
        fileList: [
          "cloud://cloud***477825.jpg",
        ],
      });
      console.log("真实链接", res);
    },

Mobx

在这里插入图片描述

https://github.com/wechat-miniprogram/mobx-miniprogram-bindings

修改数据

 
export const store = observable({
  // 数据字段
  obj:[{
    name:'张三',
  }],
  // actions
  update: action(function (num) {
    this.obj=[...this.obj,num]
  }),
   update2: action(function (num) {
     this.obj=[...this.obj.slice(0,1)]
  }),
});

page里面打印数据

wx.nextTick(()=>{
      console.log(this.data.obj)
    })

wx.getAccountInfoSync() 获取当前帐号信息。

开发环境
在这里插入图片描述

微信支付

支付方式
1.展示固定的收款码,扫码支付
2.动态生成收款码,微信扫码支付
3.第三方网站/app,跳转到微信支付,支付完跳转回去
4.公众号嵌入的网页中,不用跳转,直接唤起微信支付
5.小程序中,直接唤起微信支付

在这里插入图片描述

微信小程序支付过程

  1. 已登录用户在小程序中调用商户系统后台接口下单
  2. 商户系统后台生成平台订单,并调用微信支付系统下单接口生成预付单
  3. 商户系统后台生成带签名的支付参数信息返回给小程序
  4. 用户在小程序中使用收到的参数调用wx.requestPayment发起微信支付
  5. 微信支付系统异步通知商户系统后台支付结果,并返回给小程序执行
    wx.requestPayment的回调函数
  6. 用户在小程序中调用商户系统后台查单接口查询支付状态
 const order = await request.post('/order', {
      phone,
      meal_time: '立即取餐',
      meal_type: '打包带走',
      products: [{ id: 181, count: 1 }],
      pay_type: '微信支付',
      desc: '7日包5G-wyx'
    });
    let payInfo={};
        if (order.errmsg === '已存在未完成的订单') {
          const info = await request.get('/order/current');
          payInfo=info.data.pay_info;
        }else{
          payInfo=order.data;
        }
        wx.requestPayment(payInfo);
        //requestPayment,success不一定就付钱了,需要再请求一个接口判断是否真付钱了

1.先调用后端支付接口,获取requestPayment需要的数据

在这里插入图片描述

2.使用wx.requestPayment(Object object),把接口获取到的数据传过去

项目Value
timeStamp时间戳,从 1970 年 1 月 1 日 00:00:00 至今的秒数,即当前的时间
nonceStr随机字符串,长度为32个字符以下
package统一下单接口返回的 prepay_id (预付单)参数值,提交格式如:prepay_id=***
signType签名算法,应与后台下单时的值一致
paySign签名,具体见微信支付文档

wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success (res) { },
  fail (res) { }
})

二次支付

第一次请求是吧(预设单id)prepay_id存起来,第二次是使用第一次的prepay_id发起支付

从前端的角度来梳理微信支付(小程序、H5、JSAPI)的流程

云函数统一下单

https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/open/pay/CloudPay.unifiedOrder.html

支付流程

分享

1.button open-type="share"设置

<button open-type="share">分享给好友</button>

2.onShareAppMessage设置

Page({
  onShareAppMessage() {//分享
    return {
      title: '充值优惠',
      path: '/pages/pay/pay',
      imageUrl:'../../images/banner-top.jpeg',
   // promise 属性可以动态设置这些
    }
  },})

在这里插入图片描述

自定义导航栏navigation

1.“navigationStyle”: “custom”

局部的.json文件或者app.json全局设置
wx.getSystemInfo()获取屏幕全部信息
wx.getMenuButtonBoundingClientRect()获取按钮的

// app.js
App({
  onLaunch() {
    //自定义导航栏 获取设备顶部窗口的高度(不同设备窗口高度不一样,根据这个来设置自定义导航栏的高度)
    wx.getSystemInfo({
      success: (res) => {
        let custom = wx.getMenuButtonBoundingClientRect()
        this.globalData.statusBarHeight = res.Hieght
      }
    })
  },
  globalData: {
    statusBarHeight: 0,
  }
})

在这里插入图片描述

//在页面getapp().globalData.statusBarHeight获取

客服

1.点击按钮接入客服

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

2.在微信公众平台添加客服
在这里插入图片描述
3.用户向客服发起对话
在这里插入图片描述

  1. 客服人员可以登录移动端/网页版客服

客服回话
在这里插入图片描述

自定义tabBar

1、app.json中修改tabBar:{custom:true}

如果自定义显示不了,就显示list里面的数据
自定义样式需要取消样式隔离

{
  "tabBar": {
    "custom": true,
    "color": "#000000",
    "selectedColor": "#000000",
    "backgroundColor": "#000000",
    "list": [{
      "pagePath": "page/component/index",
      "text": "组件"
    }, {
      "pagePath": "page/API/index",
      "text": "接口"
    }]
  },
  "usingComponents": {}
}

2. 创建根目录custom-tab-bar文件夹+四个文件

index.js
index.json
index.wxml
index.wxss

3.点击跳转切换

样式参考 vant-ui自定义tabBar

//使用list遍历
data:{
	list:[{
      "pagePath": "page/component/index",
      "text": "组件"
    }, {
      "pagePath": "page/API/index",
      "text": "接口"
    }]
}
//通过数据遍历渲染tabBar

或者使用navigator

<view>
  <navigator open-type="switchTab" url="/pages/pay/pay" class="{{active=='pay'?'active':''}}">
    充值
  </navigator>
  <navigator open-type="switchTab" url="/pages/welfare/welfare"  class="{{active=='welfare'?'active':''}}">
    福利
  </navigator><navigator open-type="switchTab" url="/pages/my/my"  class="{{active=='my'?'active':''}}">
    我的
  </navigator>
</view>

 data: {
    active: 'pay',//当前高亮   
  },

//在每个页面
  onShow(options) {
   const tabbar=this.getTabBar()
   tabbar.setData({
       active:'pay',
   })
  },

4.全局数据中设置选中的那一项的索引getTabBar修改索引

通过getTabBar()可以拿到tabBar页面的实例,然后setData
每次跳转页面修改索引,才能做到tabBar样式跟着页面动

 const tabbar= this.getTabBar()
   tabbar.setData({
       active:'pay',
   })

或者获取当前的页面栈getCurrentPages(),查找对应修改active

	init() {
			const page = getCurrentPages().pop();
			this.setData({
				active: this.data.list.findIndex(item => item.url === `/${page.route}`)
			});
		}
//每个页面设置		
this.getTabBar().init();

分包

一个完整的项目,按需求分为不同子包,构建时打包成不同分包,使用时按需加载
优点:优化小程序首次启动下载时间,解耦操作
1主包+多个分包<=16M
主包:启动页面+tabBar页面
分包:只包含分包有关的页面+资源<2M

主包不能引用私包的资源,分包不能互相引用
分包可以引用主包的
在这里插入图片描述

在app.json的subpackages字段声明项目分包结构:
	{
	  "pages":[			主包
	    "pages/index",
	    "pages/logs"
	  ],
	  "subpackages": [	分包	
	    {
	      "root": "packageA",	
	      "pages": [
	        "pages/cat",	相对于root分包的路径
	        "pages/dog"
	      ]
	    }, {
	      "root": "packageB",
	      "name": "pack2",
	      "pages": [
	        "pages/apple",
	        "pages/banana"
	      ],
	      independent:true|false分包是否是独立分包
	      
	    },
	  ]
	}

独立分包

可以独立于主包和其他分包单独运行(使用独立分包就可以打开程序)
和普通分包的区别:是否依赖主包
普通分包必须依赖主包,独立分包不下载主包,可以独立运行
(不能引用彼此资源)
independent:true|false分包是否是独立分包

 {
	      "root": "packageB",
	      "name": "pack2",
	      "pages": [
	        "pages/apple",
	        "pages/banana"
	      ],
	      independent:true//独立分包
	    },

分包预下载

在进入小程序某个页面的时候,自动下载可能需要的分包,提升启动速度,如点击我的页面,自动下载dog和cat页面<2M

 "preloadRule": {		//进行预下载
	    "pages/index": {	//触发下载的页面路径
	      "network": "all",			//指定网络下载,all不限网络、wifi:仅wifi下预下载
	      "packages": ["packageB"]	//进入页面之后预下载那些包可以是分包的root或name
	    },
	  }

小技巧

输入框

 <view>
  <text>a输入的值</text>
  <input type="text" confirm-type="search" bindconfirm="onComfirm1"/>
  // confirm-type="search" 修改确认按钮文字
  //bindconfirm按确认按钮之后
  
 </view>

将数据写入全局数据

//App.js
App({
  globalData:{
    userInfo:123
  }
})

整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全局唯一的 App 实例,获取 App 上的数据或调用开发者注册在 App 上的函数。

//组件.js 写法一
  onLoad(options) {
    getApp().globalData.userInfo=456
    getApp().globalData.abc=45555556
    console.log(getApp().globalData.userInfo)
  },
//组件.js 写法二
var app = getApp();
Page({
...
app.globalData.userInfo
...
});

数据存到缓存和全局的区别

缓存中的数据一直存在,全局中的数据只在小程序运行的时候存在,关掉之后就没有了,用于存(背景音乐id,是否有歌曲等)

更换图标

在这里插入图片描述

人气星星

在这里插入图片描述

//stars=48
<block wx:for="{{5}}" wx:key="*this">
          <image src="{{stars>(index+1)*10?'/images/icon/star.png':'/images/icon/no-star.png'}}"></image>
 </block>
//使用wxs
<block wx:for="{{util.toArr(stars)}}">//wxs处理数据传入48返回[ true,true,true,true,false],根据数组判断图片是否显示
          <image src="{{item?'/images/icon/star.png':'/images/icon/no-star.png'}}"></image>
 </block>
//util.wxs
function toArr(num){
  if(!num){
    return
  }
  var arr=[]
  var num1=Math.floor(num/10)
  for(var i=0;i<num1;i++){
    arr.push(true)
  }
  // arr.fill(false,num1-1)
  var num2=5-arr.length
  for(var i=0;i<num2;i++){
    arr.push(false)
  }
  return arr
}
module.exports={toArr:toArr}

小程序显示svg图标 通过转=>base64

1.转base64网站

2.页面

<view class="v1"></view>


.v1{
  width:50rpx;
  height: 50rpx;
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bW...");
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

使用和风天气

开发文档地址:https://dev.qweather.com/docs/api/

(1)注册和风天气账号,申请key

登录账号->登录控制台->应用管理->创建应用->添加数据key

(2)配置小程序合法安全域名

小程序管理后台->开发>开发管理->开发设置->修改->合法域名配置request字段

使用icon图标

1.阿里巴巴选择需要的添加到项目

在这里插入图片描述

2.修改base64

在这里插入图片描述

3.下载

在这里插入图片描述

4.添加到小程序修改iconfont.css=>wxss

在这里插入图片描述

5.使用

<view class="iconfont icon-shoujitaobao"></view>

在这里插入图片描述

获取当前时间

  let dataTime
  let yy = new Date().getFullYear()//年
  let mm = new Date().getMonth()+1//月
  let dd = new Date().getDate()//日
  let hh = new Date().getHours()//
  let mf = new Date().getMinutes()<10?'0'+new Date().getMinutes():new Date().getMinutes()
  let ss = new Date().getSeconds()<10?'0'+new Date().getSeconds():new Date().getSeconds()
    dataTime = `${yy}-${mm}-${dd} ${hh}:${mf}:${ss}`;
    //2022-10-23 12:23:43

flex布局第二行两边对齐问题

在这里插入图片描述

.cont{
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
  // 这里使用伪元素
 .cont::after {
 	display:block;
    content: '';
    width: 400px;
  }

wx.showToat()跟着wx.showToat()

 wx.showToast({
      title: '123',
      icon:'loading',
      duration:5000,
      success:()=>{
        setTimeout(()=>{
          wx.showToast({
            title: '678',
            duration:4000
          })
        },5000)
      }
    })

获取当前页面栈 getCurrentPages()

在这里插入图片描述

使用表单form统一获取表单项的值

监听form的submit
每一个表单项加name
提交按钮form-type=“submit”
通过form 的bindsubmit事件的回调参数event获取所有表单项的值

<form bindsubmit="onSubmit">
  <input name="phone"  placeholder="手机号"/>
  <input name="label"  placeholder="标签"/>
  <button form-type="submit">确定</button>
</form>

小程序json-server环境搭建

1.安装

npm install -g json-server

2.跟目录创建myserver文件夹,创建json数据

在这里插入图片描述

3.进入myserver文件夹

//执行这个
json-server --watch db.json
//db.json,存放数据
{
  "tabList": [
    {
      "id": 1,
      "image": "http://vivo.njzykeji.com/static/img/xuangou.jpg"
    } 
    ]
}

4.package.json设置快捷打开服务,默认打开3000服务器

{
    "scripts": {
        "mock": "json-server db.json --port 3000"
    }
}

5.npm run mock打开服务

6.使用数据

wx.request({
            url: 'http://localhost:3000/tabList',
            method:'GET',
            success:(res)=>{
              this.setData({
                tabList:res.data
              })
            }
          })

上线流程

如果是uniapp开发,使用小程序预览,先切换为线上url地址,从新运行到小程序,然后点击上传,输入修改信息,然后登录微信公众平台,版本管理进行上传审核

在这里插入图片描述
在这里插入图片描述
在小程序公众平台 上传
在这里插入图片描述
版本管理分为开发,审核,线上。先提交开发版本,然后审核,上线(上线可以一开始都传上去,也可以一点点更新)
在这里插入图片描述

分享页面全局设置

添加链接描述

微信小程序没有全局分享配置,只能用页面onShareAppMessage 才可以。

// app.js
/**
 * 全局分享配置,页面无需开启分享
 * 使用隐式页面函数进行页面分享配置
 * 使用隐式路由获取当前页面路由,并根据路由来进行全局分享、自定义分享
 */
// app.js
App({
  globalData: { },
  onLaunch() { this.overShare()},
  overShare: function() {
          // 调用隐藏路由回调
       wx.onAppRoute(function(res) {
           //获取加载的页面
           let pages = getCurrentPages(),
           //获取当前页面的对象
             view = pages[pages.length - 1],
            if (view) {
              data = view.data;
              if (true || !data.isOverShare) {
               data.isOverShare = true;
                view.onShareAppMessage = function() {
                  //重写分享配置
                return {
                   title: '分享标题',
                  path:'page/index/index',
                  imageUrl:'/utils/未标题-1.jpg'
                 };
                }
              }
            }
         })
  },})

map ios不显示

在这里插入图片描述

不能是number,必须是string

A—>B修改A的值

添加链接描述

//b页面点击一个事件,
 <view  bindtap='supItemClick' data-id="{{item.id}}" data-name="{{item.name}}"></view>
  supItemClick:function(e){
    var name=e.currentTarget.dataset["name"];
    var pages = getCurrentPages();
    var prevPage = pages[pages.length - 2]  //上一个页面
    prevPage.setData({
      ["selectedSup.supName"]:name
    });
    wx.navigateBack({
      delta: 1,
    });
  },
}) 

setDate修改指定值

改变对象的值

Page({
    data: {
        // 默认的数据
        objs: {
            sex: "女",
        },
    },
    // 点击事件
    btnClick() {
        this.setData({
            ['objs.sex']: "男",
        })
    },
})

改变数组的值

const app = getApp()
Page({
    data: {
        // 默认的数据
        imgData: [{
            imgTit: "风景图1",
            imgUrl: "https://img0.baidu.com/it/u=530426417,2082848644&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1656522000&t=0050fe01b5db9476166821b30d44655c",
        }],
    },
    // 点击事件
    btnClick() {
        //数组动态赋值
        const imgOne = "imgData[0].imgUrl";
        this.setData({
            [imgOne]: "https://img0.baidu.com/it/u=3643895624,2552772604&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675",
        })
    },
})

1px线

  .no-more--line {
    position: relative;
    width: 80rpx;
  }
    /* 1px边框 */
    .no-more--line:after {
      position: absolute;
      box-sizing: border-box;
      -webkit-transform-origin: center;
      transform-origin: center;
      content: ' ';
      pointer-events: none;
      top: -50%;
      right: -50%;
      bottom: -50%;
      left: -50%;
      border: 0 solid #eee;
      border-width: 1px;
      -webkit-transform: scale(0.5);
      transform: scale(0.5);
    }

在这里插入图片描述

小程序下载文件,删除下载的临时文件downloadFile()

wx.downloadFile({
        url: url,
        success: (res) => {
          var savePath = wx.env.USER_DATA_PATH + '/' + this.getFileName(url);
          const fs = wx.getFileSystemManager();
          fs.saveFile({ //下载成功后保存到本地
            tempFilePath: res.tempFilePath,
            filePath: savePath,
            success(res2) {
              //获取了相册的访问权限,使用 wx.saveImageToPhotosAlbum 将图片保存到相册中
              wx.saveImageToPhotosAlbum({
                filePath: savePath,
                success: () => {
                  // 保存完成后删除本地缓存文件
                  fs.unlink({
                    filePath: savePath,
                    fail(errmsg) {
                      console.log('remove file fail:', errmsg);
                    }
                  });
                },
                fail(err) {
                }
              });
            },
            fail(err2) {
            }
          });
        },
        fail: (err) => {
          console.log('download error', err);
        }
      });

微信下载文件

添加链接描述

			downloadFileOpen(){
				let link = 'https://www.gjtool.cn/pdfh5/git.pdf'
				//下载文件
				wx.downloadFile({
				  url: link,
				  success (res) {
				    if (res.statusCode === 200) {
						const filePath = res.tempFilePath
    					wx.openDocument({
    					  filePath: filePath,
						  showMenu:true, //关键点
    					  success: function (res) {
    					    console.log('打开文档成功')
    					  }
    					})
				    }
				  }
				})
			}

左右列表联动

在这里插入图片描述
原文链接

小程序骨架屏

点击省略号自动生成骨架屏
在这里插入图片描述

<import src="logs.skeleton.wxml"/>
<template is="skeleton" wx:if="{{loading}}" />//使用loading控制
<view class="" wx:else="{{!loading}}">//其他内容eles判断隐藏

消息订阅

添加链接描述

操作步骤1:在微信公众号平台获得合适的模板

在这里插入图片描述

操作步骤2:wx.requestSubscribeMessage

wx.requestSubscribeMessage({
  tmplIds: [''],//模板id号
  success (res) { }
})

在这里插入图片描述

在这里插入图片描述

获取 uni.getUserProfile({})失效

//具体看官网
<button open-type="chooseAvatar" bindchooseavatar="getAvatar">
<input type="nickname" placeholder="请输入昵称" model:value="{{nickname}}"  />
//有个问题不能监听到nickname填入值改变,输入可以监听到,
给input nickname一个id值,@blur="getnickname"
  uni.createSelectorQuery().in(this) // 注意这里要加上 in(this)  
				      .select("#nickname-input")  
				      .fields({  
				          properties: ["value"],  
				      })  
				      .exec((res) => {  
				          const nickName = res?.[0]?.value 
				        this.userData.name = nickName  		
									this.upUserData(1) 
				      })			

网站扫描二维码,跳转小程序指定页面

onLoad: function(option) {
	//通过二维码打开小程序 // scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
			if (option.mediatorId != undefined) {
				this.mediatorId = option.mediatorId;
				this.getMediatorDetailFun();
			}
			
			 
		//通过二维码打开小程序 
			if(option.scene) {
				let scene = decodeURIComponent(option.scene);
				this.mediatorId=scene.split('=')[1]
				this.getMediatorDetailFun();
			}}

ios端省略号效果不对,超出部分隐藏收起

 	<view style="display: -webkit-box;
 	text-overflow: ellipsis;
 	-webkit-line-clamp: 13;//控制这个
 	-webkit-box-orient: vertical;
 	overflow: hidden;" :style="{'-webkit-line-clamp':isHiddentHeight?'initial':'13'}">
		<text>{{item.content}} </text>//需要在外面包裹一个元素
	</view>

网站上此图片来自微信公众平台未经允许不可引用

在这里插入图片描述

//nuxt3 设置
app: {
    head: {
      meta: [
        {
          name: "referrer",
          content: "never",
        }]},
  },
  //其他设置
  <meta name="referrer" content="never">

uv-waterfall 瀑布流 切换速度较快,数据混乱

//如果页面还没渲染结束,页面就跳走,但此时@changeList回调还在返回数据,可能会造成渲染出错,所以要想办法停止渲染,
<script>
	export default {
		onHide() {
			this.$refs.waterfall.clear();
		}
	}
</script>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值