mpvue logo

npm npm

mpvue

mpvue 是一个使用 Vue.js 开发小程序的前端框架,目前支持 微信小程序百度智能小程序头条小程序支付宝小程序。 框架基于 Vue.js,修改了的运行时框架 runtime 和代码编译器 compiler 实现,使其可运行在小程序环境中,从而为小程序开发引入了 Vue.js 开发体验。

一些使用微信小程序前端/Mpvue开发前端的小技巧

Swiper的高度调整

在做小程序开发的时候,往往都要用到列表来进行展示,而对于列表类型的切换,则有很多各种各样的方法,有的使用按钮来切换,有的则使用滑动等方法,而swiper轮播视图则被很多人使用作为列表切换。

swiper

但是swiper存在一个比较不好的地方就是它是主要作为轮播一些图片的,因此高度需要自己设定,并不适合作为列表来使用。

但如果一定要作为列表使用的话,则有两种方法

  1. 先获得列表中的元素个数,并且元素的高度要是统一的,从而计算得到高度。
  2. 内部先放一个scroll-view,使得内部的元素能够进行滚动(推荐)

使用v-for自己做一个显示列表

mpvue里的v-for是一个很好用的东西,可以把数据中的一个数组对应为一组元素来进行渲染。

  1. 先使用v-for来写好tab,和list,最好做成组件的形式,提高代码复用性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <template>
    <div class="weui-tab">
    <div class="weui-navbar">
    <div v-for="(item,index) in tabs" :key="index" :class="{'weui-bar-item-on':activeIndex == index }"
    class="weui-navbar__item">
    <div class="weui-navbar__title">{{item}}</div>
    </div>
    </div>
    <div class="weui-navbar-content__slider">
    <div class="weui-navbar-slider" v-for="(item,index) in tabs" :key="index">
    <div class="weui-navbar-slider-inner" :class="{'weui-navbar-slider-on':activeIndex == index}"></div>
    </div>
    </div>
    </div>
    </template>

mptab


mplist


以上是tab为点击切换列表,同理列表也是一样使用v-for渲染。
tab的切换则是通过对class进行绑定,并且能够根据判断条件来进行,比如tab点击选项后,被点击的选项下面出现的下划线和颜色变化,则是通过:activeIndex == index来判断实现的。

  1. 添加使用触摸滑动的方式切换。
    如果点击的方式切换则没有这么友好,因此我们可以使用对整个list的触摸进行监听控制。当发现手指触摸向左/向右之后,进行切换。

    实现方式:
    在主页面上绑定触摸事件

    1
    <div class="mission-main" @touchstart="touchStart" @touchend="touchEnd" @touchmove="touchmove">

    得到触摸的开始位置和结束位置,进行判断,设置阈值防止误触。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    touchStart(e) {
    this.startX = e.mp.changedTouches[0].pageX;
    this.startY = e.mp.changedTouches[0].pageY;
    },
    touchmove(e) {
    this.endX = e.mp.changedTouches[0].pageX;
    this.endY = e.mp.changedTouches[0].pageY;
    if (Math.abs(this.endY - this.startY) < 100) {
    if (Math.abs(this.endX - this.startX) > 100) {
    .....
    switch()

    scrolllist

  2. 添加左右页面来进行更加流畅的滑动
    这个是理论上的实现,先在页面滑动页面上左右两边设置相同大小的页面隐藏在两边,类似于侧边栏,滑动能出来的那种,当向一遍滑动的时候,修改style样式中的left/right,让他能够显示出来,并且通过z-index设置,让它像滚筒一样最左边的那一张移动到最右边去。left-middle-right => middle-right-left,就能无限循环。(我猜swiper是这样弄得?

父子组件之间的交互(Props, 事件通信)

在使用mpvue之后,因为组件化更加彻底,出现很多组件需要进行相互通信的时候。

  1. 父组件给子组件传递数据
    需要使用props传递数据,父组件使用绑定类似的方式。

    1
    <children :data="data">

    子组件声明该变量为props

    1
    2
    3
    export default {
    props: ['data']
    }

    因为这个传递是单向的,所以在子组件中最好不要对props的数据进行修改,应当另外声明一个变量赋值后再修改使用。
    如果需要数据同步,在子组件中要用到watch方法:

    1
    2
    3
    4
    5
    6
    7
    8
    watch: {
    role:function (oldValue, newValue){
    this.role = newValue
    },
    activeIndex:function (oldValue, newValue){
    this.activeIndex = newValue
    }
    }
  2. 子组件传递数据给父组件
    子组件使用$emit来触发父组件的自定义事件。

    1
    this.$emit('confirmSend',data);

    父组件绑定事件,在触发的时候,得到数据

    1
    2
    3
    4
    5
    6
    <questionnaire @confirmSend="addQues"></questionnaire>
    ...
    addQues: function(val) {
    this.temDatas.push(val);
    console.log(this.temDatas)
    }
  3. 父组件调用子组件内部的方法

    1
    2
    3
    <child ref="child"></child>
    ...
    this.$.refs.child.childFn()

v-if和v-show的区别

在使用mpvue的时候常常会遇到v-if和v-show这两个东西来控制页面的显示。

v-if 是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

而 v-show 则是简单地基于 CSS 进行切换,不管怎样都会进行渲染。

一般来说, v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件不太可能改变,则使用 v-if 较好。

自定义组件click的处理

在mpvue中,不支持对组件的click操作,因此如果想要实现点击,需要换一个思路。

  1. 单纯地想实现点击事件,则只需要在组件内绑定click就行了,若需要反馈只要使用以上的消息传递即可。

  2. 只是想得到被点击的内容,如果是这样的话,往往都是只想知道自己点击的是第几个,那么使用v-for来进行配合,直接绑定在列表上,将会得到index,然后根据自己的需要得到内容(常用于导航栏的跳转和列表详情跳转)

    1
    2
    3
    4
    5
    6
    <div
    class="mission-list-item"
    v-for="(item, index) in show_list"
    :key="index"
    v-on:click="goto(index)"
    />

在mpvue下如何解决img变形问题

因为在mpvue的方式是通过对vue.js编译实现的,所以在对于<img>这一标签是被编译成小程序中的<image>,而这一标签没有width\height属性,因此我们需要写成内联的形式。

1
<img class="icon" style="width: 200px;" mode="widthFix" src="/static/images/question/单选.png">

另外image的mode里包含了对于图片的裁剪缩放模式,能够防止因尺寸不对图片变形。

云开发数据库API不支持类似SQL中like模糊查询

在小程序开发社区中有解决方法:

1
2
3
4
5
where({
key:{
$regex:'.*' + keyWord,
}
})

类似于SQL中的

1
2
select * from table
where key like '%'+keyWord

解决了我在数据库中检索数组中是否包含某一数值的难题。
据说后续会提供模糊搜索的API,但我貌似没有发现有。

Style的scope和!important

这个是关于style的域,scope是为了某一界面的class和另一界面的class同名导致冲突/污染,能够有效地限制style仅在该页面上使用。

而!important则是为了在让某一样式能够覆盖掉另一个同名样式,类似于一个组件有2个样式表,且存在同名的属性,这样在你所需要的属性后加上!important,则无论该样式作用先后的顺序,都能渲染你所需要的属性。(原本是后作用的样式表会覆盖前面的属性)

至于有一些在网上很多通用的模板,如果想要修改里面的样式,看中某一点,就可以使用这种覆盖的方式,但是推荐直接拿到源码来进行魔改。。。
例如使用npm下载的,在node_module中找到那个包,找到所需的组件,拉出来直接魔改更加方便。