小程序wepy.js框架总结
wepy.js借鉴了Vue的语法风格和功能特性,对官方提供的框架进行了封装,更贴近于MVVM架构模式,让开发者更加容易上手,增加开发效率。(脏数据处理--是否有标识、是否有响应)
前端开发的对组件化开发应该都都很熟悉,我们就讲精华的部分:
首先我们需要输入下面的命令:
npm install wepy-cli -g // 全局安装或更新WePY命令行工具
wepy new myproject // 在开发目录中生成Demo开发项目
cd myproject // 切换至项目目录
npm install // 安装依赖
wepy build --watch // 开启实时编译
完成上面的命令后,你会看到类似下面的目录结构(部分文件夹是本人自己的项目业务需要,学习不需要理会):
目录讲解:
--dis
文件夹是微信开发者工具指定的目录(该目录由WePY的build指令自动编译生成,请不要直接修改该目录下的文件)
--src
代码编写的目录(该目录为使用WePY后的开发目录)
--components
wepy组件目录(组件不属于完整页面,仅供完整页面或其他组件引用)
--pages
wepy页面目录(属于完整页面)
--app.wpy
小程序逻辑、公共配置、公共样式
--package.json
项目的package配置
wepy官方文档有五个重要的提示,我们要跟着规则做,不要给自己挖坑。
使用
微信开发者工具
-->添加项目
,项目目录
请选择dist
目录。微信开发者工具
-->项目
-->关闭ES6转ES5
。 重要:漏掉此项会运行报错。微信开发者工具
-->项目
-->关闭上传代码时样式自动补全
。 重要:某些情况下漏掉此项也会运行报错。微信开发者工具
-->项目
-->关闭代码压缩上传
。 重要:开启后,会导致真机computed, props.sync 等等属性失效。(注:压缩功能可使用WePY提供的build指令代替,详见后文相关介绍以及Demo项目根目录中的wepy.config.js
和package.json
文件。)本地项目根目录运行
wepy build --watch
,开启实时编译。(注:如果同时在微信开发者工具
-->设置
-->编辑器
中勾选了文件保存时自动编译小程序
,将可以实时预览,非常方便。)
用于开发的编辑器,个人喜欢vs code。开发者可以根据自己熟悉的编辑器(微信开发者工具
仅用于实时预览和调试)。
- VS Code
1. 在 Code 里先安装 Vue 的语法高亮插件 Vetur
。
2. 打开任意 .wpy
文件。
3. 点击右下角的选择语言模式,默认为纯文本
。
4. 在弹出的窗口中选择 .wpy 的配置文件关联...
。
5. 在选择要与 .wpy 关联的语言模式
中选择 Vue
。
wepy官方提供了一些代码规范的规则,这里我列出重要的几条:
1.变量与方法尽量使用驼峰式命名,并且注意避免使用$
开头。
2.事件绑定语法使用优化语法代替。
* 原 bindtap="click"
替换为 @tap="click"
,原catchtap="click"
替换为@tap.stop="click"
。
* 原 capture-bind:tap="click"
替换为 @tap.capture="click"
,原capture-catch:tap="click"
替换为@tap.capture.stop="click"
。
3.事件传参使用优化后语法代替。 原bindtap="click" data-index={{index}}
替换为@tap="click({{index}})"
。
4.自定义组件命名应避开微信原生组件名称以及功能标签<repeat>
。 不可以使用input、button、view、repeat
等微信小程序原生组件名称命名自定义组件;另外也不要使用WePY框架定义的辅助标签repeat
命名。
基于WePY的代码:
export default class Catalog extends wepy.page //通过继承自wepy.page的类创建页面逻辑
methods //事件处理函数(集中保存在methods对象中)
components //支持组件化开发如下图
注意:WePY中,在父组件template
模板部分插入驼峰式命名的子组件标签时,不能将驼峰式命名转换成短横杆式命名(比如将childCom
转换成child-com
),这与Vue中的习惯是不一致。
wepy基于原生进行优化:
(使用原生同时最多只能发起5个请求,使用wepy后没有了这个限制)
import wepy from 'wepy'; async onLoad() {
await wepy.login();
this.userInfo = await wepy.getUserInfo();
}
一个.wpy
文件可分为三大部分,各自对应于一个标签:
- 脚本部分,即
<script></script>
标签中的内容,又可分为两个部分:
逻辑部分,除了config对象之外的部分,对应于原生的.js
文件;
配置部分,即config对象,对应于原生的.json
文件。
结构部分,即
<template></template>
模板部分,对应于原生的.wxml
文件。样式部分,即
<style></style>
样式部分,对应于原生的.wxss
文件。
其中,小程序入口文件app.wpy
不需要template
,所以编译时会被忽略。.wpy
文件中的script
、template
、style
这三个标签都支持lang
和src
属性,lang
决定了其代码编译过程,src
决定是否外联代码,存在src
属性且有效时,会忽略内联代码。
代码如下
<style lang="less" src="page1.less"></style>
<template lang="wxml" src="page1.wxml"></template>
<script>
// some code
</script>
各标签对应的lang
值如下表所示:
标签 | lang默认值 | lang支持值 |
---|---|---|
style | css |
css 、less 、scss 、stylus |
template | wxml |
wxml 、xml 、pug(原jade) |
script | babel |
babel 、TypeScript |
下面具体对脚本进行讲解,
小程序的入口是app.wpy
<script>
import wepy from 'wepy';
export default class extends wepy.app {
config = {
"pages":[
"pages/index/index"
],
"window":{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "black"
}
};
onLaunch() {
console.log(this);
}
}
</script> <style lang="less">
/** less **/
</style>
入口文件app.wpy
中所声明的小程序实例继承自wepy.app
类,包含一个config
属性和其它全局属性、方法、事件。其中config
属性对应原生的app.json
文件,build编译时会根据config
属性自动生成app.json
文件,如果需要修改config
中的内容,请使用微信提供的相关API。
页面page.wpy
<script>
import wepy from 'wepy';
import Counter from '../components/counter'; export default class Page extends wepy.page {
config = {};
components = {counter1: Counter}; data = {};
methods = {}; events = {};
onLoad() {};
// Other properties
}
</script> <template lang="wxml">
<view>
</view>
<counter1></counter1>
</template> <style lang="less">
/** less **/
</style>
页面文件page.wpy
中所声明的页面实例继承自wepy.page
类,该类的主要属性介绍如下:
属性 | 说明 |
---|---|
config | 页面配置对象,对应于原生的page.json 文件,类似于app.wpy 中的config |
components | 页面组件列表对象,声明页面所引入的组件列表 |
data | 页面渲染数据对象,存放可用于页面模板绑定的渲染数据 |
methods | wxml事件处理函数对象,存放响应wxml中所捕获到的事件的函数,如bindtap 、bindchange |
events | WePY组件事件处理函数对象,存放响应组件之间通过$broadcast 、$emit 、$invoke 所传递的事件的函数 |
其它 | 小程序页面生命周期函数,如onLoad 、onReady 等,以及其它自定义的方法与属性 |
组件com.wpy
<template lang="wxml">
<view> </view>
</template> <script>
import wepy from 'wepy';
export default class Com extends wepy.component {
components = {}; data = {};
methods = {}; events = {};
// Other properties
}
</script> <style lang="less">
/** less **/
</style>
组件文件com.wpy
中所声明的组件实例继承自wepy.component
类,除了不需要config
配置以及页面特有的一些生命周期函数之外,其属性与页面属性大致相同。
通过上面的总结,我们可以知道,小程序被分成三个实例:小程序实例App
、页面实例Page
、组件实例Component
import wepy from 'wepy'; // 声明一个App小程序实例
export default class MyAPP extends wepy.app {
} // 声明一个Page页面实例
export default class IndexPage extends wepy.page {
} // 声明一个Component组件实例
export default class MyComponent extends wepy.component {
}
App小程序实例中主要包含小程序生命周期函数、config配置对象、globalData全局数据对象,以及其他自定义方法与属性。
在Page页面实例中,可以通过this.$parent
来访问App实例。
Page页面实际上继承自Component组件,即Page也是组件。除扩展了页面所特有的config
配置以及特有的页面生命周期函数之外,其它属性和方法与Component一致,因此这里以Page页面为例进行介绍。
注意,对于WePY中的methods属性,因为与Vue中的使用习惯不一致,非常容易造成误解,这里需要特别强调一下:WePY中的methods属性只能声明页面wxml标签的bind、catch事件,不能声明自定义方法,这与Vue中的用法是不一致的。示例如下:
import wepy from 'wepy';
export default class MyComponent extends wepy.component {
methods = {
bindtap () {
let rst = this.commonFunc();
// doSomething
},
bindinput () {
let rst = this.commonFunc();
// doSomething
},
}
//正确:普通自定义方法在methods对象外声明,与methods平级
customFunction () {
return 'sth.';
}
}
需要特别注意的一点:当需要循环渲染WePY组件时(类似于通过wx:for
循环渲染原生的wxml标签),必须使用WePY定义的辅助标签<repeat>
,代码如下:
<template>
<!-- 注意,使用for属性,而不是使用wx:for属性 -->
<repeat for="{{list}}" key="index" index="index" item="item">
<!-- 插入<script>脚本部分所声明的child组件,同时传入item -->
<child :item="item"></child>
</repeat>
</template>
computed计算属性、watcher监听器跟VUE很相似。
// computed
data = {
a:
}
// 计算属性aPlus,在脚本中可通过this.aPlus来引用,在模板中可通过{{ aPlus }}来插值
computed = {
aPlus () {
return this.a +
}
} // wathcer
data = {
num:
}
// 监听器函数名必须跟需要被监听的data对象中的属性num同名,
// 其参数中的newValue为属性改变后的新值,oldValue为改变前的旧值
watch = {
num (newValue, oldValue) {
console.log(`num value: ${oldValue} -> ${newValue}`)
}
} // 每当被监听的属性num改变一次,对应的同名监听器函数num()就被自动调用执行一次
onLoad () {
setInterval(() => {
this.num++;
this.$apply();
}, )
}
Props传值:
props传值在WePY中属于父子组件之间传值的一种机制,包括静态传值与动态传值。
在props对象中声明需要传递的值,静态传值与动态传值的声明略有不同,具体可参看下面的示例代码。
静态传值
静态传值为父组件向子组件传递常量数据,因此只能传递String字符串类型。
在父组件template
模板部分的组件标签中,使用子组件props对象中所声明的属性名作为其属性名来接收父组件传递的值。
<child title="mytitle"></child>
// child.wpy
props = {
title: String
};
onLoad () {
console.log(this.title); // mytitle
}
动态传值
动态传值是指父组件向子组件传递动态数据内容,父子组件数据完全独立互不干扰。但可以通过使用.sync
修饰符来达到父组件数据绑定至子组件的效果,也可以通过设置子组件props的twoWay: true
来达到子组件数据绑定至父组件的效果。那如果既使用.sync
修饰符,同时子组件props
中添加的twoWay: true
时,就可以实现数据的双向绑定了。
注意:下文示例中的twoWay
为true
时,表示子组件向父组件单向动态传值,而twoWay
为false
(默认值,可不写)时,则表示子组件不向父组件传值。这是与Vue不一致的地方,而这里之所以仍然使用twoWay
,只是为了尽可能保持与Vue在标识符命名上的一致性。
在父组件template
模板部分所插入的子组件标签中,使用:prop
属性(等价于Vue中的v-bind:prop
属性)来进行动态传值。
// parent.wpy <child :title="parentTitle" :syncTitle.sync="parentTitle" :twoWayTitle="parentTitle"></child> data = {
parentTitle: 'p-title'
}; // child.wpy props = {
// 静态传值
title: String, // 父向子单向动态传值
syncTitle: {
type: String,
default: 'null'
}, twoWayTitle: {
type: Number,
default: 'nothing',
twoWay: true
}
}; onLoad () {
console.log(this.title); // p-title
console.log(this.syncTitle); // p-title
console.log(this.twoWayTitle); // p-title this.title = 'c-title';
console.log(this.$parent.parentTitle); // p-title.
this.twoWayTitle = 'two-way-title';
this.$apply();
console.log(this.$parent.parentTitle); // two-way-title. --- twoWay为true时,子组件props中的属性值改变时,会同时改变父组件对应的值
this.$parent.parentTitle = 'p-title-changed';
this.$parent.$apply();
console.log(this.title); // 'c-title';
console.log(this.syncTitle); // 'p-title-changed' --- 有.sync修饰符的props属性值,当在父组件中改变时,会同时改变子组件对应的值。
}
组件之间的通信:
wepy.component
基类提供$broadcast
、$emit
、$invoke
三个方法用于组件之间的通信和交互,如:
this.$emit('some-event', , , , );
import wepy from 'wepy' export default class Com extends wepy.component {
components = {}; data = {}; methods = {}; // events对象中所声明的函数为用于监听组件之间的通信与交互事件的事件处理函数
events = {
'some-event': (p1, p2, p3, $event) => {
console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`);
}
};
// Other properties
}
$broadcast
事件是由父组件发起,所有子组件都会收到此广播事件,除非事件被手动取消。
$emit
与$broadcast
正好相反,事件发起组件的所有祖先组件会依次接收到$emit
事件。
$invoke
是一个页面或组件对另一个组件中的方法的直接调用,通过传入组件路径找到相应的组件,然后再调用其方法。
组件自定义事件处理:
可以通过使用.user
修饰符为自定义组件绑定事件,如:@customEvent.user="myFn"
其中,@
表示事件修饰符,customEvent
表示事件名称,.user
表示事件后缀。
目前总共有三种事件后缀:
.default
: 绑定小程序冒泡型事件,如bindtap
,.default
后缀可省略不写;.stop
: 绑定小程序捕获型事件,如catchtap
;.user
: 绑定用户自定义组件事件,通过$emit
触发。注意,如果用了自定义事件,则events中对应的监听函数不会再执行。
// index.wpy <template>
<child @childFn.user="parentFn"></child>
</template> <script>
import wepy from 'wepy'
import Child from '../components/child' export default class Index extends wepy.page {
components = {
child: Child
} methods = {
parentFn (num, evt) {
console.log('parent received emit event, number is: ' + num)
}
}
}
</script> // child.wpy <template>
<view @tap="tap">Click me</view>
</template> <script>
import wepy from 'wepy' export default class Child extends wepy.component {
methods = {
tap () {
console.log('child is clicked')
this.$emit('childFn', )
}
}
}
</script>
当然,所有人写的总结都是基于自己的理解的,因此,个人觉得无论学什么技术,当自己有一定能力可以阅读官方文档后,最好自己把官方的文档都看一遍,只有这样自己的该门技术才有深入的理解。
官方文档地址:https://tencent.github.io/wepy/document.html#/?id=api
如果你阅读到这里了,说明你是个有追求的人,本人额外附送两个链接
https://github.com/hjkcai/wepy-plugin-axios
https://github.com/youzan/zanui-weapp
小程序wepy.js框架总结的更多相关文章
- 用Vue.js开发微信小程序:开源框架mpvue解析
前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...
- 小程序组件化框架 WePY 在性能调优上做出的探究
作者:龚澄 导语 性能调优是一个亘古不变的话题,无论是在传统H5上还是小程序中.因为实现机制不同,可能导致传统H5中的某些优化方式在小程序上并不适用.因此必须另开辟蹊径找出适合小程序的调估方式. 本文 ...
- 小程序--wepy省市区三级联动选择
产品老哥对项目再一次进行关爱, 新增页面, 新增需求, 很完美........ 不多说, 记录一下新增东西中的省市区联动选择, (这里全国地区信息是在本地, 但不建议这么做, 因为js文件太大.. 建 ...
- 快速上手小程序的mpvue框架
一.什么是mpvue框架? mpvue 是一个使用 Vue.js 开发小程序的前端框架.框架基于 Vue.js 核心(所以建议熟练掌握vue再使用mpvue框架,否则还是建议去使用原生框架去写小程序) ...
- 在微信小程序的JS脚本中使用Promise来优化函数处理
在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入 ...
- 微信小程序wepy开发循环wx:for需要注意
微信小程序wepy开发循环wx:for需要注意 item index值必须在wx:for之后使用 <view wx:for="{{tablist}}" class=" ...
- 微信小程序:JS 交互逻辑
微信小程序:JS 交互逻辑 一.JS 交互逻辑 一个服务仅仅只有界面展示是不够的,还需要和用户做交互:响应用户的点击.获取用户的位置等等.在小程序里边,我们就通过编写 JS 脚本文件来处理用户的操作. ...
- 小程序app.js小结
小程序app.js app.js import { ApiUrl } from 'utils/apiurl.js'; import { httpReq } from 'utils/http.js'; ...
- 使用Vue开发微信小程序:mpvue框架
使用Vue开发微信小程序:mpvue框架:https://www.jianshu.com/p/8f779950bfd9
随机推荐
- C++_调用约束
1.要求 声明定义处调用约定必须相同 int __stdcall add(int a, int b); int __stdcall add(int a, int b) { return a + b; ...
- 一个tomcat部署多个应用实例
安装JDK7sudo apt-get install java7-jdk 安装tomcat7 Tomcat7下载地址http://mirror.bjtu.edu.cn/apache/tomcat/to ...
- 《Java大学教程》—第9章 软件质量
软件质量:可维护性.可靠性.健壮性.可用性. 9.3 可维护性系统维护(maintaining)是指根据需求的变化更新现有系统的过程 9.3.1 封装的重要性连锁反应:对系统某一部分的改变可能会 ...
- 【汤鸿鑫 3D太极】5年目标规划(基本功、套路、实战搏击)
[5年目标]在基本功的基础上,每年完成一个套路或实战搏击的学习研究. [中小学2年]三段九节 + 2套路. [高中的3年]太极十三势 + 1套路 + 推手 + 搏击. 1.中小学阶段-可自学 (1)基 ...
- 用js检测文本框中输入的是否符合条件并有错误和正确提醒
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- android studio 定位具体的错误原因
编译一个数据监测APP的时候出现了报错: Error:Compilation failed; see the compiler error output for details. 在网上查到方法如下: ...
- Java8时间的简单时间
package com.java8.date; import org.junit.Test; import java.text.SimpleDateFormat; import java.time.* ...
- P1182 数列分段`Section II`(贪心+二分, 好题)
这道题让我见识了二分的新姿势.本来,我是二分的位置的. 思路:直接二分答案x, 关键是检验函数的写法: 先用前缀和 a[i....], 看满足多少段满足 a[ j ]-a[ i ]<=x; 的注 ...
- (五)JavaScript 变量
JavaScript 变量 与代数一样,JavaScript 变量可用于存放值(比如 x=5)和表达式(比如 z=x+y). 变量可以使用短名称(比如 x 和 y),也可以使用描述性更好的名称(比如 ...
- Python框架学习之Flask中的视图及路由
在前面一讲中我们学习如何创建一个简单的Flask项目,并做了一些简单的分析.接下来在这一节中就主要来讲讲Flask中最核心的内容之一:Werkzeug工具箱.Werkzeug是一个遵循WSGI协议的P ...