mpvue框架开发小程序遇到的坑

一. 使用v-if 和 v-show 的 问题

1…解决v-if闪屏问题:由于v-cloak mpvue框架报错不支持 不能直接使用后台数据判断 需要初始化一个值
isXXX = false 并赋值给 后台数据
2. 区别:
2.1:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;

2.2:编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

2.3:编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;

2.4:性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

使用场景:如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

总结:v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

二. 后台返回数据的问题

  1. 二次循环的时候 undefined.undefined这样是不行的,undefined后面不能用点语法不然会直接报错卡死下面的数据也不能直接运行
  2. 当后台数据为空的时候不能用 xxx.xxx === [] 来判断 两个单独的数组永不相等
  3. v-for 数组二次循环的时候会显示报错,虽然不影响运行,出现原因是因为数据请求需要时间,一开始的时候是空。你直接 v-for 就报错了。给 xxx数组写一个初始值,报错会消失。例如:xxx : [ { } ]

三,其他问题

  1. 场景:用v-for循环渲染商品列表,点击当前商品获取index进行下一步操作时,当用户进入页面没有点击但已设置显示默认选中第一个,直接操作下一个动作会获取不到index从而数据混乱,需要在获取数据的方法里面把index值代入,把默认值带进去 例如 xxx[this.index]带入解决
  2. 获取后台返回数组的键名:

四,小程序功能

  1. 复制订单号 手机号
 <div>
                  <div>手机号:</div>
                  <div class="number">{{mineInfoData.phone}}</div>
                  <div class="copy" @tap="copyHandle(mineInfoData.phone)">
                    <img src="/static/images/copy.png" alt />
                  </div>
                </div>
>    // copy赋值操作
>     copyHandle(phone) {
>       wx.setClipboardData({
>         data: phone,
>         success(res) {
>           wx.getClipboardData({
>             success(res) {
>               console.log(phone);
>             },
>           });
>         },
>       });
>     },

五,vue移动端功能

  1. 设置页面头部固定和容器高度及滚动

设置高度body高度和padding-top是为了给头部返回栏留空间

/* body高度 */
.boxHeight{
    height: 100%;
    padding-top: 4.1rem;
}
/* 容器高度&滚动 */
.containerHeight{
    height: 100%;
    overflow-x: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    position: relative;
    top: -1px;
}

**

头部栏封装代码

给头部设置了绝对定位,因为是一个可视窗口的高度所以可以固定,就内容里面在滚动
**

<template>
	<header :class="'common_header ' + headerClass">
		<ul class="header_wrap">
			<li @click="toBack" feedback="active">
				<van-icon name="arrow-left"/>
			</li>
			<li>
				<span class="header_close" @click="closePage" v-if="closeText">关闭</span>
				<span class="pd_title">{{commonTitle ? commonTitle : 'title'}}</span>
			</li>
			<li @click="iconHandle" feedback="active" class="header_share"> 
				<!-- <img src="../../image/commonImg/common_refresh.png" v-if="rightIcon == 'refresh'"/> -->
				<van-icon name="replay" v-if="rightIcon == 'refresh'"/>
				<van-icon :name="rightIcon" v-else-if="rightIcon"/>
			</li>
			<span class="right_title" v-if="rightConfig" @click="jumpHandle(rightConfig.rightRouter)">{{rightConfig.rightTitle}}</span>
		</ul>
	</header>
</template>
<script>
import appuse from "../../utils/useapp.js";
export default {
	/**
	* commonTitle:头部标题
	* ifProtocol:返回类型:0-路由返回,1-原生协议返回
	* rightConfig:头部右边配置
	*  - rightRouter:头部右边配置-跳转路由
	*  - rightTitle:头部右边配置-标题
	* rightIcon:头部右边icon
	* closeText:是否显示“关闭”,false-否,true-是
	* backRouter:需是ifProtocol 等于3 时生效,返回的路由
	* headerStyle: 头部样式:默认红色渐变,black-黑底白字,transparent-透明底白字
	*/
  props: [
    "commonTitle",
    "ifProtocol",
    "rightConfig",
    "rightIcon",
    "closeText",
    "backRouter",
		"headerStyle"
  ],
	data(){
		return {
			// 头部类名
			headerClass: ''
		}
	},
	mounted(){
		this.headerStyleHandle();
	},
  methods: {
		// 样式处理
		headerStyleHandle(){
			var self = this;
			switch(self.headerStyle){
				case 'black' :
					self.headerClass = 'black_header';
          break;
        case 'transparent' :
					self.headerClass = 'transparent_header';
          break;
				default:
					break; 
			}
		},
    toBack() {
      var self = this;
      /**
       * 1 & 2---采用协议返回原生
       * 3 - 返回指定路由
       * 4 - 返回h5上一级页面
       * 其他---采用路由返回
       */
      if (self.ifProtocol == 1) {
        appExec.callHandler("closePage", {}, function(cbData) {});
      } else if (self.ifProtocol == 2) {
        appExec.callHandler("backSelf", {}, function(cbData) {});
      } else if (self.ifProtocol == 3 && self.backRouter) {
        self.$router.push({ name: self.backRouter });
      } else if (self.ifProtocol == 4) {
        appExec.callHandler("goBack", {}, function(cbData) {});
      } else {
        self.$router.go(-1);
      }
    },
    closePage() {
      appExec.callHandler("closePage", "", function(cbData) {});
    },
    // 右边跳转
    jumpHandle(_router) {
      if (this.rightConfig.rightRouter) {
        this.$router.push({ name: _router });
      } else {
        // 暴露方法
        this.$emit("showRight");
      }
    },
    // icon事件处理
    iconHandle() {
      this.$emit("getIconHandle");
    }
  }
};
</script>
<style lang="scss" scoped>
// @import '../../common/resetStyles.scss';
// 公共头部
.common_header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  overflow: hidden;
  z-index: 99;
}
.header_wrap {
  height: 82px;
  display: flex;
  align-items: center;
  position: relative;
  background: $appBackground;
  .right_title {
    position: absolute;
    top: 50%;
    right: 24px;
    margin-top: -2.05rem;
    font-size: 1.4rem;
    font-family: PingFang-SC-Medium;
    font-weight: bold;
    color: $textColor;
    line-height: 82px;
  }
  li {
    position: relative;
    i {
      font-size: 34px;
      font-weight: bold;
      color: $textColor;
      line-height: 82px;
    }
    img {
      width: 32px;
      height: 32px;
    }
    .header_close {
      position: absolute;
      left: 10px;
      font-size: 30px;
      font-family: PingFang-SC-Medium;
      font-weight: bold;
      color: $textColor;
      line-height: 36px;
    }
  }
}
.header_wrap li {
  display: flex;
  justify-content: center;
  align-items: center;
}
.header_wrap .img_box {
  width: 0.8rem;
  height: 1.45rem;
  position: relative;
}
.pd_title {
  color: $textColor;
  font-size: 34px;
  font-weight: bold;
  line-height: 82px;
}
li:nth-child(1),
li:nth-child(3) {
  height: 82px;
  width: 10%;
}
li:nth-child(2) {
  flex: 1;
}
// 替换头部样式:白底黑字
.black_header{
  border-bottom: 1px solid #e1e1e1;
	i,.header_close, .pd_title, .right_title{
		color: #000 !important;
	}
  .header_wrap{
	  background: #fff !important;
  }
}
// 替换头部样式:透明底白字
.transparent_header{
  i,.header_close, .pd_title, .right_title{
		color: #fff !important;
	}
  .header_wrap{
	  background: transparent;
  }
}

</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值