一. 使用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 较好。
二. 后台返回数据的问题
- 二次循环的时候 undefined.undefined这样是不行的,undefined后面不能用点语法不然会直接报错卡死下面的数据也不能直接运行
- 当后台数据为空的时候不能用 xxx.xxx === [] 来判断 两个单独的数组永不相等
- v-for 数组二次循环的时候会显示报错,虽然不影响运行,出现原因是因为数据请求需要时间,一开始的时候是空。你直接 v-for 就报错了。给 xxx数组写一个初始值,报错会消失。例如:xxx : [ { } ]
三,其他问题
- 场景:用v-for循环渲染商品列表,点击当前商品获取index进行下一步操作时,当用户进入页面没有点击但已设置显示默认选中第一个,直接操作下一个动作会获取不到index从而数据混乱,需要在获取数据的方法里面把index值代入,把默认值带进去 例如 xxx[this.index]带入解决
- 获取后台返回数组的键名:
四,小程序功能
- 复制订单号 手机号
<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移动端功能
- 设置页面头部固定和容器高度及滚动
设置高度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>