佛山网站建设运营,后端低代码平台,公司简介链接怎么制作,网页作图软件目录 一、前期预备 1. 预备知识 2. 注册账号 - 申请AppID 3. 下载小程序开发工具 4. 小程序项目结构 5. 小程序的MVVM架构 二、创建小程序项目 1. 查看注册的appId 2. 创建项目 3. 新建页面 01 - 创建text页面文件夹 02 - 新建text的page 03 - 在app.json中配置 … 目录 一、前期预备 1. 预备知识 2. 注册账号 - 申请AppID 3. 下载小程序开发工具 4. 小程序项目结构 5. 小程序的MVVM架构 二、创建小程序项目 1. 查看注册的appId 2. 创建项目 3. 新建页面 01 - 创建text页面文件夹 02 - 新建text的page 03 - 在app.json中配置 4. 开发初体验 01 - text.wxml 02 - text.js 03 - 效果 三、小程序的架构和配置 1. 小程序的架构模型 01 - 宿主环境 02 - 双线程模型 2. 小程序的配置文件 01 - project.config.json 02 - sitemap.json 03 - app.json 代码 效果 04 - (page).json 代码 效果 四、注册小程序 – App函数 - app.js 作用一 : 判断打开场景 01 - 常见场景 02 - 确定场景 代码 效果 作用二 : 定义全局App的数据 app.js page.js 效果 作用三 : 生命周期函数 五、注册页面 – Page函数 - (page).js 0. 生命周期 1. 发送网络请求 2. 初始数据 3. 绑定事件函数 wxml js 4. 其他的监听 01 - 下拉刷新 logs.json logs.js 效果 02 - 上拉加载更多 logs.json logs.js logs.wxml 效果 03 - 页面滚动 六、常见的内置组件 Text : 文本组件 Button : 按钮组件 基本用法 open-type属性 获取用户信息 wxml js 获取用户手机 wxml js View : 视图组件 ScrollView滚动组件 上下滚动 wxml css js 左右滚动 wxml css js Image : 图片组件 基本使用 使用手机本地图片 wx.chooseMedia wxml js Input : 组件 wxml js 组件的共同属性 七、小程序基础语法 1. Wxss 01 - 样式写法 02 - 选择器 03 - 尺寸单位 2. Wxml 01 - 逻辑判断 02 - hidden 03 - block 04 - 列表渲染 wx:for item - index key 3. Wxs 01 - 概念 02 - 写法 写法一 : 直接写在标签内 写法二 : 独立的文件通过src引入 定义format.wxs wxml 八、小程序的事件处理 1. 组件事件类型 2. 事件对象event 01 - currentTarget target wxml wxss js 02 - touches changedTouches 区别一 : touchend中不同 区别二 : 多手指触摸时不同 03 - 事件参数的传递 wxml js 04 - 事件参数的传递的例子 wxml wxss js 效果 3. 事件冒泡 事件捕获 4. 获取元素的宽高等 九、小程序的组件化开发 1. 概念 2. 创建并使用组件 01 - 创建 02 - 配置 03 - 引入组件 局部注册组件 全局注册组件 04 - 使用组件 05 - 注意事项 3. 组件的样式细节 01 - 组件内的样式 对 外部样式 的影响 02 - 外部的样式 对 组件内样式 的影响 03 - 如何让class可以相互影响 4. 组件的通信 01 - 向组件传递数据 - properties 页面定义 组件接收 02 - 向组件传递样式 - externalClasses 页面定义 页面传递 组件接收 组件使用 03 - 组件向外传递事件 组件定义 组件传递 页面监听 页面处理 04 - 页面直接调用组件方法 组件定义 页面定义 页面使用 5. 组件的插槽 01 - 单个插槽 组件 页面 效果 02 - 具名插槽 组件定义 组件配置 页面使用 03 - 解决默认值问题 组件 样式 6. 组件中的混入 - behaviors 01 - 共享的代码 02 - 组件中使用 7. 组件的生命周期 01 - 概念 02 - 组件所在页面的生命周期 8. 组件Component构造器总结图 十、小程序系统API调用 1. 网络请求 01 - API参数 02 - API使用 03 - API封装 封装成函数 封装 使用 封装成类 封装 使用 04 - 网络请求域名配置 2. 展示弹窗效果 01 - showToast 效果 代码 02 - showLoading 效果 代码 03 - showModal 效果 代码 04 - showActionSheet 效果 代码 3. 分享功能 onShareAppMessage 方式一 方式二 4. 获取设备信息 wx.getSystemInfo 5. 获取位置信息 wx.getLocation 01 - 授权 02 - 获取 6. Storage存储 01 - 同步 02 - 异步 十一、页面跳转 1. 通过wx的API跳转 00 - switchTab - 跳转到 tabBar 页面 01 - navigateTo - 普通页面跳转 02 - navigateBack - 页面返回 03 - 页面跳转 - 数据传递一 首页 详情页 详情页 首页 04 - 页面跳转 - 数据传递二 首页 详情页 详情页 首页 2. 通过navigator组件 01 - 跳转到 tabBar 页面 02 - 跳转到 普通 页面 03 - 返回 上一个 页面 十二、小程序登录解析 1. 概念 01 - openid 02 - unionid 03 - 用户身份多平台共享 2. 登录流程 3. 代码 十三、代码上传到Gitee 1. 创建远程仓库 2. 配置远程仓库 01 - 本地点击版本管理 02 - 添加远程仓库 03 - 设置用户名和邮箱 04 - 设置网络和认证 3. 推送代码到远程仓库 01 - 首次推送 02 - 修改后推送 推送到本地仓库 拉取远程仓库代码 推送到远程仓库 一、前期预备
1. 预备知识
小程序的核心技术主要是三个
页面布局WXML类似HTML页面样式WXSS几乎就是CSS(某些不支持某些进行了增强但是基本是一致的)页面脚本JavaScriptWXS(WeixinScript)2. 注册账号 - 申请AppID 网址 : 微信小程序 3. 下载小程序开发工具 网址 : 微信开发者工具下载地址与更新日志 | 微信开放文档 4. 小程序项目结构 5. 小程序的MVVM架构 Vue的MVVM和小程序MVVM对比 MVVM : DOM Listeners: ViewModel层可以将DOM的监听绑定到Model层Data Bindings: ViewModel层可以将数据的变量, 响应式的反应到View层MVVM架构将 命令式编程 转移到 声明式编程
二、创建小程序项目
1. 查看注册的appId 网址 : 小程序 2. 创建项目 3. 新建页面 01 - 创建text页面文件夹 02 - 新建text的page 03 - 在app.json中配置 可能会自动注册完成 ps : 也可以反向注册在这里直接配置文件夹会自动生成 4. 开发初体验 01 - text.wxml !--pages/text/text.wxml--
!-- 1. 普通文本 --
viewtext页面/view!-- 2. 数据绑定使用 {{}} 这个语法 --
view{{message}}/view!-- 3. 列表渲染 --
block wx:for{{movies}} wx:keyitemviewitem : {{item}} index: {{index}}/view
/block!-- 4. 事件监听 --
view styletext-align: center当前计数 : {{counter}}/view
button bindtapincrement1/button
button bindtapdecrement-1/button 02 - text.js 直接修改data中的数据不会引起页面的刷新 小程序和react中都不会只有vue劫持了属性才能直接操作 ps : 修改data并且希望页面重新渲染必须使用 this.setData() // pages/text/text.js
Page({/*** 页面的初始数据*/data: {// 1. 数据绑定{{}} 语法message: star,// 2. 列表渲染数据movies: [迪迦大战肯德基, 图图和小新抢东西吃],// 3. 计数器参数counter: 0},// 监听计数器增加按钮触发increment() {// 此方法修改后的数据不会在页面上响应// this.data.counter 1this.setData({counter: this.data.counter 1})},// 监听计数器减少按钮触发decrement() {this.setData({counter: this.data.counter - 1})},
}) 03 - 效果 三、小程序的架构和配置
1. 小程序的架构模型
01 - 宿主环境 小程序的宿主环境 微信客户端 ps : 宿主环境为了执行小程序的各种文件wxml文件、wxss文件、js文件 02 - 双线程模型
当小程序基于 WebView 环境下时WebView 的 JS 逻辑、DOM 树创建、CSS 解析、样式计算、Layout、Paint (Composite) 都发生在同一线程在 WebView 上执行过多的 JS 逻辑可能阻塞渲染导致界面卡顿以此为前提小程序同时考虑了性能与安全采用了目前称为「双线程模型」的架构
双线程模型 :
WXML模块和WXSS样式运行于 渲染层渲染层使用WebView线程渲染一个程序有多个页面会使用多个WebView的线程JS脚本app.js/home.js等运行于 逻辑层逻辑层使用JsCore运行JS脚本这两个线程都会经由微信客户端Native进行中转交互注 : wxs是和渲染层呆在一起的2. 小程序的配置文件 01 - project.config.json 项目配置文件 比如项目名称、appid等 网址 : 项目配置文件 | 微信开放文档 02 - sitemap.json 小程序搜索相关的 网址 : sitemap 配置 | 微信开放文档 03 - app.json 全局配置 网址 : 全局配置 | 微信开放文档 pages : 页面路径列表 用于指定小程序由哪些页面组成每一项都对应一个页面的 路径含文件名 信息小程序中所有的页面都是必须在pages中进行注册的全局配置 - pages | 微信开放文档window : 全局的默认窗口展示 用户指定窗口如何展示, 其中还包含了很多其他的属性全局配置 - window | 微信开放文档tabBar : 顶部tab栏的展示 全局配置 - tabBar | 微信开放文档代码 {pages: [// 默认显示的页面pages/text/text,pages/index/index,pages/logs/logs],window: {// 下拉 loading 的样式仅支持 dark 黑色 / light 白色// 需要到页面的.json中加入 enablePullDownRefresh: true 开启即可// 最好别在全局开启下拉刷新backgroundTextStyle: dark,// 导航栏背景颜色navigationBarBackgroundColor: #f00,// 导航栏标题文字内容navigationBarTitleText: Weixin,// 导航栏标题颜色仅支持 black / whitenavigationBarTextStyle: black},// 底部导航按钮tabBar: {// 文字默认的颜色color:#fff,// 选中时文字的颜色selectedColor:#ff8189,// 导航是一个数组list: [{// 页面路径pagePath: pages/index/index,// 文本text: 首页,// 默认显示的图标iconPath: assets/images/tabbar/home.png,// 选中时显示的图标selectedIconPath: assets/images/tabbar/home_active.png},{pagePath: pages/text/text,text: 记录,iconPath: assets/images/tabbar/category.png,selectedIconPath: assets/images/tabbar/category_active.png}]},// 表明启用新版的组件样式style: v2,// 配置搜索相关文件基本不需更改sitemapLocation: sitemap.json
} 效果 04 - (page).json 页面配置 每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置 页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项 网址 : 页面配置 | 微信开放文档 代码 {// 是否使用组件usingComponents: {// 需要在这里配置},// 页面顶部标题文字navigationBarTitleText: 冲啊,// 页面顶部标题颜色navigationBarTextStyle: white,// 页面顶部背景颜色navigationBarBackgroundColor: #0f0,// 是否开启下拉刷新 // Page.js 中onPullDownRefresh 开启这个可以监听到是否下拉刷新了enablePullDownRefresh: true,
} 效果 四、注册小程序 – App函数 - app.js 每个小程序都需要在 app.js 中调用 App 函数 注册小程序示例 网址 : App(Object object) | 微信开放文档 在注册时, 可以绑定对应的生命周期函数在生命周期函数中, 执行对应的代码
注册App时一般做如下事情 :
监听生命周期函数在生命周期中执行对应的业务逻辑比如在某个生命周期函数中进行登录操作或者请求网络数据判断小程序的进入场景因为App()实例只有一个并且是全局共享的单例对象所以我们可以将一些共享数据放在这里作用一 : 判断打开场景 01 - 常见场景 小程序的打开场景较多 : 常见的打开场景 群聊会话中打开小程序列表中打开微信扫一扫打开另一个小程序打开场景值 : 微信开放文档 - 场景值列表
02 - 确定场景 在 onLaunch 和 onShow 生命周期回调函数中会有options参数其中有scene值 代码 // app.js
App({/*** 生命周期回调——监听小程序初始化。* 小程序初始化时触发只有执行一次*/onLaunch(options) {console.log(onLaunch , scene :, options.scene);// 登录wx.login({success: res {// 发送 res.code 到后台换取 openId, sessionKey, unionId}})},/*** 生命周期回调——监听小程序启动或切前台* 每次打开小程序都会执行*/onShow(options) {console.log(onShow , scene :, options.scene);// 可根据场景值跳转到对应的页面wx.navigateTo({// url: url,})},onHide() {console.log(onHide 隐藏~);}
}) 效果 作用二 : 定义全局App的数据 注意 : 定义在全局的数据不会响应式 共享的数据通常是一些固定的数据 app.js // app.js
App({// 定义的全局变量globalData: {token: ,userInfo: {name: coder,age: 18}},// 页面初始化调用的回调函数onLaunch(options) {// 登录wx.login({success: res {console.log(code , res.code);// 发送 res.code 到后台换取 openId, sessionKey, unionIdthis.globalData.token res.token || abcdefghijklmnopqrstuvwxyz}})}
}) page.js // pages/text/text.js
Page({// 页面加载的时候触发/*** 获取页面所需数据*/onLoad() {// 获取共享的数据// 1. 获取app实例对象const app getApp()// 2. 从app实例对象中获取数据const token app.globalData.tokenconst userInfo app.globalData.userInfoconsole.log(userInfo :, userInfo);console.log(token :, token);// 3. 拿到token后发送网络请求// wx.request({// url: url,// token// })// 4. 展示数据到页面this.setData({userInfo})},/*** 页面的初始数据*/data: {userInfo: {}},
}) 效果 作用三 : 生命周期函数 在生命周期函数中完成应用程序启动后的初始化操作 比如登录操作比如读取本地数据类似于token然后保存在全局方便使用比如请求整个应用程序需要的数据 这里简单写写详细的登录操作在下方 // app.js
App({// globalDataglobalData: {userState: {openId: ,sessionKey: ,unionId: },userInfo: {}},// 页面初始化调用的回调函数onLaunch(options) {// 从本地获取用户状态信息判断是否需要登录const userState wx.getStorageSync(userState)// 如果不存在则进行登录if (!userState || !userState.openId) {wx.login({success: res {console.log(code , res.code);// 发送 res.code 到后台换取 openId, sessionKey, unionIdthis.getUserState(res.code)}})}},// 获取用户信息getUserState(code) {wx.request({// 填入请求地址url: url,code,success: (res) {const { openId, unionId, sessionKey, userInfo } res// 将登录成功的数据保存在storage中wx.setStorageSync(userState, {openId,unionId,sessionKey,})wx.setStorageSync(userInfo, userInfo)// 将登录成功的数据保存在globalData中this.globalData.userState {openId,unionId,sessionKey,}this.globalData.userInfo userInfo}})// }
}) 五、注册页面 – Page函数 - (page).js 小程序中的每个页面, 都有一个对应的js文件, 其中调用 Page函数 注册页面示例 网址 : Page(Object object) | 微信开放文档 在注册时, 可以绑定初始化数据、生命周期回调、事件处理函数等
注册Page页面时一般做如下事情 :
在生命周期函数中发送网络请求从服务器获取数据初始化一些数据以方便被wxml引用展示监听wxml中的事件绑定对应的事件函数其他一些监听比如页面滚动、上拉刷新、下拉加载更多等
0. 生命周期 网址 : 生命周期 | 微信开放文档 1. 发送网络请求 // logs.js
Page({data: {pagaData: {}},// 页面加载时促发onLoad() {const _this this// 发送网络请求wx.request({url: www.baidu.com,success: (res) {console.log(this, res);this.setData({pagaData: res.pagaData || {}})},error(err) {console.log(_this, err);}})}
}) 2. 初始数据 // logs.js
Page({data: {// 定义初始化数据movies: [葫芦娃大战喜羊羊, 蜡笔小新殴打图图],},// 页面加载时促发onLoad() { }
}) 3. 绑定事件函数
wxml !--logs.wxml--
viewbutton bindtaphandClick事件触发/buttonbutton------/buttonbutton bindtapclickQuerydata-queryabc触发并传递参数/buttonbutton------/buttonbutton wx:for{{btns}}wx:key*thisbindtapbtnsClickdata-index{{index}}data-item{{item}}stylebackground-color: {{item}};{{item}} - {{index}}/button
/view js // logs.js
Page({data: {// 定义初始化数据btns: [red, blue, green, pink, yellow],},// 页面加载时促发onLoad() { },// 绑定事件handClick() {console.log(我被点击了);},// 传递参数clickQuery(e) {console.log(我被点击了,参数是 : , e.target.dataset);},btnsClick(e) {console.log(循环出的按钮, e.target.dataset);}
}) 4. 其他的监听
01 - 下拉刷新 logs.json {usingComponents: {},// 开启下拉刷新enablePullDownRefresh: true
} logs.js // logs.js
Page({data: {},// 监听用户下拉刷新onPullDownRefresh() {console.log(用户下拉刷新);// 模拟网络请求setTimeout(() {// api: 停止下拉刷新wx.stopPullDownRefresh({success: (res) {console.log(成功关闭下拉刷新, res);},fail: (err) {console.log(关闭失败, err);}})}, 1000);}
}) 效果 02 - 上拉加载更多 logs.json {usingComponents: {},// 页面上拉触底事件触发时距页面底部距离单位为px// 距离底部多少距离触发onReachBottomDistance: 100
}logs.js // logs.js
Page({data: {// 默认展示50条数据countsNum: 50,// 到达底部后需要增加的数量countsSize: 40},// 监听页面是否滚动到达底部onReachBottom() {this.setData({// 到达底部后增加countsNum: this.data.countsNum this.data.countsSize})console.log(滚动到底部);}
})logs.wxml !--logs.wxml--
view wx:for{{countsNum}} wx:key*this页面数据 : {{item}}
/view 效果 03 - 页面滚动 // logs.js
Page({data: {// 定义初始化数据btns: [red, blue, green, pink, yellow],},// 页面加载时促发onLoad() { },// 页面滚动onPageScroll(e) {console.log(e); // 距离顶部的距离},
}) 六、常见的内置组件
Text : 文本组件 Text组件 : 用于显示文本, 类似于span标签, 是行内元素 text | 微信开放文档 !-- 基本用法 --
textHello world/text!-- 使用js中定义的数据 --
text{{message}}/text!-- 长按可选择可用来复制 --
text user-select{{message}}/text!-- 解码 --
text decodegt;/text Button : 按钮组件 Button组件用于创建按钮默认块级元素 button | 微信开放文档 基本用法
!-- 默认 独占一行 --
button按钮/button!-- size属性 变成了inline-block --
button sizeminisize属性/button!-- type属性 可更改背景、颜色 --
button sizeminitypedefault文字颜色变绿/button
button sizeminitypeprimary背景颜色变绿/button
button sizeminitypewarn文字颜色变红/button!-- plain 镂空效果 --
button sizeminiplain 镂空效果有边框 /button!-- 禁用 --
button sizeminidisabled 禁止交互 /button!-- 加载效果 前方有个小圆圈在转可动态绑定 --
button sizeminiloading{{true}} 等待加载 /button
open-type属性 open-type用户获取一些特殊性的权限可以绑定一些特殊的事件 获取用户信息 wxml
!-- 获取用户信息 --
button bindtapgetUserProfile获取用户信息/button js
Page({getUserProfile(e) {// 推荐使用 wx.getUserProfile 获取用户信息开发者每次通过该接口获取用户个人信息均需用户确认// 开发者妥善保管用户快速填写的头像昵称避免重复弹窗wx.getUserProfile({desc: 用于完善会员资料, // 声明获取用户个人信息后的用途后续会展示在弹窗中请谨慎填写// 点击允许success: (res) {console.log(success, res);},// 点击拒绝fail: (err) {console.log(fail, err);}})}
}) 获取用户手机 wxml
!-- 获取用户手机号 --
button open-typegetPhoneNumberbindgetphonenumbergetPhoneNumber获取用户手机号/button js
Page({getPhoneNumber(e) {// 如果点击了拒绝if (e.target.errMsg ! getPhoneNumber:ok) {return wx.showToast({title: 用户未同意授权手机号,icon: none})}// 如果点击确认cosnt { code, encryptedData, iv } e.target// 把数据传给后端后端会去解密拿到手机号的wx.request({url: https://example.com/onLogin,data: {appId: ,openId: ,code,encryptedData,iv},method: post,success: function (res) {console.log(res);}})}
})
View : 视图组件 View视图组件 : 块级元素独占一行通常用作容器组件和div差不多 view | 微信开放文档 ScrollView滚动组件 scroll-view : 可以实现局部滚动 scroll-view | 微信开放文档 上下滚动 wxml
!-- 固定高度上下滚动( y轴 : scroll-y ) --
scroll-view classcontain scroll-yscroll-ybindscrolltoupperscrollTopbindscrolltolowerscrollBottombindscrollscrollIngblock wx:for{{viewColors}}wx:key*thisview classboxstylebackground-color: {{item}}{{item}}/view/block
/scroll-view css
.contain {height: 300px;
}.box {height: 100px;color: white;font-weight: bold;
} js
Page({data: {viewColors: [red, pink, green, blue]},scrollTop() {console.log(到达顶部);},scrollBottom() {console.log(到达底部);},// 滚动中触发scrollIng({ detail }) {console.log(detail);}
})
左右滚动 注 : 若要开启flex布局须加上enable-flex这个属性 wxml
!-- 固定宽度左右滚动( x轴 : scroll-x ) --
scroll-view classcontain scroll-xscroll-xenable-flexbindscrolltoupperscrollLeftbindscrolltolowerscrollRightbindscrollscrollIngblock wx:for{{viewColors}}wx:key*thisview classboxstylebackground-color: {{item}}{{item}}/view/block
/scroll-view css
.contain {display: flex;
}.box {/* 不压缩 */flex-shrink: 0;width: 150px;height: 150px;color: white;font-weight: bold;
} js
Page({data: {viewColors: [red, pink, green, blue]},scrollLeft() {console.log(到达左侧);},scrollRight() {console.log(到达右侧);},// 滚动中触发scrollIng({ detail }) {console.log(detail);// detail.deltaX 0,往左滚动// detail.deltaX 0,往右滚动}
})
Image : 图片组件 Image组件 : 用于显示图片 image | 微信开放文档 基本使用
!-- image : 默认自带宽度和高度 320 * 240 --!-- 根目录 : / 表示根目录有些地方能用有些不行 --
!-- image src/assets/images/zznh.png / --!-- 加载本地图片 --
image src../../assets/images/zznh.png /
!-- 加载网络图片 --
image srchttps://uploadfile.bizhizu.cn/up/9d/8d/1e/9d8d1e3fba7895d13a639f464ef147b1.jpg.source.jpg /!-- 使用mode属性 --
image src../../assets/images/zznh.png modewidthFix /
使用手机本地图片 wx.chooseMedia wxml
!-- 选择手机本地图片将本地图片展示出来 --
button bindtapchoseImagetypeprimary进入相册选择图片/buttonimage wx:if{{imgUrl}}src{{imgUrl}}stylewidth: 100%;modewidthFix / js
Page({data: {imgUrl: },choseImage() {// 选择本地图片wx.chooseMedia({// 最多可以选择的文件个数count: 1,// 只能拍摄图片或从相册选择图片mediaType: image,}).then(res {if (res.errMsg ! chooseMedia:ok) returnconsole.log(res);const imageList res.tempFiles || []const imgUrl imageList[0].tempFilePath || this.setData({imgUrl})})}
})
Input : 组件 model:value 双向绑定功能 wxml
input typetext model:value{{message}} /
js
Page({data: {message: abc},
})
组件的共同属性 七、小程序基础语法
1. Wxss
01 - 样式写法 页面样式的三种写法行内样式、页面样式、全局样式 优先级依次是行内样式 页面样式 全局样式 02 - 选择器 权重 03 - 尺寸单位 rpxresponsive pixel: 可以根据屏幕宽度进行自适应规定屏幕宽为750rpx 在iphone6上屏幕宽度为375px共有750个物理像素1px 2rpx iphone6为标准设计稿是3751px 2rpx 设计稿16px我们写32rpx iphone6为标准设计稿是7501px 1rpx 设计稿20px我们写20rpx .view {/* 在375的设计稿中200rpx 100px */width: 200rpx;height: 200rpx;background-color: blue;line-height: 200rpx;text-align: center;color: #fff;
}
2. Wxml
01 - 逻辑判断 wx:if --- wx:elif --- wx:else viewtext wx:if{{counter 90}}优秀/texttext wx:elif{{counter 60}}及格/texttext wx:else不及格/text
/view
02 - hidden
hidden属性:
hidden是所有的组件都默认拥有的属性当hidden属性为true时, 组件会被隐藏当hidden属性为false时, 组件会显示出来hidden和wx:if的区别 hidden 控制隐藏和显示是控制是否添加hidden属性相当于display:none wx:if 是控制组件是否渲染的 03 - block block : 并不是一个组件它仅仅是一个包装元素不会在页面中做任何渲染只接受控制属性 将需要进行遍历或者判断的内容进行包裹将遍历和判断的属性放在block便签中不影响普通属性的阅读提高代码的可读性
04 - 列表渲染 wx:for index : 遍历后在wxml中可以使用一个变量index保存的是当前遍历数据的下标值 item : 数组中对应某项的数据 !-- 遍历一个数组 a,b,c --
view wx:for{{[a,b,c]}}wx:key*this{{item}} --- {{index}}/view!-- 遍历一个字符串 p,o,i,p,o,i --
view wx:for{{poipoi}}wx:keyitem{{item}} --- {{index}}/view!-- 遍历数字 0 - 9 --
view wx:for{{10}}wx:key*this{{item}} --- {{index}}/view item - index wx:for-item item 重命名 wx:for-index index 重命名 view wx:for{{[a,b,c]}}wx:for-itemstrwx:for-indexkeywx:key*this{{str}} --- {{key}}/view key 使用wx:for时可以添加一个key来提供性能 wx:key 的值以两种形式提供
字符串 代表在 for 循环的 array 中 item 的某个 property该 property 的值需要是列表中唯一的字符串或数字且不能 动态改变保留关键字 *this 代表在 for 循环中的 item 本身这种表示需要 item 本身是一个唯一的字符串或者数字 3. Wxs
01 - 概念 WXSWeiXin Script是小程序的一套脚本语言结合 WXML可以构建出页面的结构 为什么要设计WXS语言
在WXML中是不能直接调用Page/Component中定义的函数的 ( 底层没有进行封装 )但是某些情况, 我们可以希望使用函数来处理WXML中的数据(类似于Vue中的过滤器)这个时候就使用WXS了
WXS使用的限制和特点 :
WXS 不依赖于运行时的基础库版本可以在所有版本的小程序中运行WXS 的运行环境和其他 JavaScript 代码是隔离的WXS 中不能调用其他 JavaScript 文件中定义的函数也不能调用小程序 提供的API由于运行环境的差异在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备 上二者运行效率 无差异最好使用ES6之前的语法否则可能会有问题
02 - 写法 WXS有两种写法 :写在标签中 || 写在以.wxs结尾的文件中 WXS标签的属性 : wxs :
每一个 .wxs 文件和 标签都是一个单独的模块每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数默认为私有的对其他模块不可见一个模块要想对外暴露其内部的私有变量与函数只能通过 module.exports 实现 写法一 : 直接写在标签内
!-- 1. 定义wxs标签设定模块名 --
wxs moduleformat// 2. 定义函数function priceFormat(price) {return price 元}// 3. 导出 : 必须导出后才能被使用且必须被CommonJs导出module.exports {priceFormat: priceFormat}
/wxs!-- 4. 使用 : 使用模块名.函数 进行使用 --
view wx:for{{[111,222,333]}}wx:for-itemmoneywx:for-indexkeywx:key*this{{format.priceFormat(money)}}/view
!-- 5. 输出 : 111元、222元、333元 -- 写法二 : 独立的文件通过src引入 定义format.wxs
// 1. 定义函数
function priceFormat(price) {return price 元
}
// 2. 导出 : 必须导出后才能被使用且必须被CommonJs导出
module.exports {priceFormat: priceFormat
} wxml
!-- 3. 定义wxs标签设定模块名引入wxs文件 --
wxs moduleformat src./format.wxs /!-- 4. 使用 : 使用模块名.函数 进行使用 --
view wx:for{{[111,222,333]}}wx:for-itemmoneywx:for-indexkeywx:key*this{{format.priceFormat(money)}}/view
!-- 5. 输出 : 111元、222元、333元 --
八、小程序的事件处理
1. 组件事件类型 某些组件会有自己特性的事件类型 input : bindinput || bindblur || bindfocus scroll-view : bindscrolltowpper || bindscrolltolower 2. 事件对象event 当某个事件触发时, 会产生一个事件对象, 并且这个对象被传入到回调函数中 01 - currentTarget target target : 触发事件的元素 currentTarget : 处理事件的元素大部分情况使用target wxml
view idouter classouter bindtapouterClickview idinner classinner/view
/view wxss
.outer {width: 400rpx;height: 400rpx;background-color: #0f0;display: flex;justify-content: center;align-items: center;margin: 100rpx auto;
}.inner {width: 150rpx;height: 150rpx;background-color: #00f;
} js
Page({outerClick(e) {console.log(e);// target : 触发事件的元素 点击的是蓝色所以 target innerconsole.log(target:, e.target);// currentTarget : 处理事件的元素 冒泡到外层了所以 currentTarget outerconsole.log(currentTarget:, e.currentTarget);}
})
02 - touches changedTouches touches : 当前屏幕上有多少个手指 changedTouches : 较上一个状态改变了多少个手指 区别一 : touchend中不同 区别二 : 多手指触摸时不同 03 - 事件参数的传递 方式一 : 使用data-* 方式二 : 使用mark ( 2.7.1版本以上 ) 事件 | 微信开放文档 data- : 需要区分currnetTarget 和 target一般使用currnetTarget即可 mark : 会自动合并所有的mark数据不受影响 wxml
view idouterclassouterbindtapouterClickdata-namecoderdata-age18mark:address地球text mark:know是的传递/text
/view js
Page({outerClick(e) {// 通过data- : 传递过来的数据const { name, age } e.currentTarget.datasetconsole.log(name, age);// 通过mark : 传递过来的数据子组件和父组件mark数据会合并console.log(e.mark); // { know: 是的, address: 地球 }const { address } e.markconsole.log(address);}
})
04 - 事件参数的传递的例子 wxml
view classnavblock wx:for{{dataList}}wx:key*thisview classitembindtapitemClickdata-index{{index}}text classtext {{currentIndex index ? active : }}{{item}}/text/view/block
/view wxss
.nav {display: flex;align-items: center;height: 100rpx;
}.item {flex: 1;text-align: center;
}.text {display: inline-block;padding-bottom: 10rpx;border-bottom: 6rpx solid #fff;
}.active {border-bottom-color: orange;
} js
Page({data: {dataList: [衣服, 裤子, 鞋子],currentIndex: 0},itemClick(e) {// 注意这个时候使用currentTarget才能拿到传递过来的参数// 如果不这么做那么点到文字上就不会进行切换const { index } e.currentTarget.datasetthis.setData({currentIndex: index})}
})效果 3. 事件冒泡 事件捕获 事件捕获 : 从外到内 事件冒泡 : 从内到外 总是先捕获再冒泡 bind : 继续传递 bind* 冒泡监听到后继续传递capture-bind* 捕获监听到后继续传递catch : 停止传递 catch* 冒泡监听到后即停止不传递 capture-catch* 捕获到后即停止不传递
4. 获取元素的宽高等
const query wx.createSelectorQuery()
query.select(.swiper-item-layout).boundingClientRect()
query.exec((res) {const winWid wx.getSystemInfoSync().windowWidth // 获取当前屏幕的宽度const height res[0].height // 获取元素的高度const width res[0].width // 获取元素的宽度const swiperHeight height / width * winWid px // 等比例设置值this.swiperHeight swiperHeight
})
九、小程序的组件化开发
1. 概念 小程序刚刚推出时是不支持组建化的1.6.3版本后开始支持 组件化思想的应用 :
尽可能的将页面拆分成一个个小的、可复用的组件让代码更加方便组织和管理并且扩展性也更强
2. 创建并使用组件
01 - 创建 02 - 配置 需要在 json 文件中进行自定义组件声明 将component 字段设为 true 可这一组文件设为自定义组件 03 - 引入组件 局部注册组件 在页面的json文件中配置usingComponents即可在页面中使用 全局注册组件 在app.json的usingComponents声明某个组件那么所有页面和组件可以直接使用该组件 04 - 使用组件
view!-- 使用即可 --main-list /
/view
05 - 注意事项
自定义组件也是可以引用自定义组件 使用usingComponents 字段自定义组件和页面所在项目根目录名 不能以“wx-”为前缀 否则会报错
3. 组件的样式细节
01 - 组件内的样式 对 外部样式 的影响 组件内的class样式 : 只对组件wxml内的节点生效, 对于引用组件的Page页面不生效 ps : 组件内不能使用id选择器、属性选择器、标签选择器 因为会作用到外面不安全 02 - 外部的样式 对 组件内样式 的影响 外部使用class的样式 : 只对外部wxml的class生效对组件内是不生效的ps : 外部使用了id选择器、属性选择器不会对组件内产生影响 外部使用了标签选择器会对组件内产生影响 03 - 如何让class可以相互影响 在Component对象中可以传入一个options属性 其中options属性中有一个styleIsolation隔离属性 styleIsolation有三个取值 :
isolated默认取值取隔离即可 表示启用样式隔离在自定义组件内外使用 class 指定的样式将不会相互影响apply-shared 表示页面的样式将影响到自定义组件但自定义组件中的样式不会影响页面shared 表示页面的样式将影响到自定义组件自定义组件的样式也会影响页面和其他设置......
// pages/logs/components/mainList.js
Component({options: {// 1. 默认值相互不影响// styleIsolation: isolated,// 2. 页面可以影响组件内部组件内部不能影响页面// styleIsolation: apply-shared,// 3. 相互都能影响styleIsolation: shared,}
})
4. 组件的通信 01 - 向组件传递数据 - properties 可以使用 properties 属性 支持的类型 String、Number、Boolean、Object、Array、null不限制类型默认值 通过value设置默认值页面定义
view!-- 使用组件 --main-list title我要飞的更高 /
/view 组件接收
// pages/logs/components/mainList.js
Component({properties: {// 传递过来的数据title: {type: String,value: 我是默认的}}
})
02 - 向组件传递样式 - externalClasses 说实话有点繁琐咕噜咕噜 页面定义 页面传递 组件接收 组件使用 03 - 组件向外传递事件 组件定义 组件传递 页面监听 页面处理 04 - 页面直接调用组件方法 可在父组件里调用 this.selectComponent 获取子组件的实例对象 调用时需要传入一个匹配选择器 selector如this.selectComponent(.my-component) ps : 如果有多个可以使用 this.selectAllComponents 组件定义
// pages/logs/components/mainList.js
Component({data: {dataList: [衣服, 裤子, 鞋子],currentIndex: 0},// 绑定的方法methods: {itemClick(e) {const { index } e.currentTarget.datasetthis.setData({currentIndex: index})this.triggerEvent(itemClick, index)},// 定义一个方法textFun() {console.log(我是组件的方法);}}
}) 页面定义
view!-- 使用组件定义一个选择器这里用class --main-list classmain-list-refbind:itemClickitemClick /
/view 页面使用
Page({itemClick(params) {const { detail: index } paramsconsole.log(index);},onShow() {// 1. 获取自定义组件实例通过类选择器const mainListRef this.selectComponent(.main-list-ref)// 2. 调用自定义组件方法mainListRef.textFun()// 3. 获取自定义组件数据console.log(mainListRef.data.dataList); // [衣服, 裤子, 鞋子]}
})
5. 组件的插槽 小程序的插槽不支持默认值 01 - 单个插槽 组件
view classboxview classheaderheader/viewview classcontent!-- 定义插槽 --!-- 注 : 当没有传进来东西时这里不会显示 --slot/slot/viewview classfooterfooter/view
/view 页面
view!-- 使用组件时在标签中间写的内容会传递到slot中 --main-list123/main-listmain-list!-- 使用组件时在标签中间写的内容会传递到slot中 --buttona/button/main-listmain-list!-- 使用组件时在标签中间写的内容会传递到slot中 --text冲啊/text/main-list/view 效果 02 - 具名插槽 组件定义
view classboxview classleft!-- 插槽名称为left --slot nameleft/slot/viewview classcenter!-- 插槽名称为center --slot namecenter/slot/viewview classright!-- 插槽名称为right --slot nameright/slot/view
/view 组件配置
// pages/logs/components/mainList.js
Component({options: {// 开启使用多个插槽 具名插槽multipleSlots: true}
}) 页面使用
viewmain-list!-- 使用左侧的插槽 --view slotleftA/view/main-listmain-list!-- 使用中间的插槽 --view slotcenterB/view/main-listmain-list!-- 使用右边的插槽 --text slotright冲啊/text/main-list
/view
03 - 解决默认值问题 小程序的插槽不支持默认值 可以用css的empty伪类 兄弟选择器来解决 组件
view classboxview classheaderheader/viewview classcontent!-- 注 : 当没有传进来东西时这里不会显示 --slot/slot/view!-- 当插槽无内容时默认显示 --view classdefault哈哈哈哈我是默认/viewview classfooterfooter/view
/view 样式
/* 默认 隐藏默认值 */
.default {display: none;
}/* 当插槽为空时显示 运用empty伪类 兄弟选择器 */
.content:empty.default {display: block;
}
6. 组件中的混入 - behaviors behaviors 是用于组件间代码共享的特性类似于一些编程语言中的 “mixins” 每个 behavior 可以包含一组属性、数据、生命周期函数和方法组件引用它时它的属性、数据和方法会被合并到组件中生命周期函数也会在对应时机被调用每个组件可以引用多个 behavior behavior 也可以引用其它 behavior
01 - 共享的代码
// 创建一个Behavior并导出
export const counterBehaviors Behavior({// 定义数据data: {count: 10},// 接收参数properties: {},// 引入其他behaviorsbehaviors: [],// 定义方法methods: {text() {console.log(text);}}
})
02 - 组件中使用
// 1. 倒入behaviors
import { counterBehaviors } from ../../../behaviors/counterComponent({// 2. 组件使用behaviorsbehaviors: [counterBehaviors]
})
7. 组件的生命周期
01 - 概念 组件的生命周期指的是组件自身的一些函数这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发 ps : 最重要的生命周期是 created attached detached 组件的的生命周期也可以在 lifetimes 字段内进行声明这是推荐的方式其优先级最高 Component({// 生命周期写在这里面lifetimes: {// 组件实例被创建可以用来进行网络请求created() {console.log(created);},// 组件实例进入页面节点树中attached() {console.log(attached);},// 组件渲染布局完成后ready() {console.log(ready);},// 组件被移除时detached() {console.log(detached);}}
})
02 - 组件所在页面的生命周期 一些特殊的生命周期它们并非与组件有很强的关联但有时组件需要获知以便组件内部处理 组件所在页面的生命周期 在 pageLifetimes 定义段中定义 Component({// 组件生命周期lifetimes: {created() {console.log(created); // 1},attached() {console.log(attached); // 2},ready() {console.log(ready); // 4},detached() {console.log(detached);}},// 组件所在页面的生命周期pageLifetimes: {show() {console.log(show, 组件所在页面被展示时执行); // 3},hide() {console.log(hide, 组件所在页面被隐藏时执行);},resize(e) {console.log(resize, 组件所在页面尺寸变化时执行, e);}}
})
8. 组件Component构造器总结图 十、小程序系统API调用
1. 网络请求 微信提供了专属的API接口,用于网络请求: wx.request(Object object) 网址 : RequestTask | 微信开放文档 01 - API参数 02 - API使用
Page({data: {dataList: []},onLoad() {wx.request({// 请求地址url: https://www.baidu.com/,// 不管是post还是get请求参数都是放到data中的data: {age: 18},// 请求成功的回调success: (res) {const data res.data.dataconsole.log(data);this.setData({dataList: data})},// 请求失败的回调fail: (err) {console.log(err);}})}
})
03 - API封装 封装成函数 封装
export function request(option) {return new Promise((resolve, reject) {wx.request({...option,success: (res) {resolve(res.data)},fail: reject})})
} 使用 // 1. 导入
import { homeDataList } from ../../service/request/home/indexPage({data: {dataList: []},async onLoad() {const params {url: https://www.baidu.com/,data: {age: 18}}// 2. 直接使用homeDataList(params).then(res {console.log(res, res);}).catch(err {console.log(err, err);})// 3. 使用async/awaitconst dataList await homeDataList(params)console.log(dataList);}
}) 封装成类 封装
class request {// 设置baseUrlconstructor(baseUrl) {this.baseUrl baseUrl}// 封装 request 方法request(option) {const { url } optionreturn new Promise((resolve, reject) {wx.request({...option,// 拼接地址url: this.baseUrl url,success: (res) {resolve(res.data)},fail: reject})})}// 封装 get 方法get(option) {return this.request({ ...option, method: GET })}// 封装 post 方法post(option) {return this.request({ ...option, method: POST })}
}// 可创建多个实例请求不同的地址
export const starRequest new request(https://www.baidu.com) 使用 04 - 网络请求域名配置 每个微信小程序需要事先设置通讯域名小程序只可以跟指定的域名进行网络通信 小程序登录后台 – 开发管理 – 开发设置 – 服务器域名 配置时需要注意 :
域名只支持 https wx.request、wx.uploadFile、wx.downloadFile 和 wss (wx.connectSocket) 协议域名不能使用 IP 地址 小程序的局域网 IP 除外 或 localhost端口 配置端口 如 https://myserver.com:8080但是配置后只能向 https://myserver.com:8080 发起请求。如果向https://myserver.com、https://myserver.com:9091 等 URL 请求则会失败不配置端口 如 https://myserver.com那么请求的 URL 中也不能包含端口甚至是默认的 443 端口也不可以。如果向 https://myserver.com:443 请求则会失败域名必须经过 ICP 备案不支持配置父域名使用子域名
2. 展示弹窗效果
01 - showToast showToast 和 showLoading 只能同时显示一个 效果 代码
wx.showToast({// 提示内容title: title,// 图标 none error loading successicon: success,// 自定义图标 自定义图标的本地路径image 的优先级高于 iconimage: /assets/images/tabbar/cart_active.png,// 持续时间duration: 2000,// 是否显示透明蒙层显示期间不能进行交互mask: true,// 成功回调success: (res) {console.log(展示成功, res);},// 失败回调fail: (err) {console.log(展示失败, err);},// 接口调用结束的回调函数调用成功、失败都会执行complete: (data) {console.log(展示, data);}
})
02 - showLoading 和 showToast icon为loadind展示的效果相同 但是可以手动控制关闭弹窗的时间 效果 代码
wx.showLoading({// 提示内容title: 加载中,// 是否显示透明蒙层显示期间不能进行交互mask: true,// 成功回调success: (res) {console.log(展示成功, res);},// 失败回调fail: (err) {console.log(展示失败, err);},// 接口调用结束的回调函数调用成功、失败都会执行complete: (data) {console.log(展示, data);}
})// 两秒后关闭弹窗 可在请求数据完成后再调用该方法
setTimeout(function () {wx.hideLoading()
}, 2000)
03 - showModal 效果 代码
wx.showModal({// 提示的标题title: 你有钱吗,// 提示的内容content: 我有,// 是否显示取消按钮showCancel: true,// 取消按钮的文字最多 4 个字符cancelText: 骗你哒,// 取消按钮的文字颜色必须是 16 进制格式的颜色字符串cancelColor: #f0f,// 确认按钮的文字最多 4 个字符confirmText: 真的啦,// 确认按钮的文字颜色必须是 16 进制格式的颜色字符串confirmColor: #00f,// 是否显示输入框// editable: true,// 显示输入框时的提示文本// placeholderText: 我是提示内容,// 成功回调success: (res) {/*** content editable 为 true 时用户输入的文本* confirm 为 true 时表示用户点击了确定按钮* cancel 为 true 时表示用户点击了取消*/if (res.confirm) {console.log(用户点击确定)} else if (res.cancel) {console.log(用户点击取消)}},// 失败回调fail: (err) {console.log(展示失败, err);},// 接口调用结束的回调函数调用成功、失败都会执行complete: (data) {console.log(展示, data);}
})
04 - showActionSheet 效果 代码
wx.showActionSheet({// 警示文案alertText: 你有钱吗,// 按钮的文字数组数组长度最大为 6itemList: [吃饭, 喝水, 打豆豆, 睡觉],// 按钮的文字颜色itemColor: #0f0,// 成功回调success: (res) {/*** tapIndex 用户点击的按钮序号从上到下的顺序从0开始*/console.log(展示成功, res, res.tapIndex);},// 失败回调监听取消fail: (err) {console.log(展示失败, err);},// 接口调用结束的回调函数调用成功、失败都会执行complete: (data) {console.log(展示, data);}
})
3. 分享功能 onShareAppMessage 分享是小程序扩散的一种重要方式小程序中有两种分享方式通过 onShareAppMessage 此事件处理函数需要 return 一个 Object用于自定义转发内容 方式一 点击右上角的菜单按钮之后点击转发 直接配置 onShareAppMessage 方法即可 Page({onShareAppMessage() {return {title: 我是标题, // 分享后显示的标题path: /pages/logs/logs, // 分享后打开的路径别人打开的页面的路径imageUrl: /assets/images/tabbar/cart_active.png // 分享后显示的图片}}
})
方式二 监听用户点击页面内转发按钮 button 组件 open-typeshare 页面设置后再配置 onShareAppMessage 方法即可 // wxml
viewbutton open-typeshare分享/button
/view// js
Page({onShareAppMessage() {return {title: 我是标题, // 分享后显示的标题path: /pages/logs/logs, // 分享后打开的路径别人打开的页面的路径imageUrl: /assets/images/tabbar/cart_active.png // 分享后显示的图片}}
})
4. 获取设备信息 wx.getSystemInfo 获取当前设备的信息用于手机信息或者进行一些适配工作 wx.getSystemInfo(Object object) Page({onShow() {wx.getSystemInfo({success: (res) {console.log(success, res);},fail: (err) {console.log(fail, err);},complete: (res) {console.log(complete, res);},})}
}) 5. 获取位置信息 wx.getLocation 对于用户的关键信息比如获取用户的位置信息需要获取用户的授权后才能获得 01 - 授权 在app.json中进行配置 地址 : 全局配置 | 微信开放文档 {pages: [pages/index/index],// 配置权限permission: {// 配置位置权限scope.userLocation: {// 弹出框中显示的内容desc: 我需要你的位置信息马上给我}},window: {},tabBar: {},style: v2,sitemapLocation: sitemap.json
}
02 - 获取
Page({onShow() {wx.getLocation({type: wgs84, // wgs84 返回 gps 坐标altitude: false,// 传入 true 会返回高度信息但是会减慢接口返回速度isHighAccuracy: true, // 开启高精度定位highAccuracyExpireTime: 5000,// 高精度定位超时时间(ms)指定时间内返回最高精度该值3000ms以上高精度定位才有效果// 接口调用成功的回调函数success: (res) {/*** latitude 纬度范围为 -90~90负数表示南纬* longitude 经度范围为 -180~180负数表示西经* speed 速度单位 m/s看当前设备是否在移动* accuracy 位置的精确度反应与真实位置之间的接近程度可以理解成10即与真实位置相差10m越小越精确* altitude 高度单位 m* verticalAccuracy 垂直精度单位 mAndroid 无法获取返回 0* horizontalAccuracy 水平精度单位 m*/console.log(success, res);},// 接口调用失败的回调函数fail: (err) {console.log(fail, err);},// 接口调用结束的回调函数调用成功、失败都会执行complete: (res) {console.log(complete, res);},})}
})
6. Storage存储
01 - 同步 存储的代码执行完后才会继续往后执行 也就是说下一行代码就能获取到存储的值 Page({onShow() {// 存wx.setStorageSync(name, coder)wx.setStorageSync(age, 18)wx.setStorageSync(array, [1, 2, 3, 4])wx.setStorageSync(Object, { friends: 小明 })// 取console.log(wx.getStorageSync(name)); // coder// 删wx.removeStorageSync(name)// 清空wx.clearStorageSync()}
})
02 - 异步 不影响其他代码执行 存储后不能立马获取到值 Page({onShow() {// 存wx.setStorage({key: name,data: coder,encrypt: true, // 2.21.3 若开启加密存储setStorage 和 getStorage 需要同时声明 encrypt 的值为 truesuccess: ({ errMsg }) {console.log(errMsg); // setStorage:ok}})// 取wx.getStorage({key: name,encrypt: true, // 2.21.3 若开启加密存储setStorage 和 getStorage 需要同时声明 encrypt 的值为 truesuccess: ({ errMsg, data }) {console.log(errMsg, data); // getStorage:ok coder}});// 删wx.removeStorage({key: name,success: ({ errMsg }) {console.log(errMsg); // removeStorage:ok}})// 清空wx.clearStorage({success: ({ errMsg }) {console.log(errMsg); // clearStorage:ok}})}
})
十一、页面跳转
1. 通过wx的API跳转 00 - switchTab - 跳转到 tabBar 页面 跳转到 tabBar 页面 并关闭其他所有非 tabBar 页面使用 navigateBack 无法退回 // 跳转页面
wx.switchTab({url: /pages/text/text,success: (res) { console.log(success, res); },fail: (err) { console.log(fail, err); },complete: (res) { console.log(complete, res); },
})
01 - navigateTo - 普通页面跳转 保留当前页面跳转到应用内的某个页面 但是不能跳到 tabbar 页面 // index页面
Page({// 监听方法handleClick() {const name coderconst age 19// 跳转页面wx.navigateTo({// 地址 ?后面为携带的参数url: /pages/jump1/jump1?name${name}age${age},})}
})// ---------------------------------------------------------------------------// pages/jump1/jump1.js
Page({// 接受从index页面跳转过来时接受到的参数onLoad(option) {console.log(option); // {name: coder, age: 18}}
})
02 - navigateBack - 页面返回 wx.navigateBack(Object object) 关闭当前页面返回上一页面或多级页面 Page({onShow() {setTimeout(() {// 页面返回wx.navigateBack({// 默认返回上一页可以设定delta: 1})}, 3000);}
})
03 - 页面跳转 - 数据传递一 在界面跳转过程中需要相互传递一些数据 首页 详情页 使用URL中的query字段 // index
Page({handleClick() {const name coderconst age 19// 跳转页面wx.navigateTo({url: /pages/jump1/jump1?name${name}age${age},})}
}) 详情页 首页 在详情页内部拿到首页的页面对象直接修改数据 // jump1页面
Page({onShow() {setTimeout(() {// 页面返回wx.navigateBack({// 默认返回上一页可以设定delta: 1})}, 3000);},// 拿到传递过来的数据onLoad(option) {console.log(option);},/*** 写在这里的理由 : 用户可能点击顶部状态栏中的返回键写在这不管怎么返回都会触发*/// 页面被注销时调用onUnload() {// 1. 获取到已经存在的所有页面const pages getCurrentPages()// 2. 拿到上一个页面的实例 当前页面为最后一个所以上一个页面是减2const prePage pages[pages.length - 2]// 3. 直接设置值prePage.setData({ message: ccc })}
})
04 - 页面跳转 - 数据传递二 在小程序基础库 2.7.3 开始支持events参数也可以用于数据的传递 首页 详情页 使用URL中的query字段进行传递定义events对象 // index页面
Page({// 监听方法handleClick() {const name coderconst age 19// 跳转页面wx.navigateTo({url: /pages/jump1/jump1?name${name}age${age},// 使用该参数events: {// 设置方法名 在子组件中调用该方法传递数据过来acceptData(data) {console.log(acceptData, data); // {name:coder}},// 设置方法名acceptOtherData(data) {console.log(acceptOtherData, data); // {age:18}}}})}
}) 详情页 首页 使用eventChanner传递数据到上一个页面 // jump1页面
Page({onShow() {setTimeout(() {// 页面返回wx.navigateBack({// 默认返回上一页可以设定delta: 1})}, 3000);},// 拿到传递过来的数据onLoad(option) {console.log(option);},/*** 写在这里的理由 : 用户可能点击顶部状态栏中的返回键写在这不管怎么返回都会触发*/// 页面被注销时调用onUnload() {// 1. 拿到eventChanner渠道const eventChanner this.getOpenerEventChannel()// 2. 通过渠道拿到回调函数并且传递数据给上一个页面eventChanner.emit(acceptData, {name: coder})eventChanner.emit(acceptOtherData, {age: 18})}
})
2. 通过navigator组件 navigator组件主要就是用于界面的跳转的也可以跳转到其他小程序中 01 - 跳转到 tabBar 页面
navigator open-typeswitchTab url/pages/logs/logs跳转/navigator
02 - 跳转到 普通 页面
navigator url/pages/jump1/jump1?name123跳转/navigator
03 - 返回 上一个 页面
navigator open-typenavigateBack delta1跳转/navigator
十二、小程序登录解析
1. 概念
01 - openid openid : 当 在小程序 用微信功能登录时每个微信都具备唯一标识openid 可把 openid 保存到数据库中即使用户更换了手机也能通过 openid 识别为同一用户 02 - unionid unionid : 在微信的不同产品之间可用来识别是否为同一用户 小程序的 openid 和 公众号的 openid可能是不一样的但是unionid一样 03 - 用户身份多平台共享 再开一个页面或窗口 进行账号绑定 || 手机号绑定 openid - unionid - 手机号 就建立了联系 2. 登录流程 3. 代码 登录操作 可以写到 app.js 的 onLaunch 中 也可以写到 页面.js 的 onLoad 中 Page({/*** onLoad登录操作*/onLoad() {// 1. 判断token是否有值const token wx.getStorageSync(token) || // 2. 判断token是否过期// ......// 有值 且 没过期if (token 没过期) {// 做其他操作} else {// 3. 获取codethis.requestCode()}},// 登录获取coderequestCode() {wx.login({success: ({ code }) {// 4. 将code发给后端this.requestBack(code)},})},// 将code发给后端requestBack(code) {console.log(code);wx.request({url: https://www.baidu.com,data: { code },method: POST,success: (res) {// 5. 拿到身份标识( 自定义登录态 )可能不会返回openid, unionid看后端const { openid, unionid, token } res.data// 6. 把 自定义登录态 存入storagewx.setStorageSync(token, token)},})}
})
十三、代码上传到Gitee git操作都是大同小异详细的可以看我之前写的git文章 网址 : 版本控制工具 之 Git_玄鱼殇的博客 1. 创建远程仓库 2. 配置远程仓库 01 - 本地点击版本管理 02 - 添加远程仓库 03 - 设置用户名和邮箱 04 - 设置网络和认证 3. 推送代码到远程仓库
01 - 首次推送 02 - 修改后推送 推送到本地仓库 拉取远程仓库代码 推送到远程仓库 文章转载自: http://www.morning.c7497.cn.gov.cn.c7497.cn http://www.morning.bzlsf.cn.gov.cn.bzlsf.cn http://www.morning.bpmfl.cn.gov.cn.bpmfl.cn http://www.morning.zkqjz.cn.gov.cn.zkqjz.cn http://www.morning.sbwr.cn.gov.cn.sbwr.cn http://www.morning.smzr.cn.gov.cn.smzr.cn http://www.morning.dtfgr.cn.gov.cn.dtfgr.cn http://www.morning.ltxgk.cn.gov.cn.ltxgk.cn http://www.morning.cxsdl.cn.gov.cn.cxsdl.cn http://www.morning.nrgdc.cn.gov.cn.nrgdc.cn http://www.morning.jgmdr.cn.gov.cn.jgmdr.cn http://www.morning.qlrwf.cn.gov.cn.qlrwf.cn http://www.morning.thbkc.cn.gov.cn.thbkc.cn http://www.morning.hrjrt.cn.gov.cn.hrjrt.cn http://www.morning.knngw.cn.gov.cn.knngw.cn http://www.morning.tfcwj.cn.gov.cn.tfcwj.cn http://www.morning.thzwj.cn.gov.cn.thzwj.cn http://www.morning.wnjrf.cn.gov.cn.wnjrf.cn http://www.morning.ngcbd.cn.gov.cn.ngcbd.cn http://www.morning.kjrp.cn.gov.cn.kjrp.cn http://www.morning.tkgjl.cn.gov.cn.tkgjl.cn http://www.morning.xmbhc.cn.gov.cn.xmbhc.cn http://www.morning.dpwcl.cn.gov.cn.dpwcl.cn http://www.morning.wgcng.cn.gov.cn.wgcng.cn http://www.morning.zrlwl.cn.gov.cn.zrlwl.cn http://www.morning.rqnml.cn.gov.cn.rqnml.cn http://www.morning.cnlmp.cn.gov.cn.cnlmp.cn http://www.morning.mtdfn.cn.gov.cn.mtdfn.cn http://www.morning.qkcyk.cn.gov.cn.qkcyk.cn http://www.morning.rshijie.com.gov.cn.rshijie.com http://www.morning.rdng.cn.gov.cn.rdng.cn http://www.morning.kcypc.cn.gov.cn.kcypc.cn http://www.morning.xkyfq.cn.gov.cn.xkyfq.cn http://www.morning.rpsjh.cn.gov.cn.rpsjh.cn http://www.morning.hwbf.cn.gov.cn.hwbf.cn http://www.morning.qlrtd.cn.gov.cn.qlrtd.cn http://www.morning.hlfnh.cn.gov.cn.hlfnh.cn http://www.morning.hqwxm.cn.gov.cn.hqwxm.cn http://www.morning.ryxdr.cn.gov.cn.ryxdr.cn http://www.morning.nzmqn.cn.gov.cn.nzmqn.cn http://www.morning.huayaosteel.cn.gov.cn.huayaosteel.cn http://www.morning.seoqun.com.gov.cn.seoqun.com http://www.morning.ftntr.cn.gov.cn.ftntr.cn http://www.morning.ntlxg.cn.gov.cn.ntlxg.cn http://www.morning.rfhmb.cn.gov.cn.rfhmb.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.hxhrg.cn.gov.cn.hxhrg.cn http://www.morning.wkpfm.cn.gov.cn.wkpfm.cn http://www.morning.mxnhq.cn.gov.cn.mxnhq.cn http://www.morning.fdrwk.cn.gov.cn.fdrwk.cn http://www.morning.pjzcp.cn.gov.cn.pjzcp.cn http://www.morning.qtltg.cn.gov.cn.qtltg.cn http://www.morning.dbbcq.cn.gov.cn.dbbcq.cn http://www.morning.hnkkm.cn.gov.cn.hnkkm.cn http://www.morning.qfrmy.cn.gov.cn.qfrmy.cn http://www.morning.qmsbr.cn.gov.cn.qmsbr.cn http://www.morning.nwllb.cn.gov.cn.nwllb.cn http://www.morning.xphcg.cn.gov.cn.xphcg.cn http://www.morning.mhcys.cn.gov.cn.mhcys.cn http://www.morning.c7497.cn.gov.cn.c7497.cn http://www.morning.gtmdq.cn.gov.cn.gtmdq.cn http://www.morning.zqxhn.cn.gov.cn.zqxhn.cn http://www.morning.phjny.cn.gov.cn.phjny.cn http://www.morning.rcfwr.cn.gov.cn.rcfwr.cn http://www.morning.qbkw.cn.gov.cn.qbkw.cn http://www.morning.qlbmc.cn.gov.cn.qlbmc.cn http://www.morning.qttg.cn.gov.cn.qttg.cn http://www.morning.txlnd.cn.gov.cn.txlnd.cn http://www.morning.dmwbs.cn.gov.cn.dmwbs.cn http://www.morning.yksf.cn.gov.cn.yksf.cn http://www.morning.dxpqd.cn.gov.cn.dxpqd.cn http://www.morning.fwdln.cn.gov.cn.fwdln.cn http://www.morning.bttph.cn.gov.cn.bttph.cn http://www.morning.wfbnp.cn.gov.cn.wfbnp.cn http://www.morning.ywpcs.cn.gov.cn.ywpcs.cn http://www.morning.fwblh.cn.gov.cn.fwblh.cn http://www.morning.mzzqs.cn.gov.cn.mzzqs.cn http://www.morning.kjmws.cn.gov.cn.kjmws.cn http://www.morning.gychx.cn.gov.cn.gychx.cn http://www.morning.pumali.com.gov.cn.pumali.com