部份内容来自微信小程序官方文档,主要是对微信小程序一个系统的认识和总结css
2) 介绍小程序代码构成 app.json 、 app.js 和 app.wxss , 2-1) 介绍小程序页面构成 page.js 、 page.wxml 、 page.json 、 page.wxss 、page.wxs,3) 为 project.config.json 项目配置信息,4) 为 sitemap.json 小程序索引配置html
小程序的主要开发语言是 JavaScript。前端
网页开发渲染线程和脚本线程是互斥的,长时间的脚本运行可能会致使页面失去响应,而在小程序中,两者是分开的,分别运行在不一样的线程中。node
网页开发者可使用到各类浏览器暴露出来的 DOM API,进行 DOM 选中和操做。而如上文所述,小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并无一个完整浏览器对象,于是缺乏相关的DOM API和BOM API。这一区别致使了前端开发很是熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是没法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,因此一些 NPM 的包在小程序中也是没法运行的。es6
网页开发者须要面对的环境是各式各样的浏览器,PC 端须要面对 IE、Chrome、QQ浏览器等,在移动端须要面对Safari、Chrome以及 iOS、Android 系统中的各式 WebView 。而小程序开发过程当中须要面对的是两大操做系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具,小程序中三大运行环境也是有所区别的web
运行环境正则表达式 |
逻辑层编程 |
渲染层json |
iOScanvas |
JavaScriptCore |
WKWebView |
安卓 |
V8 |
chromium定制内核 |
小程序开发者工具 |
NWJS |
Chrome WebView |
小程序包含一个描述总体程序的app和多个描述各自页面的page。
一个小程序主体部分由三个文件组成,必须放在项目的根目录,以下:
文件 | 必需 | 做用 |
---|---|---|
app.js | 是 | 小程序逻辑 |
app.json | 是 | 小程序公共配置 |
app.wxss | 否 | 小程序公共样式表(注1) |
注1:
做用于全局的样式表,同CSS用法同样,若在任意Page页写了同名Class则覆盖此处的样式。
行内样式 > Page.css > app.css
app.json是当前小程序的全局配置,包括了小程序的全部页面路径、界面表现、网络超时时间、底部 tab 等
// 小程序配置app.json
// JSON 配置 // JSON 是一种数据格式,并非编程语言,在小程序中,JSON扮演的静态配置的角色 /* JSON 语法 注意事项: JSON文件都是被包裹在一个大括号中 {},经过key-value的方式来表达数据。JSON的Key必须包裹在一个双引号中,在实践中,编写 JSON 的时候,忘了给 Key 值加双引号或者是把双引号写成单引号是常见错误。 JSON的值只能是如下几种数据格式,其余任何格式都会触发报错,例如 JavaScript 中的 undefined。 数字,包含浮点数和整数 字符串,须要包裹在双引号中 Bool值,true 或者 false 数组,须要包裹在方括号中 [] 对象,须要包裹在大括号中 {} Null 还须要注意的是 JSON 文件中没法使用注释,试图添加注释将会引起报错。 */ { //pages用于指定小程序由哪些页面组成,每一项都对应一个页面路径(文件名) 信息。文件名不须要写文件后缀,框架会自动去寻找对于位置的 .json, .js, .wxml, .wxss 四个文件进行处理。数组的第一项表明小程序的初始页面(首页)。小程序中新增/减小页面,都须要对 pages 数组进行修改。 "pages": [ "pages/index/index", "pages/logs/logs" ], //window对象。设置小程序全局的状态栏、导航条、标题、窗口背景色。 "window": { //导航栏背景颜色,十六进制颜色 "navigationBarBackgroundColor": "#ffffff", //导航栏标题颜色 仅包含black (黑色)/ white(白色) "navigationBarTextStyle": "black", //导航栏标题文字内容 "navigationBarTitleText": "听风吟", //导航栏样式 仅包含default(默认)/custom(清空以前的全部样式设置) "navigationStyle": "default", //窗口的背景色 (未发现明显改变) "backgroundColor": "#eeeeee", //下拉 loading 的样式 仅支持 dark(刷新时改成三个 ·) / light(无特殊属性)需开启enablePullDownRefresh下拉刷新 "backgroundTextStyle": "light", //开启/关闭全局下拉刷新 仅true/false "enablePullDownRefresh": true, //页面上拉触底事件触发时距页面底部距离,单位为 px。 "onReachBottomDistance": 30, // 响应显示区域变化 //屏幕旋转设置,支持 auto (自动)/ portrait(竖屏) / landscape (2.5.0支持固定横屏显示) "pageOrientation": "portrait", // iPad 上启用屏幕旋转支持 "resizable": true }, //tabBar若是小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏能够切换页面),能够经过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面(指定页面栏目最少2个最多5个并配置样式) "tabBar": { //tab 上的文字默认颜色,仅支持十六进制颜色 "color": "#ffffff", //tab 上的文字选中时的颜色,仅支持十六进制颜色 "selectedColor": "#00ffff", //tab 的背景色,仅支持十六进制颜色 "backgroundColor": "#000000", //tabbar 上边框的颜色, 仅支持 black / white "borderStyle": "black", //tab的列表项接受一个数组,配置最少 2 个、最多 5 个 tab "list": [ { //页面路径,必须在 pages 中先定义 "pagePath": "pages/index/index", //tab 上按钮文字 "text": "首页", //图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon。 "iconPath": "../images/xxx.ico", //选中时的图片路径,限制同上 "selectedIconPath": "../images/xxx2.ico" }, { "pagePath": "pages/logs/logs", "text": "日志", "iconPath": "../images/xxx.ico", "selectedIconPath": "../images/xxx2.ico" } ], // tabBar 的位置,仅支持 bottom / top "position":"bottom", //自定义 tabBar 用自定义组件的方式编写便可,该自定义组件彻底接管 tabBar 的渲染。另外,自定义组件新增 getTabBar 接口,可获取当前页面下的自定义 tabBar 组件实例 //添加自定义目录custom-tab-bar "custom":true }, //networkTimeout各种网络请求的超时时间,单位均为毫秒。 //默认均为60s "networkTimeout": { //wx.request 的超时时间,单位:毫秒。 "request": 10000, //wx.downloadFile 的超时时间,单位:毫秒。 "downloadFile": 10000, //wx.connectSocket 的超时时间,单位:毫秒。 "connectSocket": 10000, //wx.uploadFile 的超时时间,单位:毫秒。 "uploadFile": 10000 }, //debug在开发者工具中开启 debug 模式,在开发者工具的控制台面板,调试信息以 info 的形式给出,其信息有 Page 的注册,页面路由,数据更新,事件触发等。 "debug": false, //要在插件中调用插件功能页,须要先激活插件全部者小程序的功能页 "functionalPages": { "independent": true }, //subpackages申明项目分包结构 /**某些状况下,开发者须要将小程序划分红不一样的子包,在构建时打包成不一样的分包,用户在使用时按需进行加载。 在构建小程序分包项目时,构建会输出一个或多个分包。每一个使用分包小程序一定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些全部分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展现。 目前小程序分包大小有如下限制: 整个小程序全部分包大小不超过 8M 单个分包/主包大小不能超过 2M 对小程序进行分包,能够优化小程序首次启动的下载时间,以及在多团队共同开发时能够更好的解耦协做。*/ /** 打包原则 声明 subpackages 后,将按 subpackages 配置路径进行打包,subpackages 配置路径外的目录将被打包到 app(主包) 中 app(主包)也能够有本身的 pages(即最外层的 pages 字段) subpackage 的根目录不能是另一个 subpackage 内的子目录 tabBar 页面必须在 app(主包)内 */ /* 引用原则 packageA 没法 require packageB JS 文件,但能够 require app、本身 package 内的 JS 文件 packageA 没法 import packageB 的 template,但能够 require app、本身 package 内的 template packageA 没法使用 packageB 的资源,但可使用 app、本身 package 内的资源*/ /* 低版本兼容 由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另一份是整包的兼容代码。 新客户端用分包,老客户端仍是用的整包,完整包会把各个 subpackage 里面的路径放到 pages 中。 */ "subpackages": [ { //分包跟目录 "root": "packageA", //分包别名,分包预加载时可用 "name": "pack1", //分包页面路径,相对于分包跟目录,使用同pages同样 "pages": [ "pages/test/test" ], //是否为独立分包 /* 独立分包 微信客户端 6.7.2,基础库 2.3.0 及以上版本开始支持。开发者工具请使用 1.02.1808300 及以上版本,可点此下载。 独立分包是小程序中一种特殊类型的分包,能够独立于主包和其余分包运行。从独立分包中页面进入小程序时,不须要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。 开发者能够按需将某些具备必定功能独立性的页面配置到独立分包中。当小程序从普通的分包页面启动时,须要首先下载主包;而独立分包不依赖主包便可运行,能够很大程度上提高分包页面的启动速度。 一个小程序中能够有多个独立分包 */ /* 限制 独立分包属于分包的一种。普通分包的全部限制都对独立分包有效。独立分包中插件、自定义组件的处理方式同普通分包。 此外,使用独立分包时要注意: 一、独立分包中不能依赖主包和其余分包中的内容,包括js文件、template、wxss、自定义组件、插件等。主包中的app.wxss对独立分包无效,应避免在独立分包页面中使用 app.wxss 中的样式; 二、App 只能在主包内定义,独立分包中不能定义 App,会形成没法预期的行为; 三、独立分包中暂时不支持使用插件 */ /* 关于 getApp() 与普通分包不一样,独立分包运行时,App 并不必定被注册,所以 getApp() 也不必定能够得到 App 对象: 当用户从独立分包页面启动小程序时,主包不存在,App也不存在,此时调用 getApp() 获取到的是 undefined。 当用户进入普通分包或主包内页面时,主包才会被下载,App 才会被注册。 当用户是从普通分包或主包内页面跳转到独立分包页面时,主包已经存在,此时调用 getApp() 能够获取到真正的 App。 因为这一限制,开发者没法经过 App 对象实现独立分包和小程序其余部分的全局变量共享。 为了在独立分包中知足这一需求,基础库 2.2.4 版本开始 getApp支持 [allowDefault ]参数,在 App 未定义时返回一个默认实现。当主包加载,App 被注册时,默认实现中定义的属性会被覆盖合并到真正的 App 中 定义方法: const app = getApp({allowDefault: true}) */ /* 关于 App 生命周期 当从独立分包启动小程序时,主包中 App 的 onLaunch 和首次 onShow 会在从独立分包页面首次进入主包或其余普通分包页面时调用。 因为独立分包中没法定义 App,小程序生命周期的监听可使用 wx.onAppShow,wx.onAppHide 完成。App 上的其余事件可使用 wx.onError,wx.onPageNotFound 监听 */ "independent":false }, { "root": "packageB", "name": "pack2", "pages": [ "pages/demo/demo" ], "independent": false } ], //preloadRule分包预下载 /* 进入小程序某个页面时,由框架自动预下载可能须要的分包,提高进入后续分包页面时的启动速度。对于独立分包,也能够预下载主包 预下载分包行为在进入某个页面时触发,经过在 app.json 增长 preloadRule 配置来控制。 */ "preloadRule": { //页面路径 "pages/index/index": { //预下载配置 //在指定网络下预下载,可选值为:all: 不限网络 wifi: 仅wifi下预下载 "network": "all", //进入页面后预下载分包的 root 或 name。__APP__ 表示主包 "packages": [ "packageA" ] }, "pages/logs/logs": { "network": "wifi", "packages": [ "__APP__", "packageA", "packageB" ] } }, //多线程workers /* 一些异步处理的任务,能够放置于 Worker 中运行,待运行结束后,再把结果返回到小程序主线程。Worker 运行于一个单独的全局上下文与线程中,不能直接调用主线程的方法。 Worker 与主线程之间的数据传输,双方使用 Worker.postMessage() 来发送数据,Worker.onMessage() 来接收数据,传输的数据并非直接共享,而是被复制的 */ "workers": "workers", /*在app.js中建立worker实例,只能建立一个 Worker wx.createWorker(string scriptPath) 监听主线程/Worker 线程向当前线程发送的消息的事件 worker.onMessage(function (res) {console.log(res)}) 向主线程/Worker 线程发送的消息 worker.postMessage({msg: 'hello worker'}) 须要发送的消息,必须是一个可序列化的 JavaScript key-value 形式的对象(JSON格式) Worker.terminate() 结束当前 Worker 线程。仅限在主线程 worker 对象上调用 */ //requiredBackgroundModes申明须要后台运行的能力,类型为数组。目前支持如下项目:audio: 后台音乐播放 location: 后台定位 //在此处申明了后台运行的接口,开发版和体验版上能够直接生效,正式版还需经过审核。 "requiredBackgroundModes": [ "audio", "location" ], // 使用插件 /* plugins 定义段中能够包含多个插件声明,每一个插件声明以一个使用者自定义的插件引用名做为标识,并指明插件的 appid 和须要使用的版本号。其中,引用名(如上例中的 myPlugin)由使用者自定义,无需和插件开发者保持一致或与开发者协调。在后续的插件使用中,该引用名将被用于表示该插件 */ "plugins": { "myPlugin": { "version": "1.0.0", "provider": "wxidxxxxxxxxxxxxxxxx" } }, // 当小程序须要使用 wx.navigateToMiniProgram 接口跳转到其余小程序时,须要先在配置文件中声明须要跳转的小程序 appId 列表,最多容许填写 10 个。 "navigateToMiniProgramAppIdList":[ "wxcbe110fu2xaxedfu", "wxfb1ff0f3u0abe913", "wxc1b5d81exdad1efe", "wxu8caa30cd32c1fb9", "wx52axxb89fx3xe23c" ], // usingComponents // 在此处声明的自定义组件视为全局自定义组件,在小程序内的页面或自定义组件中能够直接使用而无需再声明 // 受权permission // 部分接口须要通过用户受权赞成才能调用。咱们把这些接口按使用范围分红多个 scope ,用户选择对 scope 来进行受权,当受权给一个 scope 以后,其对应的全部接口均可以直接使用。 // 获取用户受权设置 // wx.getSetting // 打开设置界面 // wx.openSetting // 提早发起受权请求 // wx.authorize /* scope 列表 scope.userInfo wx.getUserInfo 用户信息 scope.userLocation wx.getLocation, wx.chooseLocation 地理位置 scope.userLocationBackground wx.userLocationBackground 后台定位 scope.address wx.chooseAddress 通信地址 scope.invoiceTitle wx.chooseInvoiceTitle 发票抬头 scope.invoice wx.chooseInvoice 获取发票 scope.werun wx.getWeRunData 微信运动步数 scope.record wx.startRecord 录音功能 scope.writePhotosAlbum wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum 保存到相册 scope.camera camera 组件 摄像头 */ "permission": { "scope.userLocation": { "desc": "你的位置信息将用于小程序位置接口的效果展现" // 高速公路行驶持续后台定位 } }, // 配置微信小程序内索引 /* sitemap.json 用于配置小程序及其页面是否容许被微信索引,文件内容为一个 JSON 对象,若是没有 sitemap.json ,则默认为全部页面都容许被索引; */ "sitemapLocation": "sitemap.json", // 微信客户端 7.0 开始,UI 界面进行了大改版。小程序也进行了基础组件的样式升级。app.json 中配置 "style": "v2"可代表启用新版的组件样式。本次改动涉及的组件有 button icon radio checkbox switch slider。 "style": "v2" }
每一个小程序都须要在app.js中调用 App方法注册小程序示例,绑定生命周期回调函数、错误监听和页面不存在监听函数等
//注册小程序app.js /** * * App() 必须在 app.js 中调用,必须调用且只能调用一次 * * 整个小程序只有一个 App 实例,是所有页面共享的。开发者能够经过 getApp 方法获取到全局惟一的 App 示例,获取App上的数据或调用开发者注册在 App 上的函数。 */ App({ // 生命周期回调——监听小程序初始化。 /** * 小程序初始化完成时触发,全局只触发一次。回调参数也可使用 wx.getLaunchOptionsSync 获取 * 返回参数 * Object 属性 类型 说明 path string 启动小程序的路径 scene number 启动小程序的场景值(具体场景值参考:场景值列表) query Object 启动小程序的 query 参数 shareTicket string shareTicket,获取转发信息(详见:注1) referrerInfo Object 来源信息。从另外一个小程序、公众号或 App 进入小程序时返回。不然返回 {}。(详见:注2) */ /** * 注1 * 获取更多转发信息 * 一般开发者但愿转发出去的小程序被二次打开的时候可以获取到一些信息,例如群的标识。如今经过调用 wx.showShareMenu 而且设置 withShareTicket 为 true ,当用户将小程序转发到任一群聊以后,此转发卡片在群聊中被其余用户打开时,能够在 App.onLaunch 或 App.onShow 获取到一个 shareTicket。经过调用 wx.getShareInfo 接口传入此 shareTicket 能够获取到转发信息 * * 说人话系列: * 便可以经过设置转发withShareTicket为true在另外一个页面中经过shareTicket获取wx.getShareInfo 接口回调以取得更多转发信息 * 如:A用户在将Test小程序转发至C微信群,此时B用户经过点击C微信群中的小程序卡片进入小程序,此时开发者可经过App.onLaunch或wx.getLaunchOptionsSync获取shareTicket, * 而后将shareTicket传入wx.getShareInfo获取回调,回调中的敏感数据为加密的需后台校验解密开放数据(解密详见:服务端获取开放数据) */ /** * 注2 * referrerInfo 结构 属性 类型 说明 appId string 来源小程序、公众号或 App 的 appId extraData Object 来源小程序传过来的数据,scene=1037或1038时支持 注意: 部分版本在无referrerInfo的时候会返回 undefined,建议使用 options.referrerInfo && options.referrerInfo.appId 进行判断 */ onLaunch: function(options) { //小程序初始化完后,打印回调参数,同wx.getLaunchOptionsSync函数同样 console.log(options) // 展现本地存储能力 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) // 登陆 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId } }) // 获取用户信息 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经受权,能够直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { // 能够将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 因为 getUserInfo 是网络请求,可能会在 Page.onLoad 以后才返回 // 因此此处加入 callback 以防止这种状况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, // 生命周期回调——监听小程序启动或切前台。 /** * 小程序启动,或从后台进入前台显示时触发。也可使用 wx.onAppShow 绑定监听 * 回调参数同onLaunch或wx.getLaunchOptionsSync同样,区别在于 onLaunch 全局只生效一次,而onShow每次进入小程序前台或启动都会触发 */ onShow: function(options) { console.log("Look Me") }, // 生命周期回调——监听小程序切后台 /** * 小程序从前台进入后台时触发。也可使用 wx.onAppHide 绑定监听 */ onHide: function() { console.log("awsl") }, // 错误监听函数。 /** * 小程序发生脚本错误或 API 调用报错时触发。也可使用 wx.onError 绑定监听 */ onError(msg) { console.log(msg) }, // 页面不存在监听函数 /** * 小程序要打开的页面不存在时触发。也可使用 wx.onPageNotFound 绑定监听 * 返回参数 * 属性 类型 说明 path string 不存在页面的路径 query Object 打开不存在页面的 query 参数 isEntryPage boolean 是否本次启动的首个页面(例如从分享等入口进来,首个页面是开发者配置的分享页面) 注意: 开发者能够在回调中进行页面重定向,但必须在回调中同步处理,异步处理(例如 setTimeout 异步执行)无效。 若开发者没有调用 wx.onPageNotFound 绑定监听,也没有声明 App.onPageNotFound,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面。 若是回调中又重定向到另外一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,而且再也不第二次回调 (一般能够在此处配置本身的不存在页面) */ onPageNotFound(res) { wx.redirectTo({ url: 'pages/...' }) // 若是是 tabbar 页面,请使用 wx.switchTab }, // 其余 类型:any 非必填 能够添加任意的函数或数据变量到 Object 参数中,用 this(即app实例) 能够访问 /** * 可添加全局函数,获取app应用实例后便可使用 * * 以下: * const app = getApp(); * * app.test(23333) * * 控制台将打印"23333" */ test: function(e) { console.log(e) }, //全局变量,全局可用,通常用于保存用户信息 globalData: { userInfo: null } })
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
/* app.wxss */ /* WXSS 用来决定 WXML 的组件应该怎么显示。WXSS 具备 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。 与 CSS 相比,WXSS 扩展的特性有: 尺寸单位 样式导入 尺寸单位 rpx(responsive pixel): 能够根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。 设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度) iPhone5 1rpx = 0.42px 1px = 2.34rpx iPhone6 1rpx = 0.5px 1px = 2rpx iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx 样式导入 使用@import语句能够导入外联样式表,@import后跟须要导入的外联样式表的相对路径,用;表示语句结束。 */ /* 建议: 开发微信小程序时设计师能够用 iPhone6 做为视觉稿的标准。 */ /* 内联样式 框架组件上支持使用 style、class 属性来控制组件的样式。 style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽可能避免将静态的样式写进 style 中,以避免影响渲染速度。 <view style="color:{{color}};" /> class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不须要带上.,样式类名之间用空格分隔。 <view class="normal_view" /> */ /* 选择器 目前支持的选择器有: 选择器 样例 样例描述 .class .intro 选择全部拥有 class="intro" 的组件 #id #firstname 选择拥有 id="firstname" 的组件 element view 选择全部 view 组件 element, element view, checkbox 选择全部文档的 view 组件和全部的 checkbox 组件 ::after view::after 在 view 组件后边插入内容 ::before view::before 在 view 组件前边插入内容 */ /* 全局样式与局部样式 定义在 app.wxss 中的样式为全局样式,做用于每个页面。在 page 的 wxss 文件中定义的样式为局部样式,只做用在对应的页面,并会覆盖 app.wxss 中相同的选择器。 */ .container { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 200rpx 0; box-sizing: border-box; }
文件类型 | 必需 | 做用 |
---|---|---|
js | 是 | 页面逻辑 |
wxml | 是 | 页面结构 |
json | 否 | 页面配置 |
wxss | 否 | 页面样式表 |
<!--index.wxml--> <view class='page'> <view class="container"> <view class="userinfo"> <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> <block wx:else> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view> </view> <!-- WXML --> <!-- WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,能够构建出页面的结构。 --> <!-- 仅介绍基础语法及事件系统,WXML基础组件及JS API使用 将由另外的篇幅来写,内容太多._ ._ ._ ._ ._ ._--> <!-- 如下将查看数据绑定、列表渲染、条件渲染、模板、引用等页面能力 全部功能测试数据可直接复制至js中使用,对应组件复制到wxml中,终值为最终显示的值(或最终运行的结果) --> <!-- 数据绑定 --> <!-- WXML 中的动态数据均来自对应 Page 的 data --> <!-- 简单绑定 数据绑定使用 Mustache 语法(双大括号)将变量包起来,能够做用于: 测试数据: Page({ data: { message: 'Hello WeChat!', id: 0, condition: true, flag: false, a:1, b:2, c:3, length:7, name:"World", object: { key: 'Hello ' }, array: ['MINA'], zero: 0, testa: 1, testb: 2, obj1: { a: 1, b: 2 }, obj2: { c: 3, d: 4 }, foo: 'my-foo', bar: 'my-bar', obj3: { a: 1, b: 2 }, obj4: { b: 3, c: 4 }, o: 5 } }) 可将内容复制到index.js的data中如下内容复制到wxml中便可查看效果 注:template组件因未存在相应模板将不会显示,自行调整代码以展现效果(添加对应模板文件,在模板文件中渲染数据便可) -内容 <view> {{ message }} </view> -终值:Hello WeChat! -组件属性 <view id="item-{{id}}"> </view> -终值:<view id="item-0"> </view> -控制属性 <view wx:if="{{condition}}">此组件将会显示</view> -终值:此组件将会显示 -关键字 <checkbox checked="{{false}}"> </checkbox> //true:boolean 类型的 true,表明真值。 //false: boolean 类型的 false,表明假值。 //特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后表明真值 -终值:组件未选中 -运算(支持简单运算) -三元运算 <view hidden="{{flag ? true : false}}"> Hidden </view> -终值:Hidden(组件显示) -算数运算 <view> {{a + b}} + {{c}} + d </view> -终值:3 + 3 + d -逻辑判断 <view wx:if="{{length > 5}}">大于5</view> -终值:大于5 -字符串运算 <view>{{"hello" + name}}</view> -终值:hello World -数据路径 <view>{{object.key}} {{array[0]}}</view> -终值:Hello MINA -组合 //能够在 Mustache 内直接进行组合,构成新的对象或者数组 <view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view> -终值:(依次打印数组内容"0"、"1"、"2"、"3"、"4") -对象 <template is="objectCombine" data="{{for: testa, bar: testb}}"></template> -终值:(向模板'objectCombine'传递对象{for: 1, bar: 2}) -扩展运算符 ... //将当前对象展开 <template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template> -终值:(向模版'objectCombine'传递对象{a: 1, b: 2, c: 3, d: 4, e: 5}) <template is="objectCombine" data="{{foo, bar}}"></template> -终值:(向模版'objectCombine'传递对象{foo: 'my-foo', bar:'my-bar'}) //注意: 上述方式扩展运算符能够随意组合,可是若有存在变量名相同的状况,后边的数据会覆盖前面的数据 <template is="objectCombine" data="{{...obj3, ...obj4, o, c: 6}}"></template> -终值:(向模版'objectCombine'传递对象{a: 5, b: 3, c: 6}) 花括号和引号之间若是有空格,将最终被解析成为字符串 <view wx:for="{{[1,2,3]}} "> {{item}} </view> -终值:(页面依次循环输出for中的数据"1"、","、"2"、","、"3"、" "最后将输出6个view) --> <!-- 列表渲染 测试数据 Page({ data: { array: [{ message: 'foo', }, { message: 'bar' }], condition2:true, length:4, objectArray: [ {id: 5, unique: 'unique_5'}, {id: 4, unique: 'unique_4'}, {id: 3, unique: 'unique_3'}, {id: 2, unique: 'unique_2'}, {id: 1, unique: 'unique_1'}, {id: 0, unique: 'unique_0'}, ], }, switch: function(e) { const length = this.data.objectArray.length for (let i = 0; i < length; ++i) { const x = Math.floor(Math.random() * length) const y = Math.floor(Math.random() * length) const temp = this.data.objectArray[x] this.data.objectArray[x] = this.data.objectArray[y] this.data.objectArray[y] = temp } this.setData({ objectArray: this.data.objectArray }) }, }) -wx:for 在组件上使用 wx:for 控制属性绑定一个数组,便可使用数组中各项的数据重复渲染该组件。 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item <view wx:for="{{array}}"> {{index}}: {{item.message}} </view> -终值:0:foo 1:bar //可以使用 wx:for-item 指定数组当前元素的变量名 //可以使用 wx:for-index 指定数组当前下标的变量名 //如<view wx:for="{{array}}" wx:for-item="inde" wx:for-index="indexx"> //{{indexx}}: {{inde.message}} //</view> //最终结果是同样的 //注:当 wx:for 的值为字符串时,会将字符串解析成字符串数组(将整个字符串,逐行打印) //注:花括号和引号之间若是有空格,将最终被解析成为字符串 -wx:for 嵌套,下边是一个九九乘法表 <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i"> <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j"> <view wx:if="{{i <= j}}"> {{i}} * {{j}} = {{i * j}} </view> </view> </view> -wx:key 若是列表中项目的位置会动态改变或者有新的项目添加到列表中,而且但愿列表中的项目保持本身的特征和状态(如 input 中的输入内容,switch 的选中状态),须要使用 wx:key 来指 定列表中项目的惟一的标识符。 wx:key 的值以两种形式提供 字符串,表明在 for 循环的 array 中 item 的某个 property,该 property 的值须要是列表中惟一的字符串或数字,且不能动态改变。 保留关键字 *this 表明在 for 循环中的 item 自己,这种表示须要 item 自己是一个惟一的字符串或者数字,如: 当数据改变触发渲染层从新渲染的时候,会校订带有 key 的组件,框架会确保他们被从新排序,而不是从新建立,以确保使组件保持自身的状态,而且提升列表渲染时的效率。 如不提供 wx:key,会报一个 warning, 若是明确知道该列表是静态,或者没必要关注其顺序,能够选择忽略. <switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch> <button bindtap="switch"> Switch </button> <switch wx:for="{{objectArray}}" style="display: block;"> {{item.id}} </switch> //以上代码来自官方,本身作了些调整,更加直观,也可直接去官方查看:https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html //说人话系列:简单来讲,当你的数据源发生改变时,添加了wx:key的循环体会被从新排序(已添加的数据不会被改变),而不是从新建立(初始化全部数据) --> <!-- 条件渲染 -wx:if 在框架中,使用 wx:if="" 来判断是否须要渲染该代码块: <view wx:if="{{condition2}}"> True </view> -终值:(此组件将显示) 也能够用 wx:elif 和 wx:else 来添加一个 else 块: <view wx:if="{{length > 5}}"> 1 </view> <view wx:elif="{{length > 2}}"> 2 </view> <view wx:else> 3 </view> -终值:(只显示2) //与js中的if、else if、else相同,只判断一次,若前者经过,则后者不运行 -block wx:if 若是要一次性判断多个组件标签,可使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。 //注: <block/> 并非一个组件,它仅仅是一个包装元素,不会在页面中作任何渲染,只接受控制属性。 -wx:if vs hidden 由于 wx:if 之中的模板也可能包含数据绑定,因此当 wx:if 的条件值切换时,框架有一个局部渲染的过程,由于它会确保条件块在切换时销毁或从新渲染。 同时 wx:if 也是惰性的,若是在初始渲染条件为 false,框架什么也不作,在条件第一次变成真的时候才开始局部渲染。 相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。 通常来讲,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。所以,若是须要频繁切换的情景下,用 hidden 更好,若是在运行时条件不大可能改变则 wx:if 较好。 --> <!-- 模板 WXML提供模板(template),能够在模板中定义代码片断,而后在不一样的地方调用。 测试数据: Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } }, showmodal: function () { wx.showModal({ title: '提示', content: '触发JS', }) } }) -定义模板 使用 name 属性,做为模板的名字。而后在<template/>内定义代码片断,如: <template name="msgItem"> <view bindtap="showmodal"> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template> -使用模板 使用 is 属性,声明须要的使用的模板,而后将模板所须要的 data 传入,如: <template is="msgItem" data="{{...item}}"/> //使用不一样页面的模板时 //引入模板文件 <import src="../template/template.wxml" /> //相应模板能够拥有独立的css @import "../template/template.wxss"; //模板不能独立建立JS文件,但相应事件能够在当前页面中被触发 -动态渲染 is 属性可使用 Mustache 语法,来动态决定具体须要渲染哪一个模板: <template name="odd"> <view> odd </view> </template> <template name="even"> <view> even </view> </template> <block wx:for="{{[1, 2, 3, 4, 5]}}"> <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/> </block> --> <!-- 引用 -import import能够在该文件中使用目标文件定义的template //仅引入文件而没使用,需调用对应组件才能生效 <import src="../template/template.wxml" /> 做用域: import 有做用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。 -include include 能够将目标文件除了 <template/> <wxs/> 外的整个代码引入,至关因而拷贝到 include 位置 <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/> //header.wxml <view> header </view> //footer.wxml <view> footer </view> --> <!-- 基础语法 End --> <!-- 事件系统 --> <!-- -事件 //事件系统微信官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html 事件是视图层到逻辑层的通信方式。 事件能够将用户的行为反馈到逻辑层进行处理。 事件能够绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。 事件对象能够携带额外信息,如 id, dataset, touches //说人话:事件是一种用户与程序的互动行为,当用户点击某一个按钮、图片等,若是按钮、图片绑定了相应事件,用户的行为就会触发事件如: 测试数据: Page({ tapName: function(e) { console.log(e.currentTarget.dataset.hi) } }) <view id="tapTest" data-hi="Hi WeChat" bindtap="tapName"> Click me! </view> -终值:(控制台打印)Hi WeChat -事件分类 事件分为冒泡事件和非冒泡事件: 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。 如: //index.wxml <view id="tp1" class="view1" bindtap="tap1"> <view id="tp2" class="view2" bindtap="tap2"> <view id="tp3" class="view3" bindtap="tap3"> <view id="tp4" class="view4" catchtap="tap4"> <view id="tp5" class="view5" bindtap="tap5"> </view> </view> </view> </view> </view> //index.wxss .view1 { height: 200rpx; width: 700rpx; background-color: #13c106; } .view2 { height: 200rpx; width: 550rpx; background-color: #1495e7; } .view3 { height: 200rpx; width: 400rpx; background-color: #f00; } .view4 { height: 200rpx; width: 250rpx; background-color: #fff; } .view5 { height: 200rpx; width: 100rpx; background-color: #ffce44; } //以上数据展现冒泡事件及非冒泡事件的区别,JS可写可不写,开发者工具会发出相应警告,观察警告条数便可 //注意tap4事件绑定方式为catch //微信冒泡事件列表: 类型 触发条件 最低版本 touchstart 手指触摸动做开始 touchmove 手指触摸后移动 touchcancel 手指触摸动做被打断,如来电提醒,弹窗 touchend 手指触摸动做结束 tap 手指触摸后立刻离开 longpress 手指触摸后,超过350ms再离开,若是指定了事件回调函数并触发了这个事件,tap事件将不被触发 1.5.0 longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 animationstart 会在一个 WXSS animation 动画开始时触发 animationiteration 会在一个 WXSS animation 一次迭代结束时触发 animationend 会在一个 WXSS animation 动画完成时触发 touchforcechange 在支持 3D Touch 的 iPhone 设备,重按时会触发 1.9.90 //注:除上述以外的其余组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件 -事件绑定 事件绑定的写法同组件的属性,以 key、value 的形式。 key 以bind或catch开头,而后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本 1.5.0 起,在非原生组件中,bind和catch后能够紧跟一个冒号,其含义不变,如 bind:tap、catch:touchstart。 value 是一个字符串,须要在对应的 Page 中定义同名的函数。否则当触发事件的时候会报错。基础库版本 2.8.1 起,原生组件也支持bind后紧跟冒号的写法。 //bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定能够阻止冒泡事件向上冒泡。 //具体例子见事件分类 -事件捕获 事件的捕获阶段 自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段以前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段刚好相反。须要在捕获阶段监听事件时,能够采用 capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。 在下面的代码中,点击 inner view 会前后调用handleTap二、handleTap四、handleTap三、handleTap1。 <view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2"> outer view <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4"> inner view </view> </view> 若是将上面代码中的第一个capture-bind改成capture-catch,将只触发handleTap2。 <view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2"> outer view <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4"> inner view </view> </view> //说人话:触摸类的事件在触发以前会有一个捕获阶段,捕获阶段执行完成后才会触发事件,事件触发顺序以下: //用户点击-捕获阶段(冒泡/非冒泡)-触发事件(冒泡/非冒泡) //注:捕获阶段触发非冒泡事件,则不会触发以后的任何事件,且捕获阶段执行节点与冒泡顺序相反 -事件对象 如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。 BaseEvent 基础事件对象属性列表: 属性 类型 说明 基础库版本 type String 事件类型 timeStamp Integer 事件生成时的时间戳 target Object 触发事件的组件的一些属性值集合 currentTarget Object 当前组件的一些属性值集合 mark Object 事件标记数据 2.7.1 CustomEvent 自定义事件对象属性列表(继承 BaseEvent): 属性 类型 说明 detail Object 额外的信息 TouchEvent 触摸事件对象属性列表(继承 BaseEvent): 属性 类型 说明 touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组 changedTouches Array 触摸事件,当前变化的触摸点信息的数组 //特殊事件: canvas 中的触摸事件不可冒泡,因此没有 currentTarget -对象模型 { //触发的事件类型 type:"tap" //在基础库版本 2.7.1 以上,可使用 mark 来识别具体触发事件的 target 节点。此外, mark 还能够用于承载一些自定义数据(相似于 dataset )。 当事件触发时,事件冒泡路径上全部的 mark 会被合并,并返回给事件回调函数。(即便事件不是冒泡事件,也会 mark 。) /* //index.wxml <view mark:myMark="last" bindtap="bindViewTap"> <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button> </view> //index.js Page({ bindViewTap: function(e) { console.log(e) console.log(e.mark.myMark === "last") // true console.log(e.mark.anotherMark === "leaf") // true } }) 在上述 WXML 中,若是按钮被点击,将触发 bindViewTap 和 bindButtonTap 两个事件,事件携带的 event.mark 将包含 myMark 和 anotherMark 两项 mark 和 dataset 很类似,主要区别在于: mark 会包含从触发事件的节点到根节点上全部的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值。 细节注意事项: 若是存在同名的 mark ,父节点的 mark 会被子节点覆盖。(同名时离源组件越近,级别越高) 在自定义组件中接收事件时, mark 不包含自定义组件外的节点的 mark 。(当使用自定义组件时,自定义组件中的mark是独立的) 不一样于 dataset ,节点的 mark 不会作连字符和大小写转换。 */ mark:{} //自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。 点击事件的detail 带有的 x, y 同 pageX, pageY 表明距离文档左上角的距离 detail:{} //触发事件的源组件。 target:{ //事件源组件的ID id:"tapTest" //事件源组件上由data-开头的自定义属性组成的集合 //能够绑定动态数据,如:data-id="{{userid}}" /* dataset 在组件节点中能够附加一些自定义数据。这样,在事件中能够获取这些自定义的节点数据,用于事件的逻辑处理。 在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 链接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如: data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType ; data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype 。 //index.wxml <view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view> //index.js Page({ bindViewTap:function(event){ console.log(event.currentTarget.dataset.alphaBeta === "1") // 会转为驼峰写法 console.log(event.currentTarget.dataset.alphabeta === "2") // 大写会转为小写 } }) */ dataset:{hi: "Hi WeChat"} } //touches 是一个数组,每一个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点 touches:[ 0:{ //触摸点标识符 identifier: 0 //距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴 clientX: 29 clientY: 411 force: 1 //距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴 pageX: 29 pageY: 517 } ] //页面打开到触发事件所通过的毫秒数 timeStamp:1000 //事件绑定的当前组件 currentTarget:{ //当前组件ID(如冒泡事件,此值为当前组件ID非源组件) id: "tapTest" //当前组件上由data-开头的自定义属性组成的集合(当前组件属性) dataset: {hi: "Hi WeChat"} } //changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel) changedTouches:[{}] __proto__: Object } -->
// 页面配置page.json // 每个小程序页面均可以使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项。文件内容为一个 JSON 对象,有如下属性 { // 导航栏背景颜色 颜色都以十六进制显示,不然在不一样设备中可能显示错误 "navigationBarBackgroundColor": "#13c106", // 导航栏标题颜色,仅支持 black / white (黑/白) "navigationBarTextStyle": "black", // 导航栏标题文字内容 "navigationBarTitleText": "聽風吟", // 导航栏样式,仅支持如下值:default 默认样式 、 custom 自定义导航栏,只保留右上角胶囊按钮 "navigationStyle": "default", // 窗口的背景色 "backgroundColor": "#13c106", // 下拉 loading 的样式,仅支持 dark (三个点)/ light (无特殊展现) "backgroundTextStyle": "dark", // 顶部窗口的背景色,仅 iOS 支持 "backgroundColorTop": "#13c106", // 底部窗口的背景色,仅 iOS 支持 "backgroundColorBottom": "#13c106", // 控制当前页下拉刷新 "enablePullDownRefresh": false, // 控制当前页上拉刷新 "onReachBottomDistance": false, // 控制当前页屏幕旋转 支持 auto (自动)/ portrait(竖屏) / landscape (2.5.0支持固定横屏显示) "pageOrientation": "portrait", // 设置为 true 则页面总体不能上下滚动。只在页面配置中有效,没法在 app.json 中设置 "disableScroll": true, // 页面自定义组件配置 /* 自定义组件 从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。全部自定义组件相关特性都须要基础库版本 1.6.3 或更高。 开发者能够将页面内的功能模块抽象成自定义组件,以便在不一样的页面中重复使用;也能够将复杂的页面拆分红多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件很是类似 */ /* // custom-comp 建立自定义组件 相似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。要编写一个自定义组件,首先须要在 json 文件中进行自定义组件声明(将 component 字段设为 true 能够将这一组文件设为自定义组件) // custom-comp.json { "component": true } 在 wxml 文件中编写组件模板,在 wxss 文件中加入组件样式,它们的写法与页面的写法相似。 // custom-comp.wxml <view class="inner"> {{innerText}} </view> <slot></slot> // custom-comp.wxss .inner { color: red; } // 注意:在组件wxss中不该使用ID选择器、属性选择器和标签名选择器。 在自定义组件的 js 文件中,须要使用 Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法。 组件的属性值和内部数据将被用于组件 wxml 的渲染,其中,属性值是可由组件外部传入的 // custom-comp.js Component({ properties: { // 这里定义了innerText属性,属性值能够在组件使用时指定 innerText: { type: String, value: 'default value', } }, data: { // 这里是一些组件内部数据 someData: {} }, methods: { // 这里是一个自定义方法 customMethod: function(){} } }) */ // 使用自定义组件,使用已注册的自定义组件前,首先要在页面的 json 文件中进行引用声明。此时须要提供每一个自定义组件的标签名和对应的自定义组件文件路径: "usingComponents": { "custom-comp": "./custom-comp" } /* <view> <!-- 如下是对一个自定义组件的引用 --> <custom-comp inner-text="Some text"></custom-comp> </view> */ // 在页面的 wxml 中就能够像使用基础组件同样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值 // 自定义组件的 wxml 节点结构在与数据结合以后,将被插入到引用位置内 /* 细节注意事项: 由于 WXML 节点标签名只能是小写字母、中划线和下划线的组合,因此自定义组件的标签名也只能包含这些字符。 自定义组件也是能够引用自定义组件的,引用方法相似于页面引用自定义组件的方式(使用 usingComponents 字段)。 自定义组件和页面所在项目根目录名不能以“wx-”为前缀,不然会报错。 注意,是否在页面文件中使用 usingComponents 会使得页面的 this 对象的原型稍有差别,包括: 使用 usingComponents 页面的原型与不使用时不一致,即 Object.getPrototypeOf(this) 结果不一样。 使用 usingComponents 时会多一些方法,如 selectComponent 。 出于性能考虑,使用 usingComponents 时, setData 内容不会被直接深复制,即 this.setData({ field: obj}) 后 this.data.field === obj 。(深复制会在这个值被组件间传递时发生。) */ }
//工具配置project.config.json //官方提供的配置很是残缺。。。 /* 如配置值为""则为Sring类型,根据相应路径或提示更改便可 如配置值为true则当前配置为Boolean类型 如配置值为Object固定选项则会有相应提示 */ { //指定小程序源码的目录(需为相对路径)-- "miniprogramRoot": "", //指定腾讯云项目的目录(需为相对路径)-- "qcloudRoot": "", //指定插件项目的目录(需为相对路径)-- "pluginRoot": "", //编译类型 /* 仅包含miniprogram (普通小程序项目)plugin(小程序插件项目) */ "compileType": "miniprogram", //项目设置 "setting": { //是否启用 es6 转 es5 "es6": true, //上传代码时样式是否自动补全 "postcss": true, //上传代码时是否自动压缩 "minified": true, //是否检查安全域名和 TLS 版本 "urlCheck": false, //是否进行代码保护-- "uglifyFileName": true, //是否打开SiteMap索引提示((默认为true) /* 微信现已开放小程序内搜索,开发者能够经过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否容许微信索引。当开发者容许微信索引时,微信会经过爬虫的形式,为小程序的页面内容创建索引。当用户的搜索词条触发该索引时,小程序的页面将可能展现在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler 及场景值:1129。须要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。 */ /* 说人话系列: 微信小程序2019/03/29号推出 sitemap 功能,默认收录全部小程序页面功能,用于微信场景搜索,以后能够根据内容来搜索小程序,而不只止于小程序名称和简介 此功能并不是关闭索引,而是关闭索引的提示 关闭索引请查看 sitemap.json */ "checkSiteMap": true, //是否使用工具渲染 CoverView-- "coverView": true, //是否打开加强编译-- "enhance": true, //加强编译下Babel的配置项-- "babelSetting": { //配置须要跳过Babel编译(包括代码压缩)处理的文件或目录 "ignore": [], //暂无官方说明 "disablePlugins": [], //Babel 辅助函数的输出目录,默认为 @babel/runtime "outputPath": "" }, //上传时是否带上 sourcemap(默认为true) "uploadWithSourceMap": true, //暂无官方说明 "newFeature": true, "autoAudits": false, "checkInvalidKey": true, }, //基础库版本 "libVersion": "2.8.0", //当前项目appid,只在新建项目时读取 "appid": "wx03f53a71c3f1c05c", //当前项目名字,只在新建项目时读取 "projectname": "XJTest", //打包配置项(此项设置需重启开发者工具才可生效) /* packOptions 用以配置项目在打包过程当中的选项。打包是预览、上传时对项目进行的必须步骤。 目前能够指定 packOptions.ignore 字段,用以配置打包时对符合指定规则的文件或文件夹进行忽略,以跳过打包的过程,这些文件或文件夹将不会出如今预览或上传的结果内。 packOptions.ignore 为一对象数组,对象元素类型以下: 字段名 类型 说明 value string 路径1或取值 type string 类型 */ /* type 能够取的值为 folder(文件夹) file(文件) suffix(后缀) prefix(前缀) regexp2(正则表达式) glob2(Glob 规则) 全部规则值都会自动忽略大小写。 注 1: value 字段的值若表示文件或文件夹路径,以小程序目录 (miniprogramRoot) 为根目录。 注 2: regexp、glob 仅 1.02.1809260 及以上版本工具支持。 */ //示例 "packOptions": { "ignore": [ { "type": "file", "value": "test/test.js" }, { "type": "folder", "value": "test" }, { "type": "suffix", "value": ".webp" }, { "type": "prefix", "value": "test-" }, { "type": "glob", "value": "test/**/*.js" }, { "type": "regexp", "value": "\\.jsx$" } ] }, //调试配置项 /* debugOptions 用以配置在对项目代码进行调试时的选项。 目前能够指定 debugOptions.hidedInDevtools 字段,用以配置调试时于调试器 Sources 面板隐藏源代码的文件。 hidedInDevtools 的配置规则和 packOptions.ignore 是一致的。 当某个 js 文件符合此规则时,调试器 Sources 面板中此文件源代码正文内容将被隐藏,显示为: // xxx.js has been hided by project.config.json 注:配置此规则后,可能须要关闭并从新打开项目才能看到效果。 */ "debugOptions": { "hidedInDevtools": [ { "type": "file", "value": "test/test.js" }, { "type": "folder", "value": "test" }, { "type": "suffix", "value": ".webp" }, { "type": "prefix", "value": "test-" }, { "type": "glob", "value": "test/**/*.js" }, { "type": "regexp", "value": "\\.jsx$" } ] }, //自定义预处理 "scripts": { //官方仅如下说明 /* scripts 中指定自定义预处理的命令 名字 说明 beforeCompile 编译前预处理命令 beforePreview 预览前预处理命令 beforeUpload 上传前预处理命令 */ }, //当前文件描述 "description": "项目配置文件", //是否为游客 "isGameTourist": false, //工具类型 "simulatorType": "wechat", //开发者工具插件库版本 "simulatorPluginLibVersion": {}, //暂无官方说明 "condition": { "search": { "current": -1, "list": [] }, "conversation": { "current": -1, "list": [] }, "game": { "currentL": -1, "list": [] }, "miniprogram": { "current": -1, "list": [] } } }
//小程序索引配置sitemap.json /* 微信现已开放小程序内搜索,开发者能够经过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否容许微信索引。当开发者容许微信索引时,微信会经过爬虫的形式,为小程序的页面内容创建索引。当用户的搜索词条触发该索引时,小程序的页面将可能展现在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler 及场景值:1129。须要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。 */ /* 注:若是没有 sitemap.json ,则默认为全部页面都容许被索引 注:{"action": "allow","page": "*"} 是优先级最低的默认规则,未显式指明 "disallow" 的都默认被索引 */ { //文件描述 "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", // 小程序索引配置 "rules": [ { // "allow"(容许)、"disallow"(不容许) 命中该规则的页面是否能被索引 "action": "allow", // "*" 全部页面/页面的路径 "page": "path/to/page", // 当 page 字段指定的页面在被本规则匹配时可能使用的页面参数名称的列表(不含参数值) "params": [ "a", "b" ], // 当 page 字段指定的页面在被本规则匹配时,此参数说明 params 匹配方式 /* exact 当小程序页面的参数列表等于 params 时,规则命中 inclusive 当小程序页面的参数列表包含 params 时,规则命中 exclusive 当小程序页面的参数列表与 params 交集为空时,规则命中 partial 当小程序页面的参数列表与 params 交集不为空时,规则命中 */ "matching": "exact" }, { "action": "disallow", "page": "path/to/page" } ] /* path/to/page?a=1&b=2 => 优先索引 path/to/page => 不被索引 path/to/page?a=1 => 不被索引 path/to/page?a=1&b=2&c=3 => 不被索引 其余页面都会被索引 */ }
import和require都是被模块化所使用。
1-遵循规范
require 是 AMD规范引入方式
import是ES6的一个语法标准,若是要兼容浏览器的话必须转化成ES5的语法
2-调用时间
require是运行时调用,因此require理论上能够运用在代码的任何地方
import是编译时调用,因此必须放在文件开头
3-本质
require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量
import是解构过程,可是目前全部的引擎都尚未实现import,咱们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require
var:声明全局变量。换句话理解就是,声明在for循环中的变量,跳出for循环一样可使用。
let:声明块级变量。即局部变量。(只在let命令所在的代码块内有效)
const:声明一个只读常量。具备块级做用域。(一旦声明即不可更改,声明时必须赋值)
var命令会发生”变量提高“现象,即变量能够在声明以前使用,值为undefined。这种现象多多少少是有些奇怪的,按照通常的逻辑,变量应该在声明语句以后才可使用。
为了纠正这种现象,let命令改变了语法行为,它所声明的变量必定要在声明后使用,不然报错。
只要块级做用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,再也不受外部的影响。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
上面代码中,存在全局变量tmp,可是块级做用域内let又声明了一个局部变量tmp,致使后者绑定这个块级做用域,因此在let声明变量前,对tmp赋值会报错。
ES6明确规定,若是区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就造成了封闭做用域。凡是在声明以前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量以前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
let不容许在相同做用域内,重复声明同一个变量
const实际上保证的,并非变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,所以等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,它指向的数据结构是可变的。
是一种取代XML的一种轻量级的数据交换格式
它独立于语言的文本格式的的同时还采用了相似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)和xml相比,它更小巧、易于人阅读和编写,而且描述能力也不差,同时也易于机器解析和生成。
这些特性使JSON成为理想的数据交换语言,利于网络传输数据且节省流量而起到加快速度的做用。
书写格式是:以“{”开始,“}”结束。是一个无序的“‘名称/值’对”集合。名称写在前面(在双引号中),值对写在后面(一样在双引号中),中间用冒号隔开。
[若是是字符串,那无论是键或值最好都用双引号引发来]
获取当前系统信息
wx.getSystemInfo({
success: function (res) {
console.log(res)
}
})
包含信息:
DKVersion:"2.7.7" -SDK版本
batteryLevel:100 -电池水平
brand:"devtools" -品牌
errMsg:"getSystemInfo:ok" -errMsg
fontSizeSetting:16 -字体大小设置
language:"zh" -语言
model:"iPhone 7 Plus" -模型
pixelRatio:3 -像素比
platform:"devtools" -平台
screenHeight:736 -屏幕高度
screenWidth:414 -屏幕宽度
statusBarHeight:20 -状态栏高度
system:"iOS 10.0.1" -系统
version:"6.6.3" -版本
windowHeight:672 -窗口高度
windowWidth:414 -窗口宽度