微信小程序学习笔记(汇总)

发布于 2019-12-21  111 次阅读


微信小程序

wx477794c206d6fcf3我的appid

基础文件介绍

  • app.wxss微信的css

  • 热重载,更新时即时刷新,电脑性能不是很好就建议关闭,

  • project.config.json 配置文件

  • pages 微信页面,pages中

    ,一个文件夹就是一个页面,包含四个文件

    wxml,wxss,js,json

  • app.js,在这里可以创建微信页面,只要保存编译后就会自动生成,

    也可以在app.js中修改一些全局样式,nav背景颜色,nav导航名称

        "backgroundColor": "#F6F6F6",//背景色
        "backgroundTextStyle": "light",//字体样式
        "navigationBarBackgroundColor": "#ccf",//标题背景
        "navigationBarTitleText": "微信小程序",//标题名称
        "navigationBarTextStyle": "white"//标题颜色

    首页配置:第一个引入的链接默认为首页,

    微信是基于weui框架进行布局的,现在已经更新到版本2,如果想反悔版本1需要删除app.json中的 "style": "v2"就可以使用版本1

  • ctrl+r快速编译项目

  • 开发中一般使用iphonex或者iphone6的视图

  • rpx和px的区别

    一遍UI会给开发者3种尺寸的设计图375px,750px,1125px

    2rpx = 1px

    1px = 2rpx

    30px = 60rpx

  • 微信中的button,就是button,但也是一个封装过的标签

基础标签介绍

不管seo的话,h5中几乎所有的块级元素都能用div

<view></view>相当于<div>

小程序中,块级元素全部用view

行内元素 text 相当于span

image相当于img,但是它css中,高度不随宽度的变化而变化,所以要给它加上mode="widthFix"

<image src="/xxxx" mode="widthFix"></image>

block标签:

胡子语法在小程序中一样起作用,但所有从js里来的数据都要通过胡子语法

index.js

Page({

   data:{

       msg:"你好世界1"

   },

    btnClickFn(){

    }

})

微信中的"v-for"

<view wx:for="{{dataList}}" wx:key="*this">
{{index}},{{item}}
</view>

//wx:for最好是绑定wx:key="index"不然语法不严谨而且会报警告
//默认就是item和index,没有for in语句,记得用胡子语法
//wx:key:推荐使用*this,不用去管他到底key值想为什么,自动帮你指代,提升性能

如果实在要写item的名字的话可以这样写


<view wx:for="{{dataList}}" wx:key="*this" wx:for-item="myitem">
{{index}},{{myitem}}
</view>

微信中的click

微信小程序中没有click事件,也不能用click来模拟点击事件

微信中的点击用bindtap来绑定,微信小程序中也没有methods事件(组件中有),直接在page当下加btnClickFn(){

}

<button bindtap="btnClickFn">按钮</button>

微信中的双向数据绑定

在vue中,v-model其实是一个语法糖,包装过的一个v-命令.
他原理是通过v-bind: 个v-on:事件,通过开发订阅者模式和事件监听来实现的双向绑定.
微信小程序中没有v-model,所以利用

value="msg",bindinput="iptFn"来实现双向绑定

其中iptFn(e){
//e代表传过来的这个事件dom
//修改data中的数据方法
this.setData({
        msg:e.detail.value
        //新值
})
}

微信中的data重新赋值

不能使用this.msg="新值" 了

唯一修改data里面值的方法:必须用this.setData({msg:"新值"})

拿到data:{}里的arr

this.data.arr获取值

微信中的显示隐藏

和vue中的一样,使用v-if="true"或者v-show="{{true}}"来控制元素的显示与隐藏

小程序中的

wx:if来控制dom元素的删除与创建

<view wx:if="{{istrue}}">控制显示与隐藏hidden</view>
同时wx:if还可以拿来代表判断

elif
<view wx:if="{{msg=='你好世界'}}">当等于你好世界时候显示第一个</view>

<view wx:elif="{{msg=='我好世界'}}">当等于我好世界的时候显示第二个</view>

用hidden来代替v-show的显示与隐藏,只不过逻辑相反,


<view hidden="{{true}}">控制显示与隐藏hidden</view>

//hidden= true时为隐藏  false为显示

微信小程序里面的过滤器

vue中的过滤器格式为


<div>{{ price | filterMoney}}</div>
filters:{
filterMoney(val){
    return"¥" + val.toFixed(2)+"元"
}
}

在微信小程序中没有filters所哟,所以在wxs里加入js代码

//先给这个标签写一个工具名字
<wxs model="pricetool">
//在微信里本质是js-,wxs只支持es5,不支持es6,所以不能写回调函数
function filterPrice(val){
retrun "¥"+val。toFixed(2)+"元";
}
//然后导出
module.exports = {
filterPrice:filterPrice
}
</wxs>

之后在标签中调用这个工具,并传参

<view>
{{pricetool.filterPrice(price)}}//传参
<view>

当然你也可以把这个wxs代码单独抽离出来,放在一个.wxs文件里

price.wxs
//在微信里本质是js-,wxs只支持es5,不支持es6,所以不能写回调函数
function filterPrice(val){
retrun "¥"+val。toFixed(2)+"元";
}
//然后导出
module.exports = {
filterPrice:filterPrice
}


然后再局部引入,就像引入js一样
<wxs src="./price.wxs" modle="pricetool"></wxs>

微信中使用模板

可传值模板

1、创建文件文件夹template

2、创建一个wxml文件temp.wxml

<template name="mytemp">
<view>这是模板中的一个标题{{content}}</view>
</template>

//{{}}可以接收从data中传过来的值

3、在其他页面引入这个页面

<import src="./template/temp.wxml"/>
//之后就可以使用了

//使用template标签,通过is来判断引入的模板是哪个,对应模板中的name,使用data对view传值
<template is="mytemp" data="{{content:1}}"></template>
<template is="mytemp" data="{{content:2}}"></template>
<template isn="mytemp" data="{{content:3}}"></template>


不可传值模板

只能写一个模板,不能传值

<view><button type="warn">这是一个按钮</button></view>

用inclined标签引用

<include src="btntemp1">//直接应用文件名称就可以使用它

补充:vue打包移动端后,click有300ms的延迟

解决方法

1、引入fasterclick.js

2、不使用click 使用tap代替 zepto框架(类似jq的,原生js没有tap)

3、使用touchstart

app.json=>topBar配置

  "tabBar": {
      //文字颜色
      "clolor”:"#cdcdcd",
      "selectrdColor":"#303f9b"
    "list": [{
        //路径地址
      "pagePath":"pages/home/home",
        //菜单名称
      "text": "首页",
        //菜单图标
      "iconPath": "/img/bar/dou.png",
        //激活后图标
      "selectedIconPath": "/img/bar/meng.png"
    },
    {
      "pagePath": "pages/menu/menu",
      "text": "菜单",
      "iconPath": "/img/bar/dou.png",
      "selectedIconPath": "/img/bar/meng.png"
    },
    {
      "pagePath": "pages/new/new",
      "text": "新闻",
      "iconPath": "/img/bar/dou.png",
      "selectedIconPath": "/img/bar/meng.png"
    },
  
    {
      "pagePath": "pages/service/service",
      "text": "服务",
      "iconPath": "/img/bar/dou.png",
      "selectedIconPath": "/img/bar/meng.png"
    }
  
  ]
  },

"navigationStyle": "custom":自定义nav头,没定义也不会用默认的直接没有,可以给某个页面的json加上

微信swiper

微信自带的组件

利用一元一次方程,来计算siwper的高度

540/380(图片宽高) = 100vw/x

x vw就是swiper的高度

750/400 = 100/x

可利用css中calc()的计算函数来计算x的值

如:height:calc(100vw*400/750)

微信小程序中的class绑定

        <view class="{{activeCont==1 ? 'liactive' : ''}}"></view>

scroll-view

微信商品滑动行

针对于安卓手机,解决scroll-view标签底部的横向滚动条,在全局wxss写

::-webkit-scrollbar{
width:0;
height:0;
color:transparent;

}

新建组件方法

创建组件

组件!=模板

在page里,自动创建components

在js中,把page()修改为Component,

//将他定义为组件

在json中把他定义成一个组件:"compoent":true

引入组件

使用这个组件,在需要使用的json里的"usingComponents":{"mybtn","组件路径"}

使用组件

<mybtn><mybtn/>在wxml里面直接当标签用就行了,小程序组件的事件要卸载methods里面

微信父传子

父.wxml
<mybtn btnNumber="{{btnNumber}}"></mybtn>

父.js
data:{
btnNumber:123
}

mybtn子.wxml
<view>这是父元素传过来的组件{{btnNumber}}</view>

子.js
properties:{
    btnNumber:{
        type:Number,
        //设置默认值
        value:0
    }

}

微信子传父

子组件中

son.js
methods:{
    changeNum(){
        //通过事件去触发传递
        this.triggerEvent("childFn",200)
    }
}

父组件中

//子传父触发的事情

在wxml中定绑定这个传过来的时间
<button bind:childFn="childFn">一个按钮</button>

father.js
就可以使用这个子组件传过来的值,并得到一个参数
childFn(val){
    val===200

}

全局数据

定义App

const app = getApp();

修改全局数据的值

app.globalData.username="李三"

在app.js里设置全局数据的值:

globalData: {

userInfo: null,

username:"张三"

},

修全局的值,app

跳转页面

wx.navigateTo

navigateTo,不能导航到tabBar页面

wx.navigateTo({

url:'/pages/user/user'

})

wx.swichTab

swichTab//只能跳转到tabbar页面

wx.swichTab(){

url:'/page/coffee/coffee'

}

生命周期

onLoad:页面加载,只执行一次

//一般获取数据是在这里获取

onShow:页面显示到前台,只要这个页面进入前台,就会重复执行

onReady大多数样式渲染完成(未必所以的都渲染完成了)

onHide:页面退出到后台

onUnload:页面卸载

用来清除数据

组件的生命周期

  • 组件实例刚刚被创建好时, created 生命周期被触发。此时,组件数据 this.data 就是在 Component 构造器中定义的数据 data此时还不能调用 setData 通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。

  • 在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。

  • 在组件离开页面节点树后, detached 生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached 会被触发。

  attached: function () {
    // 在组件实例进入页面节点树时执行
   
  },
  detached: function () {
    // 在组件实例被从页面节点树移除时执行
  },

还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”,在 pageLifetimes 定义段中定义

Component({
  lifetimes: {
    attached: function() {
      // 在组件实例进入页面节点树时执行
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行
    },
  },
  // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
  attached: function() {
    // 在组件实例进入页面节点树时执行
  },
  detached: function() {
    // 在组件实例被从页面节点树移除时执行
  },
  // ...
})
}

组件所在页面的生命周期

还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”,在 pageLifetimes 定义段中定义。其中可用的生命周期包括:

生命周期 参数 描述 最低版本
show 组件所在的页面被展示时执行 2.2.3
hide 组件所在的页面被隐藏时执行 2.2.3
resize Object Size 组件所在的页面尺寸变化时执行 2.4.0

数据请求

合法域名必须是https开头,http只能在开发中用作测试

wx.request({

url:"url",// 必须要https
success:function(res){
		console.log(res)

}



})

request封装请求

request.js有三个文件

api.js

// 开发的服务器
var baseUrl = 'http://kumanxuan1.f3322.net:8001'
// 测试的服务器
// var baseUrl = 'http://192.168.113.116:8637'
// 正式环境
// var baseUrl = 'http://www.mysite.com'

var homeApi = baseUrl + '/index/index'
//首页的请求,定义一个名称,然后在下方导出模块
var listApi = baseUrl + '/topic/list'
var loginApi = baseUrl + '/auth/loginByWeb'

module.exports = {
  homeApi:homeApi,
  listApi,
  loginApi
}

fetch.js

var api = require('./api.js')
var request = require('./request.js')

//引用api和request,创建模板

// get请求不携带参数
function getHome() {
  return request.requestApi({
    url: api.homeApi
  })
}

// get请求携带参数
// function getList(params) {
//   return request.requestApi({
//     url: api.listApi,
//     data: params,
//   })
// }

// post请求,携带参数
function LoginFn(params) {
  return request.requestApi({
    url: api.loginApi,
    data: params,
    header: {
      'content-type': 'application/x-www-form-urlencoded'
    },
    method: 'POST'
  })
}

//到处模板
module.exports = {
  getHome,
  LoginFn
  // LoginFn: LoginFn,
  // getList: getList
}

request.js一般就是这样子,不用动他

function request(params) {
  // 封装网络请求的代码
  return new Promise(function (resolve, reject) {
    wx.request({
      url: params.url,
      data: params.data || {},
      header: params.header || {},
      method: params.method || 'GET',
      dataType: 'json',
      success: function(res) {
        resolve(res.data)
      },
      fail: function(err) {
        wx.showToast({
          title: err || '请求错误!',
        })
        reject(err)
      }
    })
  }) 
}
// nodejs common
module.exports = {
  requestApi: request
}

在页面中使用

解构导入fetch里面定义好的请求
const {getHome} = require("../../request/fetch")

然后在事件中发送请求
btnFn(){
	getHome().then(res=>{
			log(res)
	})


}

怎么使用less

应入从vscode里面的easyless插件

wx.showLoading显示加载中

关闭的时候时候用wx.hideLoading关闭

一般运用在界面渲染前后

image-20211106155013557

小程序存到storage中,有同步就用同步

wx.setStorageSync("key",val)同步储存

wx.setStorage({

key:"key",

value:"value"

})异步储存

image-20211106164111374

全部清除

wx.clearStorageSync

指定清除

wx.removeStorageSync("token")

微信小程序中阻止冒泡事件

但是也可以阻止冒泡事件的发生,其实很简单,直接把bindtap改为catchtap即可。

刷新页面

this.onShow

获取当前页面的页面栈,数组第一个元素为首页,最后一个元素为当前页面

//获取当前页面栈,是一个数组,最后一项是当前页面的路由

getCurrentPages()

//拿到当前页面的路由

let arr = getCurrentPages()

let route = '/'+arr[arr.length-1].route

globaldata或者storage储存route

判断有没有route,如果有route,登录后就直接跳回去

popup

普通编译→添加编译模式,设置每页都有它

刷新方案

bind:refresh ="refresh"

refresh(){

this.getData()
}

返回上一页

wx.navigateBack()

SetData性能问题

// this.setData(obj, callback)数据更新是同步的,但视图更新是异步的

每一次setData相当于把data所有的数据重新赋值一遍,

节约setData 的性能:减少setData 的使用

防抖和节流

利用定时器,每一次搜索输入的时候延迟300毫秒,并在下一次输入的时候清除定时器

image-20211108142546741

强制更改请求对象的key名称

JSON.parse(JSON.stringify(fillterCategory).replace(/id/g,'value').replace(/name/g,'rext'))

微信小程序方法传参 data-item='参数'

    <view class="li" wx:for="{{listArr}}" wx:key="*this" bindtap="keywordFn"   data-item='{{item}}'>
    {{item}}
    </view>
    
    之后用event.currentTarget.dataset.item;得到数据

微信跳转路由传参

wx.navigateTo({

url:'/pages/details/details?id=2'

})

然后在details页面的onLaod(options){

log(options.id)

}

富文本渲染

如果拿到的数据是<p><img src=""></img></p>

首先要把<img replace成<img class="类名"

使用<rich-text nodes="{{str}}"></rich-text>

获取手机型号

调用wx.getSystemInfo,获取手机型号res.model

并储存为全局变量

  wx.getSystemInfo({
      success: (res) => {
        let modelmes = res.model;
        if (modelmes.search("iPhone X") != -1) {
          _self.globalData.isIphoneX = true;
        }
        wx.setStorageSync("modelmes", modelmes);
      },
    });

利用Websocket实现聊天功能

image-20211111143720318

1.初始化项目

2.安装express express-ws nodemon

2bitbug生成小图标

https://www.bitbug.net/

<link rel="shortcut icon" href="./img/libai.ico">

3项目根目录下创建 server 文件夹,在其中创建 server.js,然后写入:

const express = require("express")
const expressWs = require("express-ws")
const app = express();
const port = 3030;
expressWs(app)

// 中间件
app.use(express.static('public'))	// 主动访问public下的文件
app.get("*", (req,res)=>{})
app.listen(port, ()=>{
  console.log(`Server is running at wx://localhost:${port}`)
})

超出盒子自动滚动

当一个盒子内部的内容增加,并且超过该盒子的高度时,我们希望它自动滚动到底部:

var box = document.getElementById('box');

box.scrollTo({
  top: box.scrollHeight,
  behavior: "smooth"
})

image-20211111164231683

设置app.js文件

// 引入框架
const express = require("express")

const websocket = require("./websocket.js")
//引入websocket配置

const app = express();
const expressWs = require("express-ws")

const port = 3000;
expressWs(app)

// 中间件
app.use('/libai',express.static('public/libai.html'))
app.use('/dufu',express.static('public/dufu.html'))
// app.use('/base',express.static('public/css/'))
app.use(express.static('public'))

app.use('/ws',webSocket)

//如果不想在路由中看到ws可以app.use('/',webSocket)

app.use(express.static('public'))

//判断路由
app.get("/*",(req,res)=>{

})

// 监听端口
app.listen(port,()=>{
    console.log(`Sercer is running at http://localhost:${port}`);

})

创建websocket.js文件

`

const express = require("express");

const expressWs = require("express-ws")

const router = express.Router();

expressWs(router)

//李白访问路径为ws://localhost:3000/ws/libai

router.ws('/libai',ws=>{
    
    ws.send('李白链接成功')
})

module.exports = router

在libai.html-js中建立连接

    //实例化,跟/ws/libai建立了连接
    const ws = new WebSocket("ws://localhost:3000/ws/libai")

    //打开时候回调
    ws.onopen = function () {
        //如果得到连接状态是1的话代表链接成功
        console.log(ws.readyState);
    }
    
        //从服务端收取数据
    wx.onmessage = function (res) {
        console.log(res.data)

    }

    //断开连接时候
    ws.onclose = function () {
        console.log("断开连接");
    }

    //连接错误时
    ws.onerror = function () {

        console.log("链接错误");
    }

客户端与服务端发送数据,ws.send

客户端发送数据给服务端

//send是websocket的方法,用于发送数据,send中有个return,所以一般来说一个逻辑题里面又有一个send

ws.send(value)

服务端接收客户端发过来的数据,并且返回msg

router.ws('/libai',ws=>{

// 接受从客户端发送过来的数据

ws.on("message",(msg)=>{

//重新吧拿到的数据返回给客户端

ws.send(msg)

})

})

然后服务端接收客户端发过来的数据,并渲染在页面中

    //从服务端收取数据
    ws.onmessage = function (res) {
        console.log(res.data)
        msgbox.innerHTML += rightMsgFn(res.data)
    }

enablePullDownRefresh的使用

1.首先要在app.json里面去将enablePullDownRefresh设置为true.

2.js 中设置 // onPullDownRefresh:function(){ // console.log("刷新页面") // },


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。