• quickStart 工程文件基础

项目基础文件

  • app.json 这里对小程序所有的页面进行配置,其实详细的大家可以看官方文档,跟你app界面结构相关的就是前三个

    • “pages”字段表示app包含的所有页面,只有在这里注册过的页面才会有效进行编译,如果你的app不包含”tab”字段,那么app的首页就是”pages”数组里面的第一个page
    • “window”字段是处理对于navigationbar的一些样式设置
    • “tabBar”字段如果存在,表示app开启首页面为底部tabbar的形式,这样每个tab所对应的page在”tabBar”字段里设置
    • “networkTimeout”,”debug”这两个字段一个配置全局网络超时,一个开启debug模式
  • app.wxss 这里其实是全局的CSS,凡是在这里写过的CSS样式,在各自子page里面可以直接使用,写在其他.wxss文件里的样式是不能跨page使用的,可以通过@import进行样式导入,导入别的.wxss文件,但是目前我实践的结果@import只有在主app.wxss里才有效,路径是相对路径
  • app.js 这里就是纯js代码逻辑了,官方的demo里给你展示了一些基本代码,调用了微信的login接口,回调,读取用户头像,读本地存储之类的。并且通过js的一个全局函数getApp()可以获得app.js的这个app对象。

页面文件

如果一个页面起名叫HomePage,那么我们就应该自行手动创建3个文件,文件名一致才会被系统正确的识别

  • HomePage.js 代表着这个页面的业务逻辑,当你在空白js里面输入page的时候会自动出现代码补全,帮你补全了一个page的所有生命周期,onLoad,onHide啥的,其他的js代码提示很不完善╮(╯_╰)╭
  • HomePage.wxss 这里面写这个页面的专属css,别的页面不能使用,只在这个页面下可以用,但是可以被import到app.wxss里面,实现全局通用,并且wxss的代码提示非常完善,很爽,很多文档没写的css表,可以通过ide代码提示+推测标准css3,来知道如何编写
  • HomePage.wxml 这里面写这个页面了,这种WXML语法看起来就很像html,但他还真不是html,html的东西完全不能直接在这里用。你必须用wx提供的wxml相关组件完全重写,条件渲染,循环渲染,数据绑定,都得按着微信的规定来,并且提供了最简单的模板模块功能,实现一定程度的复用。

还可以有个可选的HomePage.json文件,页面也是可以拥有自己的.json文件进行一些专属配置的,但是页面的json可以配置的字段不如app.json多,职能配置关于本window相关的一些表现,比如

     
1
2
3
4
5
6
7
     
{
"navigationBarBackgroundColor":"#ffffff",
"navigationBarTextStyle":"black",
"navigationBarTitleText":"微信接口功能演示",
"backgroundColor":"#eeeeee",
"backgroundTextStyle":"light"
}

上手开搞

  • 创建一个新目录HomePage,创建好我们页面自己的HomePage至少三个文件
  • HomePage.js里面写page,自动补全好页面生命周期,其余留空
  • 修改app.json里面 “pages”字段,添加进去我们最新的页面路径,并且放到最上面。
  • 直接点编译,你会发现,你的微信小程序已经在模拟器里面运行起来了,没有报错,只是空白一片,什么也没有嘛。

后面开始动手画UI了,这个我没有啥教学的,因为上文提供的github各种demo里面丰富多彩的所有组件用法已经够全的了,我这手把手的教如何写一个按钮,如何写一个text,如何水平排布好几段文字,这就有点太无脑了。我举例几个项目中用到的界面,然后写点我这个小白在趟出这些界面的时候遇到的一些问题点吧

开发小记

小程序的mvvm

小程序天然有一套数据和UI的绑定机制,在js文件里有如下代码,在onload里面发起网络请求,网络请求后回来,handleResponse,再之后setData,可以看到这个data其实就是一个vm

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
     
data:{
originData: {},
bookList: []
},
onLoad:function(options){
var self = this;
console.log()
wx.request({
url:'xxxxxxxx',
header: {
'Content-Type': 'application/json'
},
success: function(res) {
if(res.data.status.code == 0){
self.handleResponse(res.data.data);
}
}
});
console.log('onLoad')
},
handleResponse:function(response){
console.log(response);
var bookList = response.content.column_data;
this.setData({
originData:response,
bookList:bookList
});
},

当任何时候在js逻辑里面,修改了data,这样的wxml中,这种就是告诉负责UI的WXML,这块UI要和bookList这个data里面的一个字段进行绑定,任何时候data发生了变化,这个UI都会根据最新的数据结果刷新

     
1
2
3
     
<view wx:for="{{bookList}}" wx:for-item="listBookItem" wx:for-index="rowIndex" class="novelBookContainer">
<include src="../../component/novelBook/novelBook.wxml"/>
</view>

小程序的代码复用&模块化

可以看出来,我的2个页面,最重要的就是一个书籍详情Cell,进行复用,避免代码大量的机械性重复。

模块化得从3个层面,jswxsswxml来说

  • js的模块化:小程序的js看起来就是最普通的js,似乎看起来是不支持ES6的,因此用传统的module.exports就可以封装js的api模块提供外部使用
  • wxss的样式导入:上文提过,每个page只能认自己page的wxss,和全局的app.wxss,其他的wxss是不支持由别的文件直接引入的,但是可以在全局app.wxss里面使用@import来把别的文件的样式,导入全局,这样各自page都能使用了
  • wxml的模板:官方文档里说支持<template>的方式创建一个模板,模板支持使用data传入数据,我的项目里没这么使用过,我用的另一种方案
  • wxml的引用:官方文档里也说明了支持<include>他的作用其实只是原封不动的代码字符串拷贝,会拷贝目标wxml文件里除<template>外所有的标签,原封不动的拷贝替换到<include>位置(这是纯字符串复制,不能支持指定代码灵活变化,需要灵活变化请使用模板)

点击事件传值

下面这个代码就是我的bookCell的wxml代码,可以看到这里大量使用了进行UI和data的绑定,这样每次setData,都会让ui直接生效,但我这里重点给大家看一下关于绑定点击事件。

     
1
2
3
4
5
6
7
8
9
10
11
     
<view class="novelBookDesc" data-sectionIndex="{{sectionIndex}}" data-rowIndex="{{rowIndex}}" bindtap="tapBook" tapIndex="{{listBookIndex}}">
<image src="{{listBookItem.small_pic_url}}" mode="scaleToFill" class="novelBookCover"/>
<text class="novelBookTitleText">[{{listBookItem.sub_class}}] {{listBookItem.title}}</text>
<view class="novelBookTextInfo">
<text class="novelBookTextAuthor">{{listBookItem.author}}</text>
<text class="novelBookTextAuthor">|</text>
<text class="novelBookTextStatus novelBookTextStatusOver" wx:if="{{listBookItem.is_full==1}}">完结</text>
<text class="novelBookTextStatus novelBookTextStatusNotOver" wx:if="{{listBookItem.is_full!=1}}">连载</text>
</view>
<text class="novelBookTextSummary">{{listBookItem.summary}}</text>
</view>

官方文档里面写的真是比较简单,bindtap="tapBook"写好了这一句后,每当这个UI元素被点击的时候,都一定会触发对应page的.js文件中tapBook这个jsfunction,看起来很容易,但传值呢?发生点击我怎么知道点击的时候是哪个book被点击了?第几个本书?书的id是啥?关键就在这里

data-sectionIndex="" data-rowIndex=""

这一行给添加了2个属性,都是以data-开头,自定义的名字为结束,并且绑定上了2个数据(for 循环的index,for循环后面说),这样添加自定义的data-xx属性就是为点击事件传递属性的关键

     
1
2
3
4
5
6
7
8
9
     
tapBook:function (event){
var section = event.currentTarget.dataset.sectionindex;
var row = event.currentTarget.dataset.rowindex;
var book = this.data.sectionList[section].column_list.book_info[row];
var docid = book.doc_id;
wx.navigateTo({
url: '../read/read?docid=' + docid
});
},

这是对应js代码,当触发tapBook的时候,会把event当做参数传入,event.currentTarget.dataset.xxx 就能获取你刚才data-xx绑定的数据,我刚才把sectionIndex rowIndex的列表点击index绑上了,于是通过这个方法取出来了。

切记,你在wxml里几遍data-xx,写了大写英文字母,此处在js里调用的时候被自动全部变成小写了,你再写大写是undefine的

for循环创建列表

官方文档里面给了好几种for循环的方案,什么 ,都可以绑定上一个js数组数据,然后按着数组的个数循环渲染列表形UI,

     
1
2
3
     
<view wx:for="{{listItem.column_list.book_info}}" wx:for-item="listBookItem" wx:for-index="rowIndex" class="novelBookContainer">
<include src="../../component/novelBook/novelBook.wxml"/>
</view>

这就是一个for循环创建列表的例子

  • wx:for的意思是告诉这个内用循环创建内容,循环所绑定的数组是listItem.column_list.book_info
  • wx:for-item的意思是,你在下面写当次循环需要用到的具体数组元素,你起名成listBookItem
  • wx:for-index的意思是,你在下面写档次循环需要用到的数组下表,你起名成了rowIndex

循环内我include的代码,就是上文点击事件传值介绍的代码,这时候我们回过头去看

<text class="novelBookTitleText">[] </text>

<view class="novelBookDesc" data-sectionIndex="" data-rowIndex="" bindtap="tapBook" tapIndex="">

怎么样,用到listBookItem数据在绑定上了吧,用到rowIndex在点击事件了把,同理可知sectionIndex其实是另外一个我没展示的外层循环的wx:for-index定义。

wx对象提供的API

所谓API其实就是,在js文件里,微信也提供了很多native API,以wx.xxx开头,官方API文档,包括很多内容,我就不一一举例了,这里举例几个比较重要的分类

  • 网络

    • http请求(最常用,各大demo都是通过wx.request()来做http请求)
    • 大文件上传下载
    • websockt
  • 数据
    • 数据缓存,本地key-value式数据存储
    • 各种同步,异步,数据处理接口
  • 导航 页面之间各种跳转
  • 动画 绘图
  • 媒体
  • 设备 重力感应,系统信息,网络状态,罗盘等等
  • 微信支付
  • 微信登陆,用户信息

可以看出,都是直接跟网络,跟设备,相关的信息。

界面跳转

我们在小程序mvvm里面已经看到了一段关于wx.request的演示,这里演示一下,界面之间跳转

  • wx.nativateTo() 通过push动画打开新的页面
  • wx.redirectTo() 当前页面重定向到新页面进行展示,不打开
  • wx.navigatBack() 通过pop动画,弹出到上一级界面

wx.nativateTo是有数量限制的,小程序界面栈层级不能超过5的,所以很多场景可以选择使用wx.redirectTo

     
1
2
3
4
5
6
7
8
9
10
     
//跳转到别的页面的代码,注意看如何传值
wx.navigateTo({
url: '../topic/topic?topicid=' + topicid
});
//topic界面的js逻辑里面,onLoad生命周期函数
onLoad:function(options){
var topic = options.topicid
}
options.topic

可以看到,界面跳转通过url跳转,而传值也通过url的方式传值,你传过去的值会直接写进onLoad生命周期函数的options参数里面,名字和你在url里面写的是一样的。

CSS

说实话,一直以来都在做客户端开发,这种css式的界面开发模式,实在是太陌生了,css式的思维,css式的嵌套,对一个新手来说有点痛苦。

我的Github上面的小程序Demo 这里面的代码其实不多,基本上是我们项目的雏形,但最让我头疼的就是那些css,我整整写了一整天,才大约摸到一丢丢前端开发,css思维的方式方法

这个我也没啥好说的,毕竟我是大大大大菜鸟,就是多写写就有感觉了。

值得一提的是IDE对于WXSS文件里,css的代码补全非常赞,各种都能第一时间补全,对于我这个根本记不住那么多css名字的新手来说,这个实在是太好了。

另外,完全支持- position: absolute- position: relative的绝对坐标布局,也完全支持flexBox的弹性盒子布局,和我一起的小伙伴表示,基本上大部分的css都是直接可以用,我把线上项目迁移到wxss的时候也感觉到了,打开chrome的debug模式,照着线上wap站,原封不动的照着写css布局参数,基本上没有任何问题

调试

大家玩起来就知道了,微信小程序的调试模式,和chrome的debug模式一模一样,其实这个ide就是拿nw.js写的,里面是一套webkit,源码里面就有chrome的debug’tool的js代码哈哈

底层实现探讨

关于这个小程序底层是如何运作的,在刚出的第一天,就引来无数的遐想,wx独有的wxml wxss到底是拿什么做的?到底是不是h5?到底能不能做成native体验?无数人都在猜测。

在最开始的时候,ide被破解,并且被证实ide是基于webkit做的,很多人猜微信在真机上就是webview啦(后面事实证明,目前也还真是)

但我当时就觉得这其实说明不了啥,wx特别抽象出来的 wxml结构,就是想定义一个独立出来的独有抽象层,他虽然目前把这个抽象层(一种自己独有的vdom结构?我是前端新人,不一定对哈),最后又重新通过编译转成了html,最后交给webview来展现(辅助绑定上了一些native插件,比如wxapp里面的视频,tab,navi,input keyboard,map等等,都是通过addsubview的方式直接add到UI/WKwebview上的)

但是这并不代表,这样的架构就是依赖在webkit,和webview的,完全独有的抽象中间层vdom,就是为了摆脱对webkit的依赖,未来可以很轻松的切换底层架构,直接切换成reactnative or weex 那样的vdom + native渲染的模式,这样就没了webview的依赖,(虽然现在选择的方案,是又绕路回到了html和webkit,但依赖和选择权已经牢牢攥在了自己手里)

微信小程序开发人员回答渲染机制

这篇文章看起来官方人员态度有点遮遮掩掩,含糊其辞,通篇都没直指要害-如何渲染,但我觉得解读一下,是这样的潜台词(开玩笑!莫喷:我们很高大上,我们抽象了很多东西,其实我们还是主要用webview渲染,辅助了很多native,就是不太好意思这么直白的说出来)

但我特别认可微博上的这个回答

微信小程序搞起来!!!相关推荐

  1. 微信小程序 搞一个天气api

    最近在搞微信小程序,突然想来搞一个天气API,来获取实时的天气.话不多说,直接开搞.. 1. 选择一个天气API 百度上随便一搜,都是天气API,但是我感觉用起来都太烦了, 无论是注册,还是说要付费, ...

  2. 微信小程序-搞懂wx:for wx:index wx:item

    一.示例 1.1 js代码 Page({data: {list:[{id:'a',name:'111'},{id:'b',name:'222'},{id:'c',name:'333'}]} }) 1. ...

  3. 终于搞定微信小程序canvas分享海报

    canvas drawer 做微信小程序中最好用的 canvas 绘图组件之一. 当前环境下,大家都非常需要分享到朋友圈这个功能,但是实现起来各有心酸(坑比较多),所以才有了如下的 canvas 绘图 ...

  4. 手把手教你制作微信小程序,开源、免费、快速搞定

    最近做了个"罗孚传车"的小程序 一时兴起,做了一个小程序,将个人收集的同汽车相关的行业资讯和学习资料,分享到小程序中,既作为历史资料保存,又提供给更多的人学习和了解,还能装一下:) ...

  5. 【微信小程序】:重磅更新,搞事情啊

    21日,微信小程序进行框架重大升级,新增&更新&修复了共108项. 其中不乏一些令人欣喜的功能~ 新增可以扫码API: 新增选择显示遮罩功能: 新增自定义分享功能: 新增滚动选择器组件 ...

  6. 你还没搞懂的微信小程序,已成今年双十一电商黑马

    阿里今年双十一成交额达1682亿.京东11天的下单额达1271亿,各大财经媒体都在纷纷报道双十一全国各网上平台今年的创收,这些每年都在几十个百分点成长的数据无不让实体的各位老板瞠目结舌:然而还有一个很 ...

  7. 微信小程序之画布的旋转,你搞懂了吗?

    最近在学习微信小程序的时候,学习到画布时,旋转功能把我有点搞糊涂了.因为我一直以为,旋转的是画布,但其实,旋转的是坐标系. 坐标系方向为:画布向右为x,向左为-x,向上为-y,向下为y 程序示例如下: ...

  8. 一篇搞懂微信小程序以及和其他对比

    一篇搞懂微信小程序以及和其他对比** 前两年的文章了,现在小程序肯定是有变化的,作为自己的随记 一.产品定位及功能分析** 微信小程序是一种全新的连接用户与服务的方式,他可以在微信内被便捷的获取和传播 ...

  9. 微信小程序从入坑到放弃二十九:一个小场景搞懂冒泡事件bindtap和catchtap的区别

    摘要: 在微信小程序中,bindtap事件会产生冒泡,若不加以拦截,会一直冒泡到顶端.在某些情况下,一次点击会触发若干点击事件.为了防止冒泡,使用catchtap即可解决问题.在有全屏半透明背景的弹出 ...

最新文章

  1. Directx11教程(11) 增加一个debug宏
  2. 清华大学校内智能车竞赛辅导资料
  3. JavaScript之Style属性学习
  4. php header功能的使用
  5. 看动画学算法之:平衡二叉搜索树AVL Tree
  6. 定义一个1 1=11 用c语言什么输出来,问题 A: C语言11.1(示例代码)
  7. seqlist插入java_大话数据结构(五)(java程序)——顺序存储结构的插入与删除...
  8. leetcode报错runtime error: reference binding to null pointer of type ‘std::vector<std::__cxx11::basic_
  9. linux下安装python3.6
  10. scp 上传文件到服务器
  11. H3C | S6X00系列交换机策略路由配置案例
  12. 【优化求解】基于matlab免疫算法求解函数极值问题【含Matlab源码 1200期】
  13. windows下安装redis详细教程
  14. 打开Office时总是提示“正在配置microsoft office解决方法
  15. 子类可以重新定义父类的同名方法,并且允许他们有不同的返回值类型吗?
  16. RecyclerView 实现横向滚动效果
  17. python绘制相频特性曲线_数据分析之Matplotlib和机器学习基础
  18. 图像分割的 U-Net 系列方法
  19. 笔记本修改无线网卡MAC地址
  20. JS-计算日期差,计算日期之间的月数

热门文章

  1. 算力理解MIPS/DMIPS/MFLOPS/TOPS
  2. 将时间戳转换成日期格式:
  3. 透过数据看打印市场风云
  4. 我觉得我还可以再抢救一下——0.999...=1的前生今世
  5. U盘(auto病毒)类病毒分析与解决方案(zt)
  6. JavaFX Image Invalid URL or resource not found
  7. c语言测试框架设计,C语言单元测试框架Check
  8. mac下安装autojump
  9. 学习Python的9个理由
  10. 百思不得姐网站 Scrapy爬虫笔记