小程序原生语法工程化

前言

关于微信小程序的工程化处理,如果像是选择mpvuewepy等框架,项目其实就是按照一般的vue项目进行处理,只不过基于一般的vue项目多了一层转编译成原生小程序代码;

但如果直接使用原生语法来搭建小程序项目,那么该如何进行一些工程化的处理呢?不可能是完全地一个个页面独立地手写,这样效率太低了。

组件

组件的创建

小程序本身就提供了组件的语法,首先需要对.json文件做一个声明:

1
2
3
{
"component": true
}

而视图(wxml)和样式(wxss)则和一般页面的写法是一样的。主要的区别就是逻辑文件(js)的写法,声明组件需要使用Component()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod: function(){}
}
})

properties是用来声明组件的自定义属性的,可以在wxml中当做data来使用;实际上就是用来进行传递父级数据的。需要注意的是组件的生命周期和页面的生命周期有所不同,组件还能监听到所在页面(Page)的一些生命周期,详情可以查看官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html

组件的使用

总所周知,组件有全局组件和局部组件,小程序组件也一样;如果是全局组件,则声明在app.json文件中,如果只是局部组件(单独使用),则可以在页面对应的json文件中进行声明,语法如下:

1
2
3
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}

usingComponents就是声明使用组件的地方,键名就是组件的标签名,键值就是组件的路径。

mixin

导出语法只能是CommonJS?

小程序为原生组件也提供了一套类似混合(mixin)的语法,叫做behaviors;用独立的js文件编写,然后引入到相应的组件文件(js)中即可。语法大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// my-behavior.js
module.exports = Behavior({
behaviors: [],
properties: {
myBehaviorProperty: {
type: String
}
},
data: {
myBehaviorData: {}
},
attached: function(){},
methods: {
myBehaviorMethod: function(){}
}
})

其作用就是复用组件之间的自定义属性、方法、数据等等。

使用 behaviors

使用的语法跟vuemixin的使用类似,在组件的behaviors属性中添加相应的behavior文件即可;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// my-component.js
var myBehavior = require('my-behavior')
Component({
behaviors: [myBehavior],
properties: {
myProperty: {
type: String
}
},
data: {
myData: {}
},
attached: function(){},
methods: {
myMethod: function(){}
}
})

WXS

语法限制

由于小程序本身语法的限制,导致在wxml的模板语法中并不能使用自定义方法,但是wxs定义的方法却能够在模板语法中使用,这样就能解决不能使用方法来处理模板语法中数据的问题了。

wxs是小程序自定义的一套脚本语言,实际上就是基于ES5进行的一些改造,不过有些原生对象做了限制,如Date对象。因此,在wxs中并不能使用ES6及以上语法,且模块语法为CommonJS!举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}

module.exports = {
getMax: getMax
};

由于习惯了ES6以上的语法,所以写wxs的时候务必注意

  • 不能使用let、箭头函数和模板字符串等语法
  • 导出只能通过module.exports对象

创建和使用

wxs既可以在wxml中进行声明,然后直接使用;也可以写在独立的.wxs文件中,然后引入到相应的wxml中进行使用。需要注意的是,不管是哪种方式,wxs里面的方法和数据都要进行导出之后才能进行使用!

wxml文件内

wxml中则通过在<wxs>标签中声明wxs语法,然后通过module属性来指定该模块的名称,然后在wxml中进行使用即可;

1
2
3
4
5
6
7
8
9
10
<wxs module="demo">
function hello (text) {
return 'hello, ' + text
}

module.exports = {
hello: hello
}
</wxs>
<text>{{demo.hello(name)}}</text>

独立的wxs文件

声明类似,只不过是把wxs代码写在单独的.wxs文件中而已:

1
2
3
4
5
6
7
8
// demo.wxs
function hello (text) {
return 'hello, ' + text
}

module.exports = {
hello: hello
}

然后通过<wxs>标签进行引入:

1
2
<wxs src="path/to/demo.wxs" module="demo"></wxs>
<text>{{demo.hello(name)}}</text>

通过<wxs>src属性来指定.wxs文件的位置;

其他注意事项

  • .wxs.js文件不能互相引入.wxs只能引入.wxs文件!
  • 使用require()函数引入.wxs文件时,只能使用相对路径!

npm包的使用

这个流程官方文档就已经说的很清楚了,不再赘述了。

后话

虽说微信小程序为原生语法工程化提供了配套的语法和设施,但是很显然,同诸如vue + webpack等成熟的前端工程化配套而言,像是一个『拙劣的模仿者』,也只能是凑合着用了。

相关文档