前言#
上次体验了一下小程序开发,用的是小程序原生语法来开发。虽然体验了一把原汁原味的小程序开发,但是发现现在版本的小程序原生语法还是比较繁杂的,不够灵活。比如单单页面就由 4 个文件组成,还有组件上不支持脚本等等。在现在 MVVM 框架盛行的年代,可以使用尝试使用框架来开发小程序。
本篇文章基于 WePy v1.7.2-alpha1
补充说明:原生小程序开发并不会比使用框架开发效率低,而且原生开发没有那么多的 BUG,这个主要看开发者的熟练水平!
选择框架#
网上查了下,微信小程序现在已经有不少开发框架,比如 WePy,Tina,MpVue 等等。选择哪个比较好呢?
最后我选择的是 WePy! 为什么呢?
- WePy 是微信官方腾讯公司的前端团队开发的一款小程序开发框架,应该会和小程序开发很搭配(后来才发现主力开发也就是一个人,一开始不是他并不是 Tencent 团队的,后面被招进来了)。
- WePy 在小程序公测的时候就开源了,现在已经到 1.7.1 版本了,听说马上出 2.0 版本了,算是比较成熟稳定的框架了。(其实比起原生, BUG 还是挺多的)
- WePy 借鉴了三大前端 MVVM 框架 Vue 的语法分格和功能特性,正好我也比较熟悉 Vue。(后来发现还不如直接使用 Vue 语法)
所以,没错!就是 WePy 了。
主要特点#
看了 WePy 的文档,发现 WePy 还是很强大的,和 Vue 的语法风格和功能特性,非常适合 Vue 开发者。 其中,有几个特性个人非常喜欢。
- 和 Vue 一样的语法风格和功能特性,更贴近 MVVM 架构模式。
- 支持 Sass/Scss,Less,Stylus 等 CSS 预处理器。(个人比较喜欢简洁风格的 Stylus 预处理器)。
- 单文件模式,和 Vue 的
.vue文件一样,把结构、样式、脚本都放在一个.wpy 文件里,使得目录结构非常清晰、简便。 - 支持加载外部的 NPM 包,也就是说可以使用第三方库了。
- 支持 ES6/7 的新特性,比如
Promise、Async/Await,处理异步很方便。 - 支持页面和组件间通信,不但数据可以双向传值,还可以进行事件派发。
其实,WePy 还有很多好的特性,比如支持 ESLink 规则等等, 详见WePy 官方文档。总之,WePy 对 Vue 开发者真的是非常友好。
使用流程#
- 安装 WePy 命令行工具
npm install wepy-cli -g- 创建项目
wepy init standard wepy-demo- 安装依赖
cd wepy-demo
npm install- 开启实时编译
wepy build --watch- 如果使用 Stylus 预处理器,需要配置 Stylus 编译(默认已经配置好了 Less 和 Sass/Scss 预处理器)
npm install wepy-compiler-stylus --save-dev// wepy.config.js
module.exports = {
compilers: {
stylus: {
compress: true,
},
},
};项目结构解析#
主要分析其中四个部分
-
dist:小程序运行目录,由 WePy 框架编译源文件生成,不要直接修改这个目录的代码。
-
src:代码源文件,自动生成分为三个部分:pages 目录、components 目录、
app.js。- pages 目录:小程序的页面目录,存放小程序的页面,继承
wepy.page类。 - components 目录: 小程序的组件目录,存放小程序的组件,继承
wepy.component类。 - app.js:小程序的配置文件,比如全局变量,全局样式,声明钩子等,继承的是
wepy.app类。 - 其他的自定义目录。比如存在工具类方法的 utils,混合 mixins,存放图片文件的目录 images 等。
- pages 目录:小程序的页面目录,存放小程序的页面,继承
3.package.json:项目的 package 管理文件。 4.wepy.config.js:框架的配置文件,比如配置 Stylus 编译就在这里配置。
wpy 文件解析#
.wpy文件结构和.vue文件一样,分为三个部分,主要由三个标签组成,分别是template、style和script。
<style lang="stylus" src="page1.styl">
/* 编写样式, 对应原生的.wxss, 支持lang和src属性, lang默认为css,支持less,sass,stylus, postcss */
</style>
<template>
<!--编写结构, 对应原生的.wxml文件, 支持lang和src属性, lang默认为wxml,支持xml,pug -->
</template>
<script>
// 编写脚本, 对应原生的.js文件和json文件, 支持lang和src属性, lang默认为babel,支持TypeScript
</script>其中,在script可以配置对应原生小程序的 json 文件,在script标签里面继承的类的config属性中配置,其他的代码为 js 文件的逻辑部分。
export default class Index extends wepy.page {
config = {
navigationBarTitleText: "小小休闲",
navigationBarBackgroundColor: "#b3d4db",
};
methods = {
onTap() {
wepy.switchTab({
url: "../../pages/posts/posts",
});
},
};
}异同点#
在这里,只列举自己使用时遇到的部分异同点,分别和小程序原生语法和 Vue 语法进行比较,这部分应该不全,详情请查看官方文档。
-
事件绑定
- 原生:
bindtap。WePy:@tap。 Vue:@click。 - 原生:
catchtap。 WePy:@tap.stop。 Vue:@click.stop。
- 原生:
-
循环渲染
- 原生
<block wx:for="{{list}}" wx:for-item="itemName" wx:key="keyName"></block>- WePy
<repeat for="/{{list}}/" item="itemName" key="keyName"></repeat>- Vue
<div v-for="itemName in list" :key="keyName"></div> -
页面和组件传值:
- 原生:
data属性。 - WePy:
props,动态传值需要加上.sync后缀,支持双向传值, 组件可以改变页面的值。 - Vue:
Props,2.3 以后重新支持双向传值。
- 原生:
-
组件向页面派发事件:
- 原生:不支持。
- WePy:
this.$emit(),传递的事件需要加上.user后缀。 - Vue:
this.$emit(),不需要加后缀。
-
调用全局 api:
- 原生:
wx:xxx。 - WePy:
wepy:xxx&this.$xxx、this.xxx。 - Vue:
Vue.xxx&this.$xxx。
- 原生:
-
指令
- 原生:
wx:xxx。 - WePy:
wx:xxx部分省略wx, 比如在<repeat>循环标签时使用for不是wx:for。 - Vue:
v-xxx部分省略v-, 比如ref等。
- 原生:
-
方法
- 原生:放在
page里面。 - WePy:放在继承的
Page类里面,特定的方法必须放在methods属性里面,即methods={method}。比如页面接收的派发事件,组件的事件绑定等。 - Vue:方法全部放在
methods里面。
- 原生:放在
-
存取 data 属性
- 原生
// 保存 data 数据 this.setData({ title: "home", }); // 获取 data 数据 const title = this.data.title;- WePy
// 保存 data 数据 this.title = "home"; // 获取 data 数据 const title = this.title;- Vue
// 保存 data 数据 this.title = "home"; // 获取 data 数据 const title = this.title; -
存取全局变量
- 原生
// 保存全局变量 const app = getApp(); app.globalData.isPlaying = true; // 获取全局变量 const isPlaying = app.globalData.isPlaying;- WePy
// 保存全局变量 this.$parent.globalData.isPlaying = true; // 获取全局变量 const isPlaying = this.$parent.globalData.isPlaying;- Vue:自定义全局变量或者使用 Vuex 状态管理器。
注意事项#
-
使用 WePy 框架开发小程序时,需要关闭开发者工具中的“ES6 转 ES5”、“上传代码是样式自动补全”、“上传代码时自动压缩”这几个选项。或者在
project.config.json设置成false也可以,不然会莫名其妙的报错。 -
开发中遇到的一个 BUG:就是用
<repeat>循环传入子组件的值,无法再传入给孙组件。从 Issue 中查了下,很多人都遇到了这个问题,维护人员说 2.0 版本才会解决这个 Bug,现在版本解决的办法是下载最新的 v1.7.2-alpha1 版本,然后导入组件时再变量上加@,再用原生的<block>和wx:for来传值,不过试了下,貌似没有效果。
总结#
代码可参考:
第一次使用 WePy 框架开发小程序难免会出现很多问题,文章中不足之处还请见谅。