不管是兄弟组件之间的传值,还是页面之间传值(如:页面A打开页面B ,页面B返回到页面A,给页面A传值)

步骤一:eventVue.js

import Vue from 'vue'
export default new Vue()

步骤二: 页面B.vue

import bus from "@/utils/eventVue.js";
 methods: {
   clickFn() {
    //返回到上一个页面A,传递变量par  $emit触发事件:updateData 
         bus.$emit("updateData", par);
        // 返回到上一个页面
       wx.navigateBack({
            delta: 1
        });
    }
}

页面A.vue

import bus from "@/utils/eventVue.js";
onShow() {
    let that = this;
  $on:运行事件名updateData, 执行里面的函数
function(par) {console.log( that.seledVal, par);}
  bus.$on("updateData", function(par) { console.log( that.seledVal, par); });
}

父组件给子组件传值:

父组件:par.vue

<indivAppl :form="seledVal" ref="indivAppl"></indivAppl>
import indivAppl from "@/components/pay/selfApplSel/indivAppl.vue";

方法一:父组件通过refs调用子组件, 设置子组件的变量 或调用子组件的方法

this.$refs.indivAppl.area = area
this.$refs.indivAppl.getSign(res);
注意:使用$refs给子组件传值时,要确保子组件dom结构已经加载完毕,所以不能在onLoad onShow生命周期中使用,要在mounted生命周期中 + this.$nextTick()使用,如:
  mounted() {
    this.$nextTick(() => {
  this.$refs.indivAppl.getSign(res);
 })
}
若子组件已经加载完毕,可在父组件的方法中 直接使用$refs给子组件传值,如par.vue中
methods:{
  finishHandler() {
  this.$refs.indivAppl.area = area
 }
}

子组件: child.vue

方法二: 通过props属性接收变量form

 props: {
    form: {
      type: Object
    },

针对父组件给子组件传递的变量form 是动态变化的,此时子组件中这个变量form也是同步更新的,最新值。若要根据变量form实现逻辑方法A,需要在子组件watch变量form, 子组件 child.vue:

data() {
    return {
       formPage: {},
 }
}
watch: {
  form: {
    handler(val) {
       // 对象直接=赋值,相当于浅拷贝,this.formPage的变化会引起 this.form的变化,所以用JSON.parse(JSON.stringify)
       this.formPage = JSON.parse(JSON.stringify(val));
    //调用该方法
    this.handleChange()

}, deep: true } },
methods:{
  handleChange(){
this.bl = !this.bl
}
}

针对多个页面需要修改的同一个变量,可用vuex, 在需要显示变量的页面,可通过computed计算属性,如下:

computed: {
    disableBl() {
      console.log("computed 判断复选框是否可用", this.$store.state.disableBl);
      return this.$store.state.disableBl === 2 ? true : false;
    }
  },

或可通过本地缓存: wx.getStorageSync("name")     wx.setStorageSync("name","demi")

 

函数防抖与函数节流

utils.js:

// 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次, 如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
function debounce(fn, t) {
  let delay = t || 500
  let timer
  // console.log(fn)
  return function () {
    // console.log('arguments', arguments)
    let args = arguments
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      timer = null
      // console.log(this)
      fn.apply(this, args)
    }, delay)
  }
}

// 函数节流(throttle):函数在一段时间内(gapTime)多次触发只会执行第一次,在这段时间结束前,不管触发多少次也不会执行函数。
// 防止用户多次点击
function throttle(fn, gapTime) {
  // console.log(fn)
  // gapTime:时间间隔
  if (gapTime == null || gapTime == undefined) {
    gapTime = 1500
  }

  let _lastTime = null // 返回新的函数
  return function () {
    let _nowTime = +new Date()
    // console.log('111_nowTime', _nowTime, '_lastTime', _lastTime)
    if (_nowTime - _lastTime > gapTime || !_lastTime) {
      // console.log('22_nowTime', _nowTime, '_lastTime', _lastTime)
      fn.apply(this, arguments) //将this和参数传给原函数
      _lastTime = _nowTime
    }
  }
}
export default {
  throttle,
  debounce,
}

函数防抖用在 输入框input输入时 实时调取后台接口实现查询功能,当用户输入值后停留超过一段时间 再调取接口查询数据,避免一直调用接口。

 <input
      type="text"
      :value="value"
      @input="bindphInput"
>
 import util from "@/utils/util.js";
 // input输入框的值发生变化
    bindphInput(e) {
      this.value = e.mp.detail.value;
        // input搜索框实时调用接口会请求过多,所以用函数防抖
        this.emitParentFn();
    },
    //用户暂停输入超过0.6s 才会请求接口
    emitParentFn: util.debounce(function(e) {
      this.$emit("sub", this.value);
    }, 600)

 函数节流:防止用户多次连续点击同一个按钮

 <p class="btns" @click="openpage">点击</p>
import util from "@/utils/util.js";
// 第n+1次点击按钮的时间与第n次相差超过1.5s以后,才会执行函数fn 打开新页面
    openpage: util.throttle(function(e) {     
     wx.navigateTo({
       url: "/pages/packageA/pages/selfName/main"
        });
   }  

地址选择器: picker-view:参考 baiyiapp\src\components\pay\address.vue页面:主要逻辑:运用 picker-view组件, 结合@change事件,省份改变的时候,改变对应城市,区域的值

动态生成并循环出来的多个input组件如何获取每个文本框的值: 

<div class="flex name nameDesign" v-for="(item,i) in datas" :key="i">
 <p>商标名称</p>
      <div class="inputDiv">
          <input type="text" :data-name="i" placeholder="请输入" @input="inputFn" />
      </div>
</div>
nameArr: [], // 商标名称组成的数组
// 所有商标名称 对应输入框发生变化 inputFn(e) { let value = e.mp.detail.value; //根据data-name变量获取对应input框的值,放到索引 i 对应的nameArr数组里面 let idx = e.mp.currentTarget.dataset.name; this.$set(this.nameArr, idx, value); },

mpvue框架解决页面返回后,数据没重置的问题:针对页面A引入子组件,一定要把A页面中prop给子组件的数据恢复重置。

案例:多个商品,打开同一个页面A(商品详情页),通过不同的商品id,调用接口返回商品详情,再prop给子组件,子组件显示的是 上次打开页面A,获取到的商品信息数据。因为再次打开页面A,data中的数据为上一次的历史值,此时接口请求获取商品详情还没完成,子组件已经渲染完毕,子组件prop的值 为上一次prop的历史值,所以子组件显示的页面数据是上一次的历史数据。

 onUnload() {
    //关闭该页面,在mpvue框架中,该页面data中的数据不会恢复默认,即保留历史数据值(小程序关闭页面自动重置该页面的所有数据),页面中的子组件保留prop过来的值,以及子组件data中的原有数据值,
    //即关闭该页面,再次打开该页面,此时prop传递给子组件的值,都是之前的历史值,id为页面A之前prop的id值,datas为之前传递的对象值
    //解决方法:关闭该页面,重置传递给子组件的变量值,或者清空页面A中data中的所有变量值
    // 解决页面返回后,数据没重置的问题(清空页面A中data中的所有变量值
   Object.assign(this, this.$options.data());
},

 总结:页面onUnload事件中,数据重置即可。