微信小程序学习笔记

小程序简介

小程序是安装运行在微信上的app,是一种轻量级的应用。

特点:

  1. 依托微信,有强大的用户基数,易发展使用群体
  2. 体量小,无需安装、即用即走
  3. 不能调用浏览器提供的的BOM和DOM相关API,但可以调用微信提供的API,比如扫码支付、地理定位等

小程序三剑客

  • wxml(结构,如同房子的钢材结构)
  • wxss(样式,如同房子的装修)
  • javascript(功能,如同房子的灯光、供水、供电)

小程序结构

基本结构

小程序会创建时候会自动创建项目模板,主要组成有:

  • pages文件夹,存放页面
  • utils文件夹,存放可供全局调用的工具性质的js模块
  • app.js、app.json、app.wxss,整个app的逻辑、配置、样式文件
  • project.config.json,项目的配置文件
  • stemap.json配置是否允许被微信搜索到
    在这里插入图片描述

页面结构

微信官方建议将页面文件放入pages文件夹中,每个页面包含四个同名文件

  1. .json 后缀的 JSON 配置文件(页面配置,配置窗口的外观、表现等)
  2. .wxml 后缀的 WXML 模板文件(页面结构)
  3. .wxss 后缀的 WXSS 样式文件(页面样式)
  4. .js 后缀的 JS 脚本逻辑文件(页面脚本,存放页面数据,事件处理函数)

基础知识

  • 小程序中任何页面宽度都是750rpx 在不同大小设备中 1rpx对应不同的px 故要使用rpx为单位 实现设备等比适配
  • 小程序最外层标签固定为page标签(隐形的)

小程序宿主环境

小程序不是安装在操作系统之上的,而是直接安装在微信之上。小程序宿主环境即是手机微信,因此小程序不需要为不同设备作适配。

而微信为小程序提供了一系列服务支持,包括如下:

  • 通信模型
  • 运行机制
  • 组件
  • API接口

小程序通信模型

主体:JS逻辑层和页面渲染层(wxml+wxss)

在这里插入图片描述

小程序运行机制

运行机制包含启动和页面渲染两部分

小程序的启动

  1. 请求微信服务器,将代码包下载到本地
  2. 解析app.json全局配置文件
  3. 执行app.js入口文件,调用**App()**创建小程序实例
  4. 渲染小程序首页
  5. 启动完成

页面渲染过程

  1. 加载页面的.json配置文件
  2. 加载页面的.wxml结构和.wxss样式
  3. 执行页面.js文件,调用**Page()**方法创建页面实例

小程序基本操作

创建页面

一个页面包含四个文件,每一个要用页面的都需要在app.json中注册,加入到其pages标签中

在这里插入图片描述

创建方法:

直接在pages标签中加入创建的页面路径,保存后系统会自动创建对应的四个页面文件;

若手动创建文件,则创建后也需要在app.json中注册新创建的页面

数据绑定

①、提前将需要的数据定义好,每个数据都有一个对应的名称

    data: {
        // 定义字符串数据name,内容为小辣鸡
        name:'小辣鸡'
    },

②、在wxml中使用Mustache语法(双大括号)使用该数据

<button type="primary">{{name}}</button>

保存数据的一般方法:

在data中保存、定义var全局变量、定义全局常量const

注意:data是页面数据和数据库数据的中转站,需要将页面数据和数据库数据都保存在data中,再js代码中进行数据交互

双括号法的三个应用

  • 动态绑定内容,将{{数据名称}}直接用于显示
  • 动态绑定属性,将{{数据名称}}赋值给某属性
  • 运算(三元运算、算术运算)

data的作用

  • 保存页面数据和数据后台数据
  • 根据data动态控制页面组件状态
  • 各个页面之间的数据交互,如通过全局的data数据来交互

事件绑定

事件:渲染层到逻辑层的通信方式

小程序中有三种事件:

  • tap,类似click点击事件

  • input,文本框输入事件

  • change,状态改变事件

用法:bindtap、bindinput、bindchange或bind:tap、bind:input、bind:change

事件对象的属性

将每个事件分别抽象成一个对象event,每个对象有其属性如下
在这里插入图片描述

target和currentTarget区别

当点击内层组件时,点击事件会以冒泡的方式向外扩散,则event.target指的是最内层的源头组件对象,event.currentTarget指的是最外层的当前对象

bindTap语法格式

定义print函数

    print(e){//会将点击事件对象作为形参传入到函数中
        console.log(e);
    },

绑定事件

<button bindtap="print">普通按钮</button>
为data赋新值

【this.data.数据名称】代表当前数据,赋值语句如下

		this.setData({
            count:this.data.count+1
        })
为事件处理函数传参

加入属性,data-参数名=”{{数据内容}}“

bindIput语法格式

显示data数据

定义数据:pre_string:"预定义字符串",
显示内容:<input value="{{pre_string}}"></input>

将输入数据同步到data中

定义数据

    info:"0"

定义同步函数

    syncInputTo_data(e){
        this.setData({
            info:e.detail.value//拿到输入框当前value
        })
    },

输入框绑定同步函数

<input value="{{pre_string}}" bindinput="syncInputTo_data"></input>

WXML模板语法

wx:if条件渲染

小程序用wx:if=“{{条件语句}}”控制当前语句是否被渲染

<!-- 注意三个等号指的是类型及数据都相等 -->
<view wx:if="{{info===0}}">1</view>
<view wx:elif="{{info==='1'}}">2</view>
<view wx:else>其它</view>
blcok的使用

block不是一个组件,而是单纯的包裹作用的容器,不会渲染出任何效果

<!-- 用block实现控制多个组件的显示 -->
<block wx:if="{{false}}">
    <view>A</view>
    <view>B</view>
    <view>C</view>
</block>
hidden的使用

与if相反,条件为真时渲染

<view hidden="{{条件}}">AAAAAAAAAA</view>
hidden与wx:if的比较

hidden只是为元素加了一条display:none属性,而wx:if则是动态的增加或删除一个元素,资源消耗大

使用建议

wx:for遍历数组

定义数组

        array1:['玛卡巴卡','唔西迪西','依古比古','飞飞鱼','叮叮车']

遍历时,{{index}}代表下标,{{item}}代表数据内容

<!-- wx:for的使用 -->
<view wx:for="{{array1}}">
item下标:{{index}}
item内容:{{item}}
</view>

也可通过wx:for-index=“下标名”/wx:for-item="子项目名"修改默认的名称

wx:key的使用

遍历数组时,建议加入wx:key="索引名"来提高页面渲染效率

页面跳转及数据传递

跳转方式

wx.navigateTo -页面跳转

  • 不关闭当前页面,跳转到其它页面(非导航栏页面),之后可以返回当前页
  • url中可以加上"?param1=value1&param=value2…paramN=valueN"

wx.redirectTo -重定向

  • 关闭当前页,跳转到其它页面

wx.switchTo

  • 切换到导航栏页面

页面数据传递

方案一:全局globalData

​ 在全局的app.js文件中定义全局globalData,在各个子页面中通过getapp()来获取app对象,再获取其中的全局data

方案二:缓存

​ 在某页面中通过wx.setStorageSync设置数据,再在其它页面中通过wx.getStorageSync取数据

区别:全局globalData是每次运行时才存在,而缓存是直接存储在手机中,设置过一次缓存以后都存在,除非缓存过期

WXSS

wxss与css区别

wxss与css相比主要是引入了rpx单位、import导入方式,并且删去了少部分选择器、样式规则,其它都一致

rpx单位

小程序会将任意设备的宽度等分成750份,每份为1rpx,故屏幕更大的设备1rpx对应更多的px

以rpx为单位能使得内容在不同的机型中做到自动设配(等比例)

import导入方式

小程序不支持链入式,但支持导入式,用法为@import “相对路径”;

App.json全局配置

    "backgroundTextStyle": "light",//可改成dark,显示下拉效果
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle": "black",//只支持black或white
    "enablePullDownRefresh": true,

小程序组件

基本组件

tabBar导航栏

六个组成部分
在这里插入图片描述
每个tab的属性
在这里插入图片描述
注意:配置tabBar时,list第一个内容必须是当前页面(首页)

自定义组件

创建方法

  1. 项目根目录创建components文件夹,右键创建component,作为自定义组件

  2. 在创建的自定义组件中编写wxml和wxss

  3. 在要使用自定义组件的页面中注册当前组件,方法是在json文件添加usingComponents字段

      "usingComponents": {
        "test":"../../../components/test"//取名为test标签
      }
    

网络请求

要求:

  • 只能请求HTTPS类型的接口
  • 必须将接口的域名配置到白名单中

GET请求

①、在js文件中定义请求函数

②、在button中绑定请求函数

云开发

环境初始化

在project.config.json中设置项目路径

  "miniprogramRoot": "项目根目录/",
  "cloudfunctionRoot": "云开发根目录/",

在app.js中设置环境id

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

云数据库

基本模板

        const db=wx.cloud.database()
        var dbtools =db.collection('数据库名').【限制条件】.【具体需求】.then(res=>{
            //请求结束后的回调函数内容
        })

【限制条件】有哪些?

//【限制条件】包括限定id、限定记录数量、加where条件、排序等等,例子如下
        .doc('xxxxxxx具体id')//指定id操作

        .where({//限定字段取值
            字段:限定的取值
        })

		.orderBy('排序字段名','排序方式')//asc表升序、desc表降序

		.limit(n)//限定为前n条记录

		.skip(n)//跳过前n条数据,一般用作分页处理

		.filed({//过滤成指定字段
            字段:true
        })

【具体需求】有哪些?

//【具体需求】包括增、删、改、查、获取数量、监听数据等等
.add({//增加
	data:{
        //增加什么
        字段:数值
    }
})

.remove()//删除

.update({//更新
    data:{
        //更新成什么
        字段:数值
    }
})

.get()//查询

.watch({//监听
    onChange: res=> {
        	//数据变化时回调
              })
            },
            onError: err=> {
             //发送错误时回调
            }
          })
}
)

.count()//获取数量

collection

查询数据

注意:查询数据前先设置好每个表的权限

获取数据+保存到本地data

const db=wx.cloud.database()//获取数据库

//普通查询
        const todos = db.collection("user_info").get({
            success:res=>{
                console.log(res.data);
                this.setData({
                    user:res.data//保存数据到本地
                })
            }
        });

在wxml文件中显示数据:

<button bindtap="getdata">
获取数据
</button>
<view wx:for="{{user}}">{{item.nickname}}</view>

总例:

    getdata(){
        // 普通查询
         const todos = db.collection("user_info").get({
             success:res=>{
                 console.log(res.data);
                 this.setData({
                     user:res.data
                 })
             }
         });
        // 指定查询
         const todos = db.collection("user_info").doc("17e3426e622de3a8133f4c640c4660db").get({
             success:res=>{
                 console.log(res);
                 this.setData({
                     user:res.data
                 })
             }
         });
         //promise语法
         const todos = db.collection("user_info").get().then(res=>{
                 console.log(res);
                 this.setData({
                     user:res.data
                 })
         });
        // where条件查询
        const todos = db.collection("user_info").where({
            nickname:"王明"
        }).get().then(res=>{
            console.log(res);
            this.setData({
                user:res.data
            })
    });
    },
添加数据
//添加数据
    adddata(){
        // 加载效果
        wx.showLoading({
          title: '正在加载中...',
          mask:true
        })
        
        const todos = db.collection("user_info").add({
            data:{
                nickname:"中国有嘻哈",
                id:"asda"
            }
        }
        ).then(res=>{
            console.log(res);
            this.setData({
                user:res.data
            });
            wx.hideLoading();
    });
    },
删除数据
 //删除数据
    delete_data(){
        // 指定id
        const todos=db.collection("user_info").doc("617ef50c622e168b0b54b9371bb48c0d").remove({
            data:{
                nickname:"王阳明"
            }
        }).then(res=>{
            console.log(res);
        })
    },
修改数据
//修改数据
    update_data(){
        //指定id
        // 注意只能修改字段中有open_id的数据
         const todos=db.collection("user_info").doc("617ef50c622e168b0b54b9371bb48c0d").update({
             data:{
                 nickname:"王阳明"
             }
         }).then(res=>{
             console.log(res);
         })

        //where条件修改
         const todos=db.collection("user_info").where({
             nickname:"王阳明"
         }).update({
             data:{
                 nickname:"张翼德"
             }
         }).then(res=>{
             console.log(res);
         })
    },
读取页面数据
读取表单提交数据

wxml代码

<view class="biaodan">
    <form bindsubmit="add_user">
    <input name="name" placeholder="请输入名称"></input>
    <input name="pwd" placeholder="请输入密码"></input>
    <textarea name="备注" placeholder="请输入备注"></textarea>
    <button type="primary" form-type="submit">添加数据</button>
    <button type="default" form-type="submit">重置</button>
</form>
</view>

js代码

    //读取表单添加用户信息
    add_user(res){
        console.log(res);
        var value=res.detail.value;//直接存储value对象
        const todos = db.collection("user_info").add({
            data:{
                value
            }
        }
        ).then(res=>{
            console.log(res);
            this.setData({
                user:res.data
            });
            wx.hideLoading();
    });
    },

读取input输入框内容

wxml代码

<input bindinput="getinput" style="border: 1px solid #536545;"></input>

js代码

    // 获取输入框内容
    getinput(req){
        var i=req.detail.value;
        console.log(req.detail.value);
        this.setData({
            input:i
        })
    },

实时更新数据

过程:加载页面时先get到数据后设置到本地data,渲染出来;定义监听器,监听器中再写setdata

wxml代码

<view wx:for="{{paper}}">//渲染到前端

  <text>{{item.title}}</text>

</view>

js代码

    onLoad: function (options) {
        //持续监听
        const watcher = db.collection('paperList').watch({
            onChange: res=> {//首次加载会执行一次,每次更新都会再执行一次
              console.log('snapshot', res.docs),
              this.setData({
                  paper:res.docs//保存到本地
              })
            },
            onError: err=> {
              console.error('the watch closed because of error', err)
            }
          })
        // login();
    },

command

在对collection数据操作时,用where只能限定某些字段等于什么,而在where中使用command的方法就能实现更高级的限定

比较运算符

用比较运算来限定数据,比如大于、小于、属于、等于

const db=wx.cloud.database()//获取数据库
const _ = db.command//获取command

const openID = 'xxx'
db.collection('articles').where({//高级限定
  	num0: _.eq(666),//num0等于666
  	num1:_.gt(10),//num1大于10
  	num2:_.gte(5),//num2大于等于5
  	num3:_.lt(3)//num3小于3
  	num4:_.lte(5),//num4小于等于5
  	num5:_.in([10,20,30]),//num5在集合10/20/30之中
  	num6:_.nin([10,20,30])//num6不在集合10/20/30之中
}).get()
逻辑运算符

用逻辑运算来实现多个条件,比如与、或、非

const db=wx.cloud.database()//获取数据库
const _ = db.command//获取command

const openID = 'xxx'
db.collection('articles').where({//用and限定给同一字段加多个条件
  	num0: _.and(_.gt(10),_.lt(20))//num0大于10且小于20
}).get()

db.collection('articles').where(_.and([//用and给不同字段做多个限定
    {
        num0:_.lt(20)//num0小于20
    },
    {
        num1:_gt(11)//num1大于11
    }
])).get()

//or的用法和and的一致
字段操作符
const db=wx.cloud.database()//获取数据库
const _ = db.command//获取command

db.collection('articles').where({
    tittle:_.exists(true),//限定存在tittle字段
    tittle:_.size(3),//tittle数组只有三个元素
    tittle:_.all,//tittle数组中包含["数码","科技"]
    tittle:_.elemMatch({
        age:_.lt(18)//tittle对象数组中,至少存在一个对象age<18
    }),
}).get()
update更新字段
const db=wx.cloud.database()//获取数据库
const _ = db.command//获取command

db.collection('articles').where({
	data:{
		hits:_.inc(1),//自增1,负数变自减
        hits:_.remove(),//删除hits字段
        hits:_.set(123)
	}
    }),
}).get()
//对于更新对象字段,注意set更新和不同set更新的区别:set更新会将旧数据清零,变成为set里面的数据;
//而不用set时只修改data中指定的字段,其它未涉及到的字段不改变

云函数

将页面js写的函数代码,部署在云端服务器上,就变成了云函数,主要就是用来操作数据库。

好处:

  • 实现前后端分离,客户端只需要调用接口就可以
  • 减少重复的代码编写,将重复的数据库操作代码封装起来,供页面调用

注意点:每次更新云函数之后,必须部署上去才会生效!!!

新建云函数

右键云开发文件夹、新建Node.js云函数

初始化

因为在云函数中需要用到微信提供的sdk提供的api,所以要安装依赖的js包,即通过node.js的npm指令安装。npm是前端的包管理工具,就相当于java领域中maven的作用。

①安装Node.js

官网:https://nodejs.org/en/download/

②检查是否安装成功

打开cmd,输入如下指令,若出现版本号则是安装成功

node -v

③为云函数安装依赖

右键需要依赖的文件夹(各云函数的父文件夹),点击【在内建终端内打开】,输入指令:

npm install --save wx-server-sdk@latest

④重启开发工具

如果重启后还是报错,比如报XXX is not a function.那么此时把这个云函数删除,再重新创建,然后下依赖即可。

云函数使用

传递参数

在小程序端,通过设置wx.cloud.callFunction的data来传递数据。

在云函数端,通过event接收数据。

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

cloud.init()
const db=cloud.database();

// 云函数入口函数
exports.main = async (event, context) => {
    const wxContext = cloud.getWXContext()
    // return db.collection("paper-info").get()
    return {
        event,
        openid: wxContext.OPENID,
        appid: wxContext.APPID,
        unionid: wxContext.UNIONID,
    }
}

常见需求

css类选择器不起作用,消除button默认样式

法一:用行内式加style,因为style优先级很高

法二:用.button和.button::after设置所有按钮样

获取表单数据并且提交到js

  • 新建form,设置bindsubmit属性,内容为对应的提交函数
  • 在form中新建各种表单,如input,设置name作为提交数据的key,value设置为当前key对应的数据
  • 在某个button中设置, form-type=“submit”,点击当前按钮后就会提交表单,执行绑定的提交函数
  • 在from提交函数中设置参数req,则通过req.detail.value获取数据了

下拉触底刷新:原理是先获取m条数据渲染出来,当监听下拉触底时,则跳过当前已经渲染的数据再二外取n条数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值