记--微信小程序知识总结+踩坑记录

937 阅读6分钟

前言
   最近接手了一个项目,是用小程序原生去开发,虽然小程序入手容易,但是其中坑巨多,以下是最近在开发时踩过的坑,花了较多时间解决,为避免更多人遇到时手足无措,特此记录。同时,在这里还总结了vue转换为小程序写法的一些知识点。

一、关于WXML

1、小程序中用来表示页面结构的文件是WXML,这是小程序自己的页面,因此原先vue中的标签在小程序这里就不能用了,得用小程序自己的标签,一般来说,vue中用到最多的标签就是div和span了,在小程序中分别对应view和text,即
div ---> view
span ---> text
img ---> image

2、vue中可以用v-html指令来动态渲染任意的HTML,而在小程序中没有对应的指令,但是我们可以用小程序中自带的rich-text标签来实现对应的功能。如下图:

image.png

image.png

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>

渲染后:

image.png

看出问题了吗?本来<view>世界</view>这个标签应该是要插在类名为demo-wrap标签里的,结果小程序却把它插在了与它同级的下一个节点里,这个是小程序的bug,到现在官方还没解决。。。

7、小程序WXML文件中是不能写反引号``来拼接字符串的,要想拼接,只能通过加号+。

二、关于WXSS

WXSS是小程序中用来展示样式的文件格式
1、小程序中的单位有两种:px和rpx,具体单位的转换可以看微信官方文档。

image.png
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>

至此,坑踩完,日后若是遇到新的坑,将会在这里继续记录。