小程序
wepy
小程序框架 wepy 文档
快速入门
安装 wepy
npm install wepy-cli -g
在开发目录生成开发DEMO。
wepy new myproject
开发实时编译。
wepy build --watch
项目目录结构
dist
node_modules
src
components
com_a.wpy
com_b.wpy
pages
index.wpy
page2.wpy
app.wpy
package.json
2
3
4
5
6
7
8
9
10
11
代码规范:
变量与方法使用尽量使用驼峰式命名,避免使用 $ 开头。
以 $ 开头的方法或者属性为框架内建方法或者属性,可以被使用,使用前请参考API文档。入口,页面,组件的命名后缀为.wpy。外链的文件可以是其它后缀。
请参考wpy文件说明使用 ES6 语法开发。
框架在 ES6 下开发,因此也需要使用 ES6 开发小程序,ES6中有大量的语法糖可以让我们的代码更加简洁高效。使用 Promise
框架默认对小程序提供的 API 全都进行了 Promise 处理,甚至可以直接使用 async/await 等新特性进行开发。
主要解决问题:
1. 开发模式转换
在原有的小程序的开发模式下进行再次封装,更贴近于现有 MVVM 框架开发模式。框架在开发过程中参考了一些现在框架的一些特性,并且融入其中,以下是使用 wepy 前后的代码对比图。
官方DEMO代码:
//index.js
//获取应用实例
var app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {}
},
//事件处理函数
bindViewTap: function() {
console.log('button clicked')
},
onLoad: function () {
console.log('onLoad')
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
基于 wepy 的实现:
import wepy from 'wepy';
export default class Index extends wepy.page {
data = {
motto: 'Hello World',
userInfo: {}
};
methods = {
bindViewTap () {
console.log('button clicked');
}
};
onLoad() {
console.log('onLoad');
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2. 支持组件化开发。
参见章节:组件
示例代码:
// index.wpy
<template>
<view>
<component id="pannel" path="pannel"></component>
<component id="counter1" path="counter"></component>
<component id="counter2" path="counter"></component>
<component id="list" path="list"></component>
</view>
</template>
<script>
import wepy from 'wepy';
import List from '../components/list';
import Panel from '../components/panel';
import Counter from '../components/counter';
export default class Index extends wepy.page {
config = {
"navigationBarTitleText": "test"
};
components = {
panel: Panel,
counter1: Counter,
counter2: Counter,
list: List
};
}
</script>
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
3. 单文件模式,使得目录结构更加清晰。
官方目录结构要求app必须有三个文件 app.json,app.js,app.wxss,页面有4个文件 index.json,index.js,index.wxml,index.wxss。而且文件必须同名。
所以使用wepy开发前后开发目录对比如下:
官方DEMO:
project
pages
index
index.json
index.js
index.wxml
index.wxss
log
log.json
log.wxml
log.js
log.wxss
app.js
app.json
app.wxss
2
3
4
5
6
7
8
9
10
11
12
13
14
15
使用wepy框架后目录结构:
project
src
pages
index.wpy
log.wpy
app.wpy
2
3
4
5
6
4. 默认使用 babel 编译,支持 ES6/7 的一些新特性。
用户可以通过修改 .wepyrc 配置文件,配置自己熟悉的babel环境进行开发。默认开启使用了一些新的特性如 promise,async/await 等等。
示例代码
import wepy from 'wepy';
export default class Index extends wepy.page {
getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({data: 123});
}, 3000);
});
};
async onLoad() {
let data = await this.getData();
console.log(data.data);
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
问题收集与解决
1. wepy 中使用 wx:if,只阻止视图渲染,不会阻止组件初始化。
2. 图片引入正常,但是无缘无故报错问题
原因:在于初始化的时候,变量还没渲染进去,导致src为错误的值。
解法:
<image wx:if="{{postData.avatar}}" class="avatar" src="{{postData.avatar}}"></image>
3. 微信小程序界面跳转传 json 对象,出现 object 对象变字串。
解法:
将 JSON 转成字符串传值 JSON.stringify(user);
将字符串转成对象接收 JSON.parse(options.userStr);
#传值 js (母页面)
personInfoAction: function(event) {
var user = this.data.user;
//将json转成字符串
let userStr=JSON.stringify(user);
console.log(user);
if(user) {
wx.navigateTo({
url: 'personInfo/index?userStr='+userStr,
success: function(res){
// success
},
})
} else {
wx.navigateTo({
url: 'login/index',
success: function(res){
// success
},
})
}
}
# 接收 js (目标页面)
onLoad: function(options) {
console.log(options);
//将字符串转成json
let user = JSON.parse(options.userStr);
console.log(user);
this.setData({
userListInfo: [
{
title: '头像',
subTitle: '',
icon:'../../../images/icon_img_tx.png',//user.avatar,
hasIcon:true
},{
title: '昵称',
subTitle: user.nickname,
icon:'',
hasIcon:false
}, {
title: '手机号',
subTitle: user.phone,
icon:'',
hasIcon:false
}, {
title: '实名认证',
subTitle: user.truename,
icon:'',
hasIcon:false
}]
});
}
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
4. this.$parent 更改没反应
需要多加
this.$parent.$apply();
5. component 可以使用 parent 的 usingComponents ,若是跳转的页面及无法。
6. 若 onLoad() 因为是组件在进画面时已被加载,可加入 this.$apply() 帮助进画面时重新渲染
7. 微信小程序的网络请求必须走 Https 协议,就是说微信小程序一定要通过 HTTPS 加密。
8. page 呼叫 global => this.$parent;
9. page里的子组件呼叫 global => this.$root.$parent;
10. 价钱的加减乘除会有出现浮点数,如 12.0000000000001
解法: 浮点数计算 bug JavaScript 数字前补“0”的五种方法
11. 如何让小程序有类似 cookie 功能
解法:
仿 cookie
12. 抓取 目标 DOM
that.$apply();
var query = wx.createSelectorQuery();
query.select('.aslide-item-info').boundingClientRect();
query.exec(function(res) {
console.log(res);
that.boxHeight = res[0].height;
});
2
3
4
5
6
7
13. textarea 高度永远最高,且卷动时会出现异常,此部份尚无解,仅能用条件判断避开
解法:
textarea 坑
当前小程序作法:
- 上方有物件时,让文字区块隐藏,如优惠券浮窗
- 卷动时文字停留 bug ,做一个伪文字区块(以 view 模拟),编辑时点击伪文字区块,换成 该 textarea,unfocus 或卷动视窗时,又切回伪文字区块,并将编辑内容放入。
mpvue
目录结构
project-name
┣ build // webpack 配置
┣ config // html 2 wxml, wxss 2 css 等配置
┣ dist // 输出小程序用的 wxml 等文件
┣ node_modules
┣ src
┃ ┣ components // 组件
┃ ┣ assets // 图片
┃ ┣ pages // 页面
┃ ┃ ┣ counter // vuex 示例
┃ ┃ ┃ ┣ index.vue
┃ ┃ ┃ ┣ main.js
┃ ┃ ┃ ┗ store.js
┃ ┃ ┣ index // 普通示例页面
┃ ┃ ┃ ┣ index.vue
┃ ┃ ┃ ┗ main.js
┃ ┃ ┗ logs // 普通示例页面
┃ ┃ ┃ ┣ index.vue
┃ ┃ ┃ ┣ main.js
┃ ┃ ┃ ┗ main.json
┃ ┣ styles // stylus 基础文件
┃ ┃ ┣ base.styl // 全局公共 class
┃ ┃ ┣ iconfont.styl // 字体图标
┃ ┃ ┣ reset.styl // 重置默认样式
┃ ┃ ┗ variable.styl // 样式变量
┃ ┣ utils
┃ ┃ ┣ index.js
┃ ┃ ┣ request.js // wx.request 二次封装
┃ ┃ ┣ static.js // 静态变量配置
┃ ┃ ┗ toast.js // 简化 wx 弹框
┃ ┣ app.json // 页面配置
┃ ┣ App.vue // 全局入口文件
┃ ┗ main.js
┣ static
┣ tes
┃ ┣ e2e
┃ ┣ unit
┃ ┗ mock // mock 数据
┣ .editorconfig
┣ .eslintignore
┣ .eslintrc.js
┣ .gitignore
┣ index.html
┣ package.json
┣ package.swan.json
┣ project.config.json
┗ README.md
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
特性
以 mpvue 为基础架构,支持 vue 的大部分功能. 开发上与 vue 有少许差异,参考 mpvue使用手册.
极速开发体验
渲染一个列表只需要几行熟悉的代码
<template lang="pug">
div.container
div(v-for="(item,i) in list" :key="i")
span {{item.name}}
</template>
mounted () {
const result = await this.$get('api/list');
this.list = result;
}
<style lang="stylus">
$mainColor = #ababab
.container
color $mainColor
div
border 1rpx solid $mainColor
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19