前言
最近接手了一个项目,是用小程序原生去开发,虽然小程序入手容易,但是其中坑巨多,以下是最近在开发时踩过的坑,花了较多时间解决,为避免更多人遇到时手足无措,特此记录。同时,在这里还总结了vue转换为小程序写法的一些知识点。
一、关于WXML
1、小程序中用来表示页面结构的文件是WXML,这是小程序自己的页面,因此原先vue中的标签在小程序这里就不能用了,得用小程序自己的标签,一般来说,vue中用到最多的标签就是div和span了,在小程序中分别对应view和text,即
div ---> view
span ---> text
img ---> image
2、vue中可以用v-html指令来动态渲染任意的HTML,而在小程序中没有对应的指令,但是我们可以用小程序中自带的rich-text标签来实现对应的功能。如下图:
3、vue中的指令对应小程序中的指令:
v-if ---> wx:if
v-else ---> wx:else
v-for ---> wx:for(小程序中默认循环的每一项名为item,索引为index
v-show ---> hidden
4、vue中动态绑定的class可以写成数组形式:[条件?'类名1': '类名2'],或对象形式:{类名:条件},但是小程序中只能写成:class="{{条件? '类名1': '类名2'}}"
5、在vue中,一个标签是可以同时写静态类名和动态类名的,例如
<div class="demo" :class="{'font32': true}">
你好,世界
</div>
但是,在小程序中,一个标签是不允许同时写多个class的,否则该标签中后面的类名将覆盖前面的类名,例如:
//错误示范×,渲染后只有demo类
<view class="{{1 === 1 ? 'font32' : ''}}" class="demo" >你好,世界</view>
这个时候,你只能将静态和动态都写在一个class上,然后多个类名之间用空格隔开,例如:
<view class="demo {{1 === 1 ? 'font32' : ''}}" >你好,世界</view>
6、小程序中的具名插槽渲染节点有问题,slot的内容没有放在指定的位置上面,而是像appendChild那样插在对应位置节点的后面。看代码:
// 首先我定义了一个子组件son
<view class="demo-wrap">
<view>你好</view>
<slot name="demo"></slot>
</view>
// 接着在父组件中引入son组件
<view class="main">
<son>
<view slot="demo">世界</view>
</son>
</view>
渲染后:
看出问题了吗?本来<view>世界</view>
这个标签应该是要插在类名为demo-wrap
标签里的,结果小程序却把它插在了与它同级的下一个节点里,这个是小程序的bug,到现在官方还没解决。。。
7、小程序WXML文件中是不能写反引号``来拼接字符串的,要想拼接,只能通过加号+。
二、关于WXSS
WXSS是小程序中用来展示样式的文件格式
1、小程序中的单位有两种:px和rpx,具体单位的转换可以看微信官方文档。
2、一般情况下我们不会直接在WXSS上写样式,就像我们不会直接写css一样,而是写less或scss,然后用插件将less或scss转换为css,微信官方其实也有关于less的配置,但是这里推荐另一种方式,感觉用起来超超超爽!操作步骤如下:
① vscode中下载Easy Less插件,并在setting文件中配置
// 对EasyLess的配置,此段配置去掉则默认生成一个css文件
"less.compile": {
"compress": false, //是否压缩
"sourceMap": false, //是否生成map文件
"out": true, // 是否输出文件,false为不输出
"outExt": ".wxss", // 输出文件的后缀,小程序可以写'wxss'
},
②、新建一个***.less文件,保存后就在对应目录下自动生成了wxss文件了。Done!
三、关于JSON文件
小程序中,一个页面或一个自定义组件,由四个文件组成,分别是:js,wxml,json,wxss,为了方便开发者减少配置项,描述页面或组件的四个文件必须具有相同的路径与文件名。
1、这里的json文件,其实是对于页面或组件的一些配置。要编写一个自定义组件,首先需要在 json
文件中进行自定义组件声明(即:将 component
字段设为 true
可将这一组文件设为自定义组件)。
2、如果我们想要在这个自定义组件中引入其他的组件,那么也是在这个json文件中写,配置usingComponents选项即可。例如:
"usingComponents": {
"item": "./item"
}
四、关于JS文件
js文件用来写页面的一些逻辑。以自定义组件为例:
在js中先写一个Component({})构造器
,当调用 Component
构造器时可以指定组件的属性、数据、方法等。
1、组件的属性properties选项:这个选项等同于vue中的props选项,用于接收父组件传过来的数据,注意:在vue中设置props中每一个数据的默认值是用default,在小程序中是用value。
2、组件的数据data选项:这个等同于vue中的data。
3、组件的方法methods选项:这个也等同于vue中的methods。
4、小程序中是没有computd和watch选项的,如果想要用,可以借助miniprogram-computed
插件,安装完后在对应想要使用的js文件中引入const computedBehavior = require("miniprogram-computed")
,然后配置一下:behaviors: [computedBehavior],
// js文件
const computedBehavior = require("miniprogram-computed")
Component({
behaviors: [computedBehavior],
computed: {
...
},
watch: {
...
}
})
这样就可以使用computed或watch选项了。
在computed或watch中如果想要用data或properties中的数据,则得按以下方式:
properties: {
a: {
type: Number,
value: 2
}
},
data: {
b: 1
},
computed: {
sum(data) {
return data.a + data.b
}
}
即:computed中传入的data其实是包含了properties、data、以及在该计算属性之前写的计算属性。
5、vue中如果想要在methods中改变data中的数据,直接this.xxx = xxx
就好,但是在小程序中,如果想要响应式地改变数据,则得借助setData函数,即
this.setData({
xxx: xxx
})
6、在vue中初始化工作我们一般是在created
生命周期中进行,在小程序中,我们是在attached
生命周期中进行,在这个生命周期函数中,我们是可以通过this.data拿到data或properties中的数据的。至于其他的生命周期函数,感兴趣的可以看一下微信官方文档。
五、关于WXS
有些时候,计算属性中依赖的数据是来自于父组件中传过来的数据,比方说:父组件传过来了两个时间startTime和endTime,我们需要对这两个数据进行一定的格式转换(使用计算属性dealTime),然后显示在页面中,同时,转换的操作是一样的。
<view>开始时间:{{dealTime(startTime)}}</view>
<view>结束时间:{{dealTime(endTime)}}</view>
那有人可能会说,computed中不是可以通过this.data拿到父组件传过来的数据吗?确实,是的,但是这并不符合我们的要求,因为如果是这样的话,你就必须写两个一模一样的计算属性,只是传入的数据不一样而已。
如果是在vue中,我们当然可以通过computed来实现,只要返回一个函数即可,即:
dealTime() {
return (value) => { // value即为从页面中传过来的值
...
}
}
但是在小程序中,我们无法用computed来实现这一功能,这个时候就需要wxs了
① 创建一个后缀名为wxs的文件(注意:wxs文件中定义变量只能用war,不能用let)
② 用module.exports导出
//wxs文件
var dealTime = function(value) {
...
}
module.exports = {
dealTime:dealTime
}
③ 在WXML文件的顶部通过标签<wxs></wxs>
中的src属性导入,通过module属性命模板名。
// wxml文件
<wxs module="time" src="./index.wxs"></wxs>
// 使用时则通过: 模块名.函数名即可
<view>开始时间:{{time.dealTime(startTime)}}</view>
<view>结束时间:{{time.dealTime(endTime)}}</view>
至此,坑踩完,日后若是遇到新的坑,将会在这里继续记录。