像我这样毫无能力又没有色彩的人
也就只能在失去中成长了吧

小程序Wepy杂谈

#小程序

前言

wepy是由Gcaufy大大开发的一款兼容微信小程序和支付宝小程序的框架。此框架的API设计与Vue极其相似,如果你熟悉Vue,那么你上手这框架只需要10分钟足矣。

当然并不是我们会Vue就一切都能那么顺利,wepy依旧也是略有不同,本文将会记录一些我认为容易出错的地方。

PS: 本文的示例代码基于wepy-cli@1.5.7(1.5.8有很多问题,强烈建议跳过)

##Components

使用组件

引入组件和Vue不同,Vue是引入.vue文件,而wepy是引入js文件,所以我们应该直接import WSlider from '../../components/Slider/slider';即可

注册组件的时候,写XML与KEY相同,无需肉串式

<view>
    <WSlider></WSlider>
</view>
import WSlider from '../../components/Slider/slider';

components = {
    WSlider,
};

关于repeat

repeat循环组件,你不能在computed或者watch里获得props的值,强烈建议不要使用repeat。正确姿势应该是你的组件就带有wx:for,你传入的data直接是一个数组,在组件里进行wx:for。然而我们用wx:for处理组件,就意味着,我们的组件不能再嵌套组件了

由于不建议使用repeat,还有很多坑就不一一说了。 2017年10月30日 更新,wepy发布了1.5.9 据说有所改善,我就不尝试了

关于computed传入组件

wepy不支持具体请看 #187 但是如果你仅仅只是个计算用作者的回答可以。如果你的值是需要通过props传进来再进行计算传入下个组件,那用作者这个方法也不行。正确姿势是先watch,props传入的值,然后在watch里写计算

props = ['xxx'];
data = {
    yyy: 0,
};
watch = {
    xxx(val) {
        this.yyy = val * 2;
        this.$apply();
    },
};

Page或Component获取globalData

有时候你会在app下保存一些全局属性globalData,你可能需要在components里获取那你需要这样写 this.$root.$parent.globalData 如果是在page下获取则直接this.$parent.globalData即可 当然我们还能这样wepy.$instance.globalData

父子组件通信

传递数据注意事项

在动态传值中,没法使用深层对象传递如下

// 失败
<child :title="xxx.title"></child>
// 成功
<child :title="title"></child>

// 传递复杂数据建议直接传递整个对象即可
data = {
    student: {
        name: '二哲',
        age: 18,
    }
}
<child :data="student"></child>

父子组件事件传递有两种方法,选择你喜欢的用

方法一 1.4.8新增

// 子组件
methods = {
    touchstart(e) {
      this.$emit('before', params);
    },
    touchmove() {
      this.$emit('change', params);
    },
    touchend() {
      this.$emit('after', params);
    },
}
// 父组件  
<child @change.user="parentChange"
       @after.user="parentAfter"
></child>
// 父组件js 
methods = {
    parentChange(params) {
      console.log(params);
    },
    parentAfter(params) {
      console.log(params);
    },
}

方法二 events

// 子组件
methods = {
    touchstart(e) {
      this.$emit('before', params);
    },
    touchmove() {
      this.$emit('change', params);
    },
    touchend() {
      this.$emit('after', params);
    },
}
// 父组件 XML 
<child></child>
// 父组件js 
events = {
    change(params) {
      console.log(params);
    },
    after(params) {
      console.log(params);
    },
}

不难发现,方法一更像Vue的用法,方法二则是依赖于events。方法一有个好处就是,可能有多个组件触发事件是同名的,我们就可以设置别名,而方法二events里就蛋疼了。所以各位可以选择自己喜欢的使用,团队最好保持风格一致,不要同时使用两种风格

Style

关于样式,小程序的CSS支持并不差,大多数参考官方文档即可。这里重点就说一个问题,我们习惯性去写伪元素,但在这里我们却没法这样在content里写中文

&:after {
    content: "图片加载中"; // 不行
}
&:after {
    content: "\u56fe\u7247\u52a0\u8f7d\u4e2d"; // 还是不行
}
&:after {
    content: "\56fe\7247\52a0\8f7d\4e2d"; // 正确姿势
}

如果你一定要写,可以转成别的编码显示中文

还有一个比较常用的属性也是可以的

&:nth-child(12n) {
    margin: 0 0 r(16) 0;
}