微信

微信小程序

2020-12-12  本文已影响0人  sweetBoy_9126

1. 组件通信

1.1. 父子组件通信

<view>
  <child test="aaa"></child>
</view>

child.js

Component({
  properties: {
    test: {
      type: String,
      value: ''
    }
  }
})
<view>
  <child bind:myEvent="handleEvent"/>
</view>

child.js

methods: {
  onClickTest(data) {
    this.triggerEvent('myEvent', data)
  }
}
App({
  globalData:{
    list:[]
  }
})

page1.js

const app = getApp()
Page({
  onLoad(){
    app.globalData.list.push({
      id: 10
    })
  }
})

page2.js

const app = getApp()
Page({
  onLoad(){
    console.log(app.globalData.list) // [{id:10}]
  }
})

2). storage
storage并不是作为通信的主要方式。storage 主要是为了缓存数据,并且最多只能存储10M的数据,我们应该合理使用storage

wx.setStorageSync('timestamp', Date.now())
wx.getStorageSync('timestamp')
wx.removeStorageSync('timestamp')

3). eventBus

class EventBus {
    constructor() {
        this.cacheData= {}
    }
    on(eventName, fn) {
        this.cacheData[eventName] = this.cacheData[eventName] || []
        this.cacheData[eventName].push(fn)
    }
    emit(eventName, data) {
        this.cacheData[eventName] = this.cacheData[eventName] || []
        this.cacheData[eventName].forEach((fn) => fn(data))
    }
    off(eventName, fn) {
        if (this.cacheData[eventName]) {
            const currentIndex = this.findIndex(eventName, fn)
            this.cacheData[eventName].splice(currentIndex, 1)
        } 
    }
    findIndex(eventName, fn) {
        for (let i = 0; i < this.cacheData[eventName].length; i++) {
            if (fn === this.cacheData[eventName][i]) {
                return i
            }
        }
    }
}
export default new EventBus()

page1.js

import eventBus from '@Utils/eventBus'
ready() {
        eventBus.on('update:addSelected', this.handleUpdateAddSelected.bind(this))
        eventBus.on('update:removeSelected', this.handleUpdateRemoveSelected.bind(this))
    },

page2.js

import eventBus from '@Utils/eventBus'
methods: {
  handleUpdateSelect() {
            if(this.data.active) {
                console.log(4)
                eventBus.emit('update:removeSelected', this.data.name)
            } else {
                console.log(5)
                eventBus.emit('update:addSelected', this.data.name)
            }
        }
}

2. 获取组件实例

可在父组件里调用 this.selectComponent ,获取子组件的实例对象。(插件的自定义组件将返回 null),调用时需要传入一个匹配选择器 selector,如:this.selectComponent(".my-component"),类似于vue的ref

// 父组件
Page({
  data: {},
  getChildComponent: function () {
    const child = this.selectComponent('.my-component');
    console.log(child)
  }
})

3.生命周期

created相当于vue的beforeCreated
attached相当于vue的created
ready相当于vue的mounted
detached相当于vue的beforeDestory

4. behaviors

相当于vue的mixin,会在使用的时候把里面的数据和当前实例合并
单独的behaviors.js文件写法

module.exports = Behavior({
  data: {},
  ...
})

observers数据监听(类似于vue的watch)

Component({
  attached: function() {
    this.setData({
      numberA: 1,
      numberB: 2,
    })
  },
  observers: {
    'numberA, numberB': function(numberA, numberB) {
      // 在 numberA 或者 numberB 被设置时,执行这个函数
      this.setData({
        sum: numberA + numberB
      })
    }
  }
})

4.给事件传递参数

使用data-属性,注意data-后面跟的必须是全小写的字符

<view class="network-debug-content-part-content" bindtap="handleRequestDataCopy" data-requestlist="aaa">
</view>

handleRequestDataCopy(event) {
            console.log(event.currentTarget.dataset.requestlist, 'aaa')
}

5. 插槽

用法

<!-- 在组件的wxml中定义插槽 -->

<view>

    <!-- 默认插槽 -->
    <slot></slot>

    <!-- 具名插槽 -->
    <slot name="before"></slot>

    <slot name="after"></slot>

</view>



<!-- 在页面组件中使用 -->


<dong my-class="add">

  <text>默认的插槽</text>

  <view slot="after">具名插槽</view>

  <view slot="before">具名插槽</view>  

</dong>

默认一个组件只支持一个插槽,如果想要使用多个插槽还需要在组件的js文件里配置options

Component({


    options: {

        multipleSlots: true
    }
})

如果想要实现有slot的时候只显示slot里的内容,没有slot的时候显示默认内容,可以使用css3 empty来实现

<view class="has-next-box has-next-customer">

<slot></slot>

</view>

<view class="has-next-box has-next-default">

没有更多数据

</view>


.has-next-customer {
 
 display: none;
}


.has-next-customer:not(:empty) {
  display: block;
}


.has-next-customer:not(:empty)+.has-next-default {
  display: none;
}

6. 微信小程序阻止触发父组件事件

将bindtap换成catchtap就可以

7. 对于key值不固定的对象在xml里遍历后想拿到每一个的key和value的方法

将一个键值对拆分成两个,将原来的key和value分别作为value
比如:

{a: 1},{b:2}
拆分成
{key1: a, key2: 1},
{key1: b, key2: 2}

7.template的使用

template主要是简化xml代码的,可以搭配behaviors对js重复代码进行复用
只要我们的xml文件里使用了<template name="模板名">就可以被使用
1).在当前页面使用
直接通过<template is="模块名 data={{数据}}">
2).在其他页面或者组件里使用

<import src="../network-debug/index.wxml" />
这里引入的l我们这个文件本身可以使xml文件,但是在import里必须写成wxml
<template is="模块名 data={{数据}}">

template模板里的方法需要在当前组件或者页面里写,如果很多地方都用到这些方法,我就就需要通过behavior引用这些方法。

问题:

1).解决弹窗层内容可拖动会底层内容跟着拖动的问题
一:给弹窗层组件设置一个catchtouchmove="ture"让它阻止父组件的touchmove;
这种情况下,我们弹窗层的touch事件也无法触发了
二:所以我们需要把弹窗层里的内容放到scroll-view组件里,这样它就可以拖动了;
因为scroll-view组件有回弹,所以如果我们底部有遮罩层的话,它拖动的时候会显示底部遮罩层的内容,所以我们需要给scroll-view标签设置背景色为我们的弹窗展示层的背景色(白色)

<block>
    <view class="collapse-drawer" w:if="{{visible}}" catchtouchmove="ture">
        <p-mask visible="{{visible}}" bindmasktap="handleHideMask" z-index="{{zIndex}}"/>
        <view class="collapse-drawer-wrapper {{visible ? 'collapse-drawer-wrapper-enter' : ''}}" style="z-index: {{zIndex}}">
            <view class="collapse-drawer-wrapper-header">
                <slot name="header"/>
            </view>
            <scroll-view scroll-y="true" style="height: {{contentHeight}}" class="collapse-drawer-wrapper-scroll">
                <slot/>
            </scroll-view>
        </view>
    </view>
</block>
.collapse-drawer {
    background: #fff;
    border-radius: 20rpx 20rpx 0 0;
    overflow: hidden;
    &-wrapper {
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        background: #fff;
        transform: translateY(100%);
        transition: all .3s linear;
        border-radius: 20rpx 20rpx 0 0;
        overflow: hidden;
        &.collapse-drawer-wrapper-enter {
            transform: translateY(0);
        }
        &-scroll {
            background: #fff;
        }
    }
}

2). 微信小程序的数据更新视图是只有当相关的data都变了视图才会变,如果只有一部分data变了,那么视图不会变
比如:


上面的item是data里的一项,它变了但是因为后面的requestItem.key(requestItem是另一个data里的一项)每次都是固定的,所以当前这个text也不会变

解决办法:对内层的wx:for遍历结构改成template的方式

上一篇下一篇

猜你喜欢

热点阅读