首页
友链
导航
影视
壁纸
统计
留言板
Search
1
el-upload自定义触发按钮及触发上传前判断
843 阅读
2
vue配置二级目录以及nginx多网站部署
701 阅读
3
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
578 阅读
4
joe主题自定义导航页面
516 阅读
5
js获取昨天今天明天日期
480 阅读
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
登录
Search
标签搜索
web
vue
node项目实战
js
javascript
typecho
css
vuex
router
nginx
git
element
joe
utils
leaflet
dateFormat
map
date
axios
reg
辰漪
累计撰写
66
篇文章
累计收到
122
条评论
首页
栏目
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
页面
友链
导航
影视
壁纸
统计
留言板
搜索到
1
篇与
微信小程序
的结果
2022-09-28
小程序学习笔记
小程序基本了解小程序与普通网页的区别运行环境不同网页运行在浏览器环境中小程序运行在微信环境中API不同运行环境不同,这也就导致小程序无法调用DOM和BOM的API。但是可以调用微信环境中提供的各种API开发模式不同网页的开发模式:浏览器 + 代码编辑器小程序: 申请小程序开发者账号,安装小程序开发者工具,创建和配置小程序项目小程序项目结构|-- project_02 // 根目录 |-- .eslintrc.js // eslint配置 |-- app.js // 小程序入口文件 |-- app.json // 全局配置文件 |-- app.wxss // 全局样式文件 |-- project.config.json // 项目配置文件 |-- project.private.config.json // 项目私有配置文件 会覆盖 project.config.json相同字段 |-- sitemap.json // 配置页面能否被微信索引 |-- pages // 存放页面的文件夹 | |-- index | | |-- index.js // 页面js文件(存放页面数据,事件处理函数等) | | |-- index.json // 页面配置文件(配置页面窗口外观,表现) | | |-- index.wxml // 页面模板文件 | | |-- index.wxss // 页面样式文件 | |-- logs | |-- logs.js | |-- logs.json | |-- logs.wxml | |-- logs.wxss |-- utils // 存放工具函数的文件夹 |-- util.js小程序配置文件app.json全局页面配置文件,配置页面的窗口,页面的路径等{ "pages":[ "pages/index/index", "pages/logs/logs" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "Weixin", "navigationBarTextStyle":"black" }, "style": "v2", "sitemapLocation": "sitemap.json" } pages节点 ---> 小程序的页面路径,在此配置会默认生成页面的目录结构window节点 ---> 配置页面的背景色,文字颜色等,全局生效style节点 ---> 定义小程序组件使用的样式版本sitemapLocation节点 --> 指定sitemap.json的位置project.config.json项目的配置文件,用来配置跟项目相关的配置setting节点 ---> 定义编译相关的配置projectname ---> 配置项目的名称appid ---> 配置小程序的appidsitemap.json配置页面是否被微信搜索到。{ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", "rules": [{ "action": "allow", // 允许索引 disallow 不允许索引 "page": "*" // * 表示所有的页面 }] }在项目配置文件peoject.config.json中的setting节点添加 "checkSiteMap": false, 可以隐藏掉索引情况提示信息页面的 .json文件可以对当前页面的窗口外观样式进行配置覆盖全局的app.json中window节点下的配置小程序代码构成如何创建一个页面直接在app.json里边的pages节点下新增页面的路径,项目会自动创建对应的页面目录在pages文件夹右键,新建文件夹,右键新建的文件夹,新建page,输入页面名后会自动生成页面需要的文件,此时app.json的pages节点也会自动添加这个页面路径修改首页对应的页面只需要将pages节点中的路径位置调整一下顺序,第一个就表示首页的页面wxml和html的区别标签名称不同html(div, span, a, img)wxml(view, text, navigator, image)属性不同<a href="#"><navigator url="/pages/home/home"></navigator>支持类似于vue的模板语法数据绑定列表渲染条件渲染wxss和css的区别新增rpx单位css中需要手动对像素px进行换算,例如:rpx单位rpx则可以在不同尺寸的屏幕上自动进行换算提供了全局样式和局部样式app.wxss全局样式会作用于所有的页面局部页面的 .wxss 样式只针对于当前页面的样式小程序中的js文件app.js是整个小程序的入口文件,通过调用App()函数启动小程序页面的 .js文件是页面的入口文件,通过调用Page()函数创建并运行页面普通的 .js文件普通的功能函数模块,封装一些公用的函数或者属性,供其他页面使用小程序中的组件小程序组件分类视图容器基础内容表单组件导航组件媒体组件map地图组件canvas画布组件开放能力无障碍访问常用的视图容器组件view组件类似于div,用来布局scroll-view组件可以滚动的div,用来实现列表滚动swiper和swiper-item组件轮播图容器(swiper)和里边的每一项轮播图(swiper-item),用来实现轮播图常用的基础内容组件text组件普通的文本组件,类似于spanrich-text富文本组件,支持html字符串转换成wxml结构<text>13213212</text> <rich-text nodes="<h1>12313</h1>"></rich-text>其他常用的组件button组件按钮组件,更丰富的功能,可通过open-type属性调用微信的功能(客服,转发,用户授权等)image组件图片组件,存放图片的容器navigator组件页面导航组件,类似于a小程序中的api事件监听api以on开头,监听某个事件例如:wx.onWindowResize(() => {}) 监听窗口尺寸的变化同步api以Sync结尾,可以直接接受函数返回值例如:wx.setStorageSync('key', 'value') 本地存储异步的api不带Sync的api,需要通过success fail compalete接收例如:wx.request()发送一个网络请求 需要通过success回调函数接收数据小程序语法数据绑定,mustache语法// js Page({ data: { // 在这里进行数据绑定 num: 1, src: 'http://wwjjds.com/1.png' } }) // wxml 在wxml模板中 使用mustache语法进行渲染 双大括号的形式 // 绑定内容 <view>{{ num }}</view> // 绑定属性 <image src="{{ src }}"></image> // 表达式 <view>{{ num > 1 ? '大于1' : '小于等于1' }}</view> // 算术运算 <view>{{ num * 100 }}</view>事件绑定tap点击事件 bindtap 或者bind:tapinput文本框输入事件 bindinput 或者bind:inputchange状态改变时触发 bindchange 或者bind:change事件对象的属性(event)属性类型说明typeString事件类型timeStampInteger页面打开到触发这个事件经过的时间,毫秒数targerObject触发事件的组件的一些属性值集合currentTargerObject当前组件的一些属性值集合detailObject额外的一些信息touchesArray触摸事件,当前停留在屏幕上的触摸点信息数组changedTouchesArray触摸事件,当前变化的触摸点信息数组targettarget指的是事件触发的源头currentTargetcurrentTarget指的是正在触发的那个元素// js Page({ tapHandler(e) { console.log(e, 'event'); } })<!-- wxml --> <view class="mine-container" data-count="{{ 2 }}" bindtap="tapHandler"> <button type="primary" data-num="{{ 1 }}">按钮</button> </view>点击按钮,此时事件向上冒泡,e.target指的就是这个button按钮,即事件触发的源头,可以从e. target . dataset. num 拿到num值。e.currentTarget是正在触发事件的那个元素 view,可以e. currentTarget. dataset. count拿到count值为data进行赋值调用this.setData()函数为data中的属性进行赋值操作 btnClick (e) { console.log(e); // 修改data中的数据 this.setData({ // 要修改的属性 : 修改的值 通过this.data拿到data中的数据 num: this.data.num + 1 }) },事件传参通过在wxml模板上绑定属性,绑定方式为 data-*,在事件对象中通过e. target. dataset对象拿到对应的属性// js Page({ tapHandler(e) { console.log(e, 'event'); console.log(e.target.dataset.num) // button绑定的属性data-num } })<!-- wxml --> <view class="mine-container" data-count="{{ 2 }}" bindtap="tapHandler"> <button type="primary" data-num="{{ 1 }}">按钮</button> </view>input事件bindinput进行绑定 通过e.detail.value拿到最新的值// js Page({ data: { inputValue: '' }, inputChange(e) { console.log(e.detail.value); // 文本框中的值 this.setData({ inputValue: e.detail.value // 实现双向绑定 修改文本框数据 data中的数据也一并修改 }) }, })<!-- wxml --> <input value="{{ inputValue }}" bindinput="inputChange"/>条件渲染wx:ifwx:elifwx:else// js Page({ data: { sex: 1 } })<!-- wxml --> <view wx:if="{{ sex === 1 }}">男</view> <view wx:elif="{{ sex === 0 }}">女</view> <view wx:else> 未知 </view>结合block标签进行条件渲染,block标签不会渲染到页面中,只是起到了包裹的作用<!-- wxml --> <block wx:if="{{ true }}"> <view>view1</view> <view>view2</view> </block> <view wx:if="{{ true }}"> <view>view1</view> <view>view2</view> </view>hidden<view hidden="{{ true }}">hidden隐藏</view>wx:if和hidden的区别hidden 通过display: none进行隐藏,wx:if会创建或者移除该元素列表渲染wx:for默认索引是index,数据项是item通过属性 wx:for-index="" 修改对应的索引变量通过属性 wx:for-item="" 修改对应的数据项变量通过wx:key提高渲染效率,不需要mustache语法,索引index,如果每一项有id的话直接写id属性// js Page({ data: { list: [ {id: 1, name: '苹果'}, {id: 2, name: '草莓'}, {id: 3, name: '鸭梨'} ] } })<!-- wxml --> <text>------------列表渲染------------</text> <view wx:for="{{ list }}" wx:key="id"> <text>名称:{{ item.name }}</text> <view>索引:{{ index }}</view> </view> <text>------------列表渲染 自定义index和item------------</text> <view wx:for="{{ list }}" wx:key="id" wx:for-index="ind" wx:for-item="ite"> <text>名称:{{ ite.name }}</text> <view>索引:{{ ind }}</view> </view>rpx单位适配不同屏幕尺寸rpx实现原理:rpx把所有设备屏幕划分为750份,即宽度为750rpx,在小屏幕上,1rpx宽度较小,在大屏幕上,宽度较大。小程序在运行时,会把rpx单位的样式换成对应的px单位,实现屏幕的适配。设备rpx换算px(屏幕宽度 / 750)px换选rpx(750 / 屏幕宽度)iPhone51rpx = 0.42px1px = 2.34rpxiPhone61rpx = 0.5px1px = 2rpxiPhone6 Plus1rpx = 0.552px1px = 1.81rpxiPhone6 屏幕宽度 375px 物理像素750,rpx等分750物理像素即 1rpx = 1物理像素 = 0.5px一般会采用iPhone6设计稿, rpx是整数小程序全局配置app.json全局配置文件常用配置项节点pages配置小程序的页面window配置页面窗口外观tabBar设置小程序的tabBarstyle小程序组件使用的样式版本号(v2)最新版window节点小程序窗口可以分为三类:navigationBar导航栏区域background背景区域,下拉刷新时可见wxml页面的主体布局区域常用的window属性属性名类型默认值说明navigationBarTitleTextString字符串导航栏标题文本内容navigationBarBackgroundColorHexColor#000000导航栏背景色,16进制颜色navigationBarTextStyleStringwhite导航栏标题颜色,仅支持white/blackbackgroundColorHexColor#ffffff窗口背景色,下拉才会显示backgroundTextStyleStringdark下拉loding的样式,仅支持dark/lightenablePullDownRefreshBooleanfalse是否开启全局下拉刷新onReachBottomDistanceNumber50上拉触底事件距离页面底部的距离,单位pxtabBar节点tabBar两种:底部tabBar,顶部tabBartabBar至少要配置两项,最多五个顶部的yabBar不会显示icon图标,只显示文本tabBar属性属性类型必填默认值说明positionString否bottomtabBar位置 仅支持bottom/topborderStyleString否blacktabBar上边框的颜色 仅支持black/whitecolorHexColor否 tabBar文本,未选中时的颜色selectedColorHexColor否 tabBar文本,选中时的颜色backgroundColorHexColor否 tabBar的背景色listArray是 tabBar的列表,最少两个,最多五个list数组对象pagePathtab对应的页面路径texttab对应的文本iconPathtab对应的图标selectedIconPathtab选中时的图标// // app.json { "pages": [ "pages/mine/mine", "pages/index/index", "pages/logs/logs", "pages/home/home" ], "window": { "backgroundColor": "#f0f0f0", // 下拉窗口背景色 16进制颜色 "backgroundTextStyle": "dark", // 下拉小圆点的样式 dark / light "navigationBarBackgroundColor": "#ff00ff", // 导航栏背景色 16进制颜色 "navigationBarTitleText": "我的小程序", // 导航栏标题文本 "navigationBarTextStyle": "white", // 导航栏标题文本样式 仅支持white/black "enablePullDownRefresh": true, // 是否开启下拉刷新 全局生效 "onReachBottomDistance": 100 // 上拉触底事件,距离底部的距离 100px }, "tabBar": { "position": "bottom", // tab位置 bottom/top "color": "#000", // tab未选中的文本颜色 "selectedColor": "#f12f00", // tab选中的文本颜色 "backgroundColor": "#f0f0f0", // tab背景色 "list": [ // tab页签选项列表 { "pagePath": "pages/mine/mine", // tab对应的页面路径 "text": "mine", // tab对应的文本 "iconPath": "", // tab对应的图标 "selectedIconPath": "" // tab选中时的图标 }, { "pagePath": "pages/index/index", "text": "index", "iconPath": "", "selectedIconPath": "" }, { "pagePath": "pages/logs/logs", "text": "logs", "iconPath": "", "selectedIconPath": "" } ] }, "style": "v2", "sitemapLocation": "sitemap.json" }小程序网络请求小程序网络请求的限制只能请求https类型的接口接口域名必须要添加到信任列表中(微信公众平台)如何去配置合法接口域名打开微信公众平台 --- 开发 --- 开发管理 --- 开发设置 --- 服务器域名使用wx.request()发起网络请求Page({ onLoad(options) { this.getLoop() // 页面加载之后就会调用 this.onLogin() }, // 发送get请求 getLoop() { wx.request({ url: 'https://www.wrz521.top:8080/api/getLoopArt', // 请求地址 method: 'GET', // 请求方法 data: {}, // 传递的数据 success(res) { // 成功后的回调 console.log(res.data, '请求结果'); }, }) }, // 发送post请求 onLogin() { wx.request({ url: 'https://www.wrz521.top:8080/api/login', method: 'POST', data: { username: 'admin', password: '123456789' }, success(res) { console.log(res.data, '请求结果'); } }) }, })跨域和ajax小程序不存在跨域,不是运行在浏览器上的。ajax依赖于浏览器xhr对象,小程序是依赖微信客户端,不能说是ajax请求,只能说网络数据请求小程序页面导航页面导航的两种方式声明式导航使用navigator组件, 点击navigator组件实现页面跳转跳转tabBar页面 需要指定open-type属性为 switchTab跳转到非tabBar页面 需要指定open-type为navigate编程式导航调用小程序的导航api进行跳转跳转tabBar页面 使用wx.switchTab()跳转到非tabBar页面 使用wx.navigatorTo()跳转到tabBar页面声明式导航:<!-- wxml --> <navigator url="/pages/index/index" open-type="switchTab"> 点击 跳转到tab index页面 </navigator>编程式导航:wx.switchTab()Page({ goTabIndex() { wx.switchTab({ url: '/pages/index/index', success(res) { // 成功回调 console.log(res, 'success'); }, fail(err) { // 失败回调 console.log(err, 'fail'); }, complete(res) { // 成功或失败都会调用 console.log(res, 'complete'); } }) } })跳转到非tabBar页面声明式导航:<!-- wxml --> <navigator url="/pages/home/home" open-type="navigate">点击 跳转到非tab home页面</navigator>编程式导航:wx.navigateTo()Page({ goPageHome() { wx.navigateTo({ url: '/pages/home/home', success(res) { // 成功回调 console.log(res, 'success'); }, fail(err) { // 失败回调 console.log(err, 'fail'); }, complete(res) { // 成功或失败都会调用 console.log(res, 'complete'); } }) }, })后退导航声明式导航使用组件时 指定 open-type属性为navigateBack delta属性为 后退的层级,是一个数字编程时导航使用wx.navigateBack()声明式导航<!-- wxml --> <navigator open-type="navigateBack" delta="1">后退</navigator>编程式导航wx.navigateBack()Page({ goPageHome() { wx.navigateBack({ delta: 1, // 返回的层级 success(res) { // 成功回调 console.log(res, 'success'); }, fail(err) { // 失败回调 console.log(err, 'fail'); }, complete(res) { // 成功或失败都会调用 console.log(res, 'complete'); } }) }, })导航传参声明式导航在url的链接中以查询字符串的形式携带url链接和参数之间 ? 隔开多个参数之间 & 隔开编程式导航在url的链接中以查询字符串的形式携带url链接和参数之间 ? 隔开多个参数之间 & 隔开获取携带的参数在onLoad(options)生命周期函数中,options就是携带的参数对象// wxml <navigator url="/pages/home/home?age=18&name=zs" open-type="navigate"> 点击 跳转到非tab home页面 </navigator>// mine.js Page({ goPageHome() { wx.navigateTo({ url: '/pages/home/home?name=zs&age=18', success(res) { console.log(res, 'success'); }, fail(err) { console.log(err, 'fail'); }, complete(res) { console.log(res, 'complete'); } }) }, })// home.js Page({ onLoad(options) { console.log(options) // 页面参数 {name: zs, age: 18} } })小程序页面事件下拉刷新事件onPullDownRefresh()开启下拉刷新app.json 设置 window节点 设置enablePullDownRefresh: true,全局生效页面的json 设置enablePullDownRefresh: true,只有当前这个页面生效(建议)监听页面的onPullDownRefresh事件下拉刷新会触发需要手动调用wx.stopPullDownRefresh()停止下拉刷新 /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { console.log('页面刷新了'); wx.stopPullDownRefresh({ success(res){ console.log(res, '停止下拉刷新了'); } }) },上拉触底事件onReachBottom()设置上拉触底距离app.json window节点配置 onReachBottomDistance: 100 距离底部100px的位置触发上拉触底事件监听页面的onReachBottom事件上拉到指定位置会触发该事件 /** * 页面上拉触底事件的处理函数 */ onReachBottom() { console.log('上拉触底了'); },滑动页面事件onPageScroll(Object object)参数Object objectscrollTop页面在垂直方向已滚动的距离(单位px)点击右上角菜单‘收藏’按钮onAddToFavorites(Object object)参数Object objectwebViewUrl页面如果包含web-view组件时,会返回web-view的url该事件需要 return一个Object,用来自定义收藏内容Objecttitle自定义标题,默认页面标题或者账号名称imageUrl自定义图片,默认页面截图query自定义query字段,默认当前页面的query更多官方文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html小程序生命周期什么是生命周期一个对象从创建到销毁的过程就是他的生命周期小程序生命周期小程序生命周期可以分为两类:应用生命周期小程序从启动 --> 运行 --> 销毁的过程页面的生命周期小程序每个页面从加载 --> 渲染 --> 销毁的过程其中页面的生命周期范围小,应用生命周期范围大,两者包含关系小程序启动 --> 页面A生命周期 --> 页面B生命周期 --> ... --> 小程序结束生命周期函数生命周期函数会伴随着生命周期,自动依次调用执行。允许我们在某个特定的时间段,做一些操作,例如在页面加载的时候,初始化页面的数据,此时就需要onLoad生命周期函数。应用生命周期函数需要在app.js中调用App(Object object)函数,指定小程序应用的生命周期回调onLaunch当小程序初始化完成时,会触发 onLaunch(全局只触发一次)onShow当小程序启动,或从后台进入前台显示,会触发 onShowonHide当小程序从前台进入后台,会触发 onHideonError当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息onPageNotFound当页面不存在时触发onUnhandledRejection有未处理的promise,reject事件时触发onThemeChange系统主题变化时触发其他可以添加任意的函数或者数据变量,全局使用,通过this进行调用// app.js App({ onLaunch: function () {}, onShow: function (options) {}, onHide: function () {}, onError: function (msg) {}, globalData: { // 可以定义全局的数据或者函数,通过this进行调用 userInfo: null } })页面生命周期函数需要在页面的 .js中调用Page(Object object)函数,指定页面的生命周期回调onLoad页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数onShow页面显示/切入前台时触发onReady页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互onHide页面隐藏/切入后台时触发。如 wx.navigateTo 或底部tab切换到其他页面,小程序切入后台等onUnload页面卸载时触发。如wx.redirectTo或wx.navigateBack到其他页面时// pages/home/home.js Page({ onLoad(options) { console.log(options, '页面参数'); }, onShow() {}, onReady() {}, onHide() {}, onUnload() {}, })更多官方文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html小程序wxs脚本wxs和js区别:wxs通常用作过滤器wxs有自己的数据类型wxs不支持es6及以上的语法形式let const 解构赋值 箭头函数等wxs遵循CommonJs规范module对象require()函数module.exports对象wxs用法内嵌在wxml中定义wxs暴露出一个函数,在{{ }}语法中调用 wxs脚本必须要有一个属性module指定模块名<view>{{ m1.toUpper(username) }}</view> <wxs module="m1"> module.exports.toUpper = function (str) { return str.toUpperCase() } </wxs>外联wxs脚本定义wxs后缀的脚本文件 如 tools.wxs在wxs中定义函数,并暴露在wxml中引入wxs脚本文件,调用m2里边的函数就行<wxs src="../../utils/tools.wxs" module="m2"></wxs>注意点只能搭配{{ }}语法使用,不能作为事件回调来使用wxs不能调用js中的函数wxs不能调用小程序提供的api小程序自定义组件如何自定义在项目根目录components文件夹中创建文件夹右键文件夹,新建Component,会自动生成组件需要的文件局部注册组件在页面的.json文件的usingComponents 节点中注册注册方式 组件名称:组件路径{ "usingComponents": { "my-test": "/componnets/test/test" } }全局注册组件在app.json文件的usingComponents 节点中注册注册方式同上如何使用在wxml中以标签的形式使用<my-test></my-test>组件特点组件样式隔离不会影响其他组件或者页面只有class类选择器才会受到样式隔离如何修改样式隔离在组件的js文件中添加options节点,添加属性styleIsolation为isolatedComponent({ options: { styleIsolation: "isolated" }, })styleIsolation属性值可选值默认值描述isolated是启用样式隔离,组件内外的class类声明的样式不会相互影响apply-shared否页面的wxss样式会影响到组件内部的样式,组件样式不会影响外部shared否组件内外的样式,相互影响组件和页面的区别组件组件的js调用Component(Object object)函数组件的方法函数定义在Component(Object object)函数的methods节点中其他Component函数的节点页面页面的js调用Page(Object object)函数页面的方法函数直接写在里边就好了其他Page函数的节点// 页面js Page({ data: {}, goBack() { // 页面的方法函数,直接写就完事了 wx.navigateBack({ delta: 1, }) }, onLoad(options) { console.log(options, '页面参数'); console.log('onLoad'); } })// 组件js Component({ options: { styleIsolation: "isolated" }, /* 组件的属性列表 用来接收组件上的属性*/ properties: { num: { type: Number, // 属性类型 value: 10 // 默认值 }, num1: Number, // 简化版 }, /* 组件的初始数据 */ data: {}, /* 组件的方法列表 */ methods: { goBack() { // 组件的方法函数,定义在methods节点 wx.navigateBack({ delta: 1, }) }, } })Component(Object object)函数参数Object objectoptions类型:Object描述:组件配置选项data类型:Object描述:存放组件私有数据properties类型:Object | Map描述:组件外传递过来的属性映射,接收methods类型:Object描述:组件的方法函数更多参数节点参考:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html组件数据监听Components函数添加observers节点监听多个字段 num1, num2监听对象的属性 obj.prop1,obj.prop2监听对象所有属性,使用通配符*,obj.* 代表所有的属性Component({ observers: { // 数据监听器 'num, num2': function (newNum, newNum2) { // 监听多个字段 // 做一些事情 }, 'obj.prop1, obj.prop2': function (newProp1, newProp2) { // 监听对象属性 // 做一些事情 }, 'obj.**': function (newObj) { // 监听对象所有的属性 // 做一些事情 } }, })纯数据字段特点:不会再页面中展示渲染不会传递给其他组件使用有利于提升页面更新的性能设置纯数据字段:options节点新增pureDataPattern属性pureDataPattern值是一个正则表达式符合表达式的数据就是纯数据字段Component({ options: { styleIsolation: "isolated", pureDataPattern: /^_/ // 以下划线开头的数据,就是纯数据字段 }, data: { _a: true } })组件生命周期函数生命周期函数created组件示例刚刚创建完执行不能调用setData函数,只能在this上挂载一些自定义属性字段attached组件初始化完毕,进入到页面节点树执行可以发送网络请求,初始化一些数据ready组件在视图布局完成后执行moved组件实例被移动到节点树的另一个位置时执行detached组件实例被从页面节点树移除时执行使用的两种方法:直接和data平级,写就完事了使用 lifetimes节点,生命周期函数写在这里边(推荐)Component({ lifetimes: { created() { console.log('test1组件 created'); }, attached() { console.log('test1组件 attached'); } } })组件所在页面的生命周期函数生命周期函数show组件所在页面显示的时候触发hide组件坐在页面隐藏的时候触发resize组件所在页面的尺寸发生变化的时候触发使用方法新增pageLifetimes节点,将函数写在里边Component({ lifetimes: { created() { console.log('test1组件 created'); }, attached() { console.log('test1组件 attached'); } }, pageLifetimes: { show() { console.log('组件所在页面显示了 show'); }, hide() { console.log('组件所在页面隐藏了 hide'); }, resize() { console.log('组件所在页面窗口尺寸变化了 resize'); } } }) 组件插槽匿名插槽使用slot标签占位时,不设置name属性具名插槽使用slot标签占位时,设置name属性开启组件多插槽组件默认只能使用一个插槽在options节点,新增multipleSlots: true,开启多插槽支持<!-- 组件wxml --> <view> <slot name="before"></slot> <slot></slot> <slot name="after"></slot> </view> <!-- 引用组件的wxml --> <cy-test1> <view slot="after"> 渲染到name为 after的插槽 </view> <view slot="before"> 渲染到name为 before的插槽 </view> <view>渲染到默认插槽</view> </cy-test1>小程序组件传值父子间组件通讯通讯方法:属性绑定绑定属性在子组件上,子组件内通过properties进行接收事件绑定通过bind绑定自定义事件,子组件内通过this. triggerEvent(自定义事件名称, 传递的数据)进行调用获取组件实例直接通过this.selectComponent()获取组件实例父向子传值通过属性绑定<!-- 父组件 使用组件,并添加属性arrList="父组件的某个数据" --> <my-test arrList="{{ arr }}"> <text slot="before">before对应的插槽内容</text> 1231456 <text slot="after">after对应的插槽内容</text> </my-test> <!-- 在子组件的js的properties节点中添加对应的属性,并声明类型或者默认值 --> properties: { arrList: { type: Array } } <!-- 子组件封装 --> <view style="background: pink;"> <slot name="before"></slot> <slot></slot> <slot name="after"></slot> <view>----------</view> <text wx:for="{{ arrList }}" wx:key=" id "> 接受到了父组件传递的数组: {{ item.name }}, {{ item.id }} // 拿到接收到的数据渲染 </text> </view>子向父传值通过事件绑定// 调用组件 并绑定自定义事件 <my-test arrList="{{ arr }}" fatherNum="{{ num }}" bind:getValue="getValue"> <text slot="before">before对应的插槽内容</text> 1231456 <text slot="after">after对应的插槽内容</text> </my-test> // js getValue (e) { console.log(e, '子组件调用父组件的getValue函数'); }, // 子组件触发这个自定义函数 并传值 this.triggerEvent('getValue', {value: 5})获取组件实例使用this.selectComponent() 传入id或者class选择器this.selectComponent('.my-text1') // 组件标签添加class类behaviors类似于vue mixins混入使用方法:创建behaviors,新建一个js文件, 调用Behavior()函数创建一个behavior实例对象,通过module.exports向外暴露,组件调用时,会被合并到组件中// js module.exports = Behavior({ data: {}, properties: {}, methods: {} })通过require导入该js文件,并且在组件的behaviors节点中注册使用const myBehavior = require('../../behaviors/my-behaviors') // 在组件中添加behaviors节点,对应一个数组 behaviors: [myBehavior],behaviors中可用的节点 同组件属性小程序npm包npm包支持和限制不支持依赖nodejs内置库的npm包不支持依赖浏览器对象的npm包不支持依赖c++插件的npm包下载和使用新版: 下载npm包 --> 工具 --> 构建npm包旧版: 下载npm包 --> 右侧详情模块勾选npm包 --> 工具 --> 构建npm包小程序全局共享容器mobx全局共享小程序可以使用mobx-miniprogram和mobx-miniprogram-bindings实现全局数据共享。mobx-miniprogram用来创建store对象mobx-program-bindings用来挂载store容器到页面 或者 组件中如何使用mobx下载npm包npm install mobx-miniprogram --save npm i mobx-miniprogram-bindings --save # or npm install --save mobx-miniprogram mobx-miniprogram-bindings创建store容器新建store.js文件import { observable, action } from 'mobx-miniprogram' // 创建store容器 export const store = observable({ // 数据字段 numA: 1, numB: 2, // 计算属性 get sum() { return this.numA + this.numB }, // action方法 修改数据 update: action(function(a = 0, b = 0) { this.numA += a this.numB += b }) })在页面中使用// js import { createStoreBindings } from 'mobx-miniprogram-bindings' import { store } from '../../store/store' Page({ data: {}, editNum(e) { const a = e.target.dataset.a || 0 const b = e.target.dataset.b || 0 this.update(a, b) }, onLoad(options) { // 挂载store容器 this.storeBindings = createStoreBindings(this, { store, // store容器 fields: ['numA', 'numB', 'sum'], // 映射数据字段和计算属性 actions: ['update'] // 映射action方法 }) }, })<!-- wxml --> <view>{{numA }} + {{ numB }} = {{ sum }}</view> <van-button type="primary" bindtap="editNum" data-a="{{ 1 }}">A + 1</van-button> <van-button type="info" bindtap="editNum" data-b="{{ 1 }}">B + 1</van-button>在组件中使用// js import { storeBindingsBehavior } from 'mobx-miniprogram-bindings' import { store } from '../../store/store' Component({ behaviors: [storeBindingsBehavior], // 挂载behavior storeBindings: { // storeBindings配置选项 store, // fields: ['numA', 'numB', 'sum'], fields: { // 可以自定义变量名称 numABC: 'numA' numA: 'numA', // 直接映射numA numB: () => store.numB, // 函数返回numB sum: (store) => store.sum // 函数返回sum }, // actions: ['update'] actions: { update: 'update' } } properties: {}, data: {}, methods: { editNum(e) { const a = e.target.dataset.a || 0 const b = e.target.dataset.b || 0 this.update(a, b) } } }) 小程序分包什么是分包分包指的是将一个完整的小程序项目根据需求划分为不同的子包,在构建时打包成不同的分包,用户在使用的时候按需进行加载分包特点加载规则小程序启动时,默认会下载主包并且启动主包内的页面(tabbar页面需要放到主包)当用户进入分包内的某个页面,客户端会把对应的分包下载下来,进行展示(非tabbar页面按照功能的不同,划分不同的分包,进行按需下载)体积限制整个小程序的所有分包大小不能超过16M(主包 + 所有分包)单个分包或者主包不能超过2M引用原则普通分包可以引用主包内的公共资源不能引用其他分包的私有资源主包不能引用分包的私有资源独立分包资源独立打包原则小程序会按照subPackages的配置进行分包subPackages之外的目录将被打包到主包中tabbar页面必须要在主包中分包之间不能互相嵌套分包好处可以优化小程序首次启动的下载时间,在多团队协作开发时能够更好的解耦协作项目构成分包前小程序所有的页面和资源都被打包在一起整个项目体积过大,影响小程序的首次启动的下载时间分包后小程序项目由一个主包和多个分包组成主包一般只包含项目的启动页面或者tabbar页面,以及所有分包都需要使用的一些公共资源分包只包含和当前分包有关的页面和私有资源如何配置分包在app.json中添加节点 subPackages 是一个数组,多个分包,就写多个对象 "subPackages": [ { "root": "pkgA", // 分包的根目录 "name": "p1", // 分包的别名 "pages": [ // 分包下面的页面 会自动创建 "pages/cat/cat", "pages/logs/logs" ] } ],独立分包独立分包和普通分包区别独立分包本质上还是分包功能独立不能引用主包公共资源,不能引用分包的私有资源,独立分包之间也不可相互引用,资源完全独立不依赖主包,可以单独运行,提升分包页面的启动速度普通分包普通分包依赖于主包,需要先下载主包可以引用主包公共资源配置独立分包只需要在分包中添加independent为true,则当前分包就是一个独立分包{ "root": "pkgB", "name": "p2", "pages": [ "pages/cat/cat", "pages/logs/logs" ], "independent": true }分包预下载分包预下载指的是,在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升后续进入分包时页面的启动速度配置分包预下载预下载分包的行为,会在进入到指定的页面时触发。在app.json中配置preloadRule节点,定义预下载规则。分包预下载所有页面共享2M,预下载的大小不能超过2M "preloadRule": { "pages/logs/logs": { // 页面路径,哪一个页面,进入这个页面,预加载哪些packges分包 "packages": ["p1", "p2"], // 分包的name别名或者 root根目录 "network": "all" // 下载环境 all 所有 wifi 仅限wifi环境 } },
2022年09月28日
87 阅读
0 评论
0 点赞