Open zhaobinglong opened 3 years ago
长列表在数据量很大的情况下,每次操作完原数组后,原数组list发生变化,会重新走一遍v-for进行页面重绘渲染,效率低下。写一个单独的组件,将数组list中的每一个对象传给子组件(Operate.vue),组件用props接受到后,之后只操作传过来的这个对象,不改变原数组list中的任何值;备注:这里为将一个数组变为两个,一个为 listOriginal 仅做初次渲染使用,另外一个listOperate 在组件回调后操作,用来做渲染之外的业务处理。这样页面渲染和业务操作通过子组件达到互补干扰的效果,页面也会极其流畅了。
<template>
<div class="optimize">
优化列表
<ul>
<Operate v-for="(item,index) in listOriginal" :item="item" :index="index" :key="index"></Operate>
</ul>
</div>
</template>
// 子组件
<template>
<li class="operate">
<img :src="item.img" />
<div class="left_bottom">
<p>{{item.name}}</p>
<p><span v-if="item.num > 0">{{item.num}}整份</span><span v-if="item.num > 0">{{item.num}}半份</span></p>
<span class="add btn" @click="add(index)">+</span>
<span class="num">{{item.num}}</span>
<span class="reduce btn" @click="reduce(index)">-</span>
</div>
</li>
</template>
<script>
export default {
name: 'operate',
data() {
return {}
},
props: ["item", "index"],
methods: {
// 子组件承担数据的渲染和业务交互
add(index) {
let t = this;
t.item.num++;
//t.$emit(...);//回调操作父组件listOperate,或者处理其他业务均可
},
reduce(index) {
let t = this;
t.item.num > 0 ? t.item.num-- : 0;
//t.$emit(...);//回调操作父组件listOperate,或者处理其他业务均可
}
}
}
</script>
https://blog.csdn.net/weixin_34178244/article/details/88028856
vFor 的优先级其实是比 vIF 高的,所以当两个指令出现来一个DOM中,那么 vFor 渲染的当前列表,每一次都需要进行一次 vIf 的判断。而相应的列表也会重新变化,这个看起来是非常不合理的。因此当你需要进行同步指令的时候。尽量使用计算属性,先将 vIf 不需要的值先过滤掉。看起像是下面这样的。
// 计算属性
computed: {
filterList: function () {
// 利用计算属性把需要渲染的数据先过滤出来,避免在for的时候判断
return this.showData.filter(item => item.checked)
}
}
// DOM
<ul>
<li v-for="item in filterList" :key="item.id">
{{ item.name }}
</li>
</ul>
// 针对只需要渲染一次的组件,一旦渲染之后内容不会再次变化的组件
<div v-once>{{ message }}</div>
利用v-if,异步加载不需要直接初始化就显示的组件,v-if是惰性指令,只有第一次为true,才会显示
<app>
<A></A>
<B v-if="showB"></B>
<C v-if="showC"></C>
</app>
使用异步路由可以根据URL自动加载所需页面的资源,并且不会造成页面阻塞,较适用于移动端页面 建议主页面直接import,非主页面使用异步路由
{
path: ‘/order’,
component: () => import(’./views/order.vue’)
}
它本质上,类似于Vue.js的生命周期钩子函数。它在新路由被确认前被调用,可以在里面进行数据处理,发起ajax获取数据,甚至是取消导航。当调用该守卫时,页面仍停留在原页面。该守卫执行完毕后(包括异步获取数据),才会跳转到新页面。
import $axios from '@/libs/axios';
import api from '@/api';
export default {
name:'testComponent',
data(){
return {};
},
beforeRouteEnter(to, from, next) {
$axios
.get(api.GetQueueSettingDetail, {
params: {
waybillKey: to.params.pickCode,
warehouseType: 11
}
})
.then(resp => {
if (resp.success) {
next(vm => {
vm.carInfo = resp.result;
});
} else {
next(false);
}
})
.catch(() => {
next(false);
});
},
}
// 应用NP处理浮点数运算
import NP from 'number-precision'
Vue.prototype.NP = NP
// 在templete中使用
{{ NP.times(data1, data2) }}
// 在methods中使用
this.NP.times(data1, data2)
什么是资源? 每创建出一个事物都需要消耗资源,资源不是凭空产生的,是分配出来的。所以说,当组件销毁后,尽量把我们开辟出来的资源块给销毁掉,比如 setInterval , addEventListener等,如果你不去手动给释放掉,那么它们依旧会占用一部分资源。这就导致了没有必要的资源浪费。多来几次后,可以想象下资源占用率肯定是上升的。 添加的事件
created() {
addEventListener('click', Function, false)
},
beforeDestroy() {
removeEventListener('click', Function false)
}
// 定时器
created() {
this.currentInterVal = setInterval(code,millisec,lang)
},
beforeDestroy() {
clearInterval(this.currentInterVal)
}
Vue(keep-alive)指定单页返回到页面不刷新,即保存状态 遇到的问题 在开发过程中,从 form单页 跳转到品牌选择页,选择成功后返回到 form页,需要保持 form页 的状态不变,即内容不刷新 众所周知,我们可以用keep-alive来实现,keep-alive是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM
// 实现所有页面不刷新
<keep-alive>
<router-view ></router-view>
</keep-alive>
但是这样并不是我所需要的效果,我只需要从品牌页跳转到form页实现不刷新 实现指定页面返回不刷新
// 1. 在路由router/index.js里面,在需要被缓存的组件路由设置keepAlive:true
{
path: '/form',
name: 'form',
component: form,
meta:{
keepAlive:true,
title: '表单应用'
}
},
// 2. 在App.vue把代码修改成如下
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
解释:路由的meta属性的keepAlive属性值为true时页面保存状态,其他情况不保存状态
数据冻结Object.freeze
vue 会通过 object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间。所以,我们可以通过 object.freeze 方法来冻结一个对象,这个对象一旦被冻结,vue就不会对数据进行劫持了。
demo