This time I will bring you keep-alive to control the number of server requests. What are the precautions for keep-alive to control the number of server requests? The following is a practical case, let's take a look.
VUE2.0 provides a keep-alive method, which can be used to cache components to avoid loading corresponding components multiple times and reduce performance consumption. For example, the data of a page, including pictures, text, etc., have been loaded by the user, and then the user jumps to another interface by clicking on it. Then return to the original interface from another interface. If it is not set, the information of the original interface will be requested from the server again. The keep-alive provided by vue can save the requested data of the page, reduce the number of requests, and improve the user experience.
Cache components be divided into two types, components to cache the entire site’s pages or components to cache some pages.
1. Cache all pages, suitable for situations where each page has a request. The method is as follows: wrap the router-view that needs to be cached with the keep-alive tag.
<keep-alive> <router-view></router-view> </keep-alive>
to write the first trigger request into the created hook, can achieve caching. For example, when you go from the list page to the details page, you will still be on the original page when you come back.
2. Cache some components or pages, which can be achieved through judgment using the router.meta attribute. The method is as follows: The name implies the meaning, include means to include, exclude means to exclude. Here you need to use the name of the component to set it, so the name must be added. Adding components a and b requires caching, while components c and d do not require caching. It is written as follows:
<keep-alive v-if="$route.meta.keepAlive"> <router-view></router-view> </keep-alive> <router-view v-if="! $route.meta.keepAlive"></router-view>
The optimization of the vue project can also be achieved through the on-demand loading of components, just like the lazy loading of pictures. If the customer does not see those pictures at all, but we are opening the page When all is loaded, this will greatly increase the request time and reduce the user experience. Lazy loading is used on many websites, such as shopping websites such as Taobao and JD.com. There are many picture links on them. If you pull the scroll down quickly, you may see the pictures loading. Condition.
Supplement:
#Notes when Vue routing turns on keep-alive
This is not Business requirements, but seeing that every time I enter the page, the DOM is re-rendered and then the data is obtained to update the DOM. I feel that as a front-end engineer, it is necessary to optimize the loading logic. It happens that Vue provides the keep-alive function, so I tried it out. . Of course, nothing will be smooth sailing, and bumps and bumps on the road are inevitable, so I record the problems encountered here and hope that people who read this article can help. ps: This is not difficult. HTML part:
routers:[ { path: '/home', name: home, meta:{keepAlive: true} // 设置为true表示需要缓存,不设置或者false表示不需要缓存 } ]
The page life cycle hook is as shown in the code above, These four are the most commonly used parts. This part needs to be noted. When keep-alive is introduced, when the page is entered for the first time, the trigger sequence of the hook is created->mounted->activated, and deactivated is triggered when exiting. When entering again (forward or backward), only activated is triggered. We know that after keep-alive, the page template is initialized and parsed into an HTML fragment for the first time. When it is entered again, it will not re-parse but read the data in the memory. That is, it will only be used when the data changes. VirtualDOM performs diff updates. Therefore, the data obtained when entering the page should also be placed in activated. After the data is downloaded, the manual operation of the DOM should also be executed in activated to take effect.
So, you should leave a copy of the data acquisition code in activated, or you should leave out the created part and directly transfer the code in created to activated.
2. The data in $route cannot be read以前的写法是在data中将需要的 $route 数据进行赋值,便于其余方法使用,但是使用了 keep-alive 后数据需要进入页面在activated中再次获取,才能达到更新的目的。定义一个initData方法,然后在activated中启动。
initData: function () { let _this = this; _this.fromLocation = JSON.parse(this.$route.query.fromLocation); _this.toLocation = JSON.parse(this.$route.query.toLocation); _this.activeIndex = parseInt(this.$route.params.activeIndex) || 0; _this.policyType = parseInt(this.$route.params.policyType) || 0; },
3. 当页动态修改url
需求描述:当页面在进行轮播操作的时候希望能记录当前显示的轮播ID(activeIndex)。当进入下一个页面再返回的时候能记住之前的选择,将轮播打到之前的ID位置。所以我想将这部分信息固化在url中,轮播发生变化时,修改URL。这样实现比较符最小修改原则,其余页面不用变动。
之前的写法是将activeIndex放在 $route 的query中,当轮播后,将
activeIndex的值存入 $route.query.activeIndex 中,然后 $router.replace 当前路由,理论上应该能发生变化,但实际没有。
查看文档后说, $route 是只读模式。当然,对象部分是他监管不到的,我修改了并不是正统的做法。
神奇的地方来了:当我将activeIndex记在params中,轮播变动修改params中的参数,然后 $router.replace 当前路由,却能发生对应的变化。代码如下:
let swiperInstance = new Swiper('#swiper', { pagination: '.swiper-pagination', paginationClickable: false, initialSlide: activeIndex, onSlideChangeEnd: function (swiper) { let _activeIndex = swiper.activeIndex; _this.$route.params.activeIndex = _activeIndex; // $router我放到了window上方便调用 window.$router.replace({ name: _this.$route.name, params: _this.$route.params, query: _this.$route.query }); // 根据activeIndex,在这里初始化下面显示的数据 _this.transferDetail = _this.allData.plans[_activeIndex].segments; _this.clearBusDetailFoldState(); } });
4. 事件如何处理
估计你也能猜到,发生的问题是事件绑定了很多次,比如上传点击input监听change事件,突然显示了多张相同图片的问题。
也就是说,DOM在编译后就缓存在内容中了,如果再次进入还再进行事件绑定初始化则就会发生这个问题。
解决办法:在mounted中绑定事件,因为这个只执行一次,并且DOM已准备好。如果插件绑定后还要再执行一下事件的handler函数的话,那就提取出来,放在activated中执行。比如:根据输入内容自动增长textarea的高度,这部分需要监听textarea的input和change事件,并且页面进入后还要再次执行一次handler函数,更新textarea高度(避免上次输入的影响)。
5. 地图组件处理
想必这是使用 keep-alive 最直接的性能表现。之前是进入地图页面后进行地图渲染+线路标记;现在是清除以前的线路标记绘制新的线路,性能优化可想而知!
我这里使用的是高德地图,在mounted中初始化map,代码示例如下:
export default { name: 'transferMap', data: function () { return { map: null, } }, methods: { initData: function () {}, searchTransfer: function (type) {}, // 地图渲染 这个在transfer-map.html中使用 renderTransferMap: function (transferMap) {} }, mounted: function () { this.map = new AMap.Map("container", { showBuildingBlock: true, animateEnable: true, resizeEnable: true, zoom: 12 //地图显示的缩放级别 }); }, activated: function () { let _this = this; _this.initData(); // 设置title setDocumentTitle('换乘地图'); _this.searchTransfer(_this.policyType).then(function (result) { // 数据加载完成 // 换乘地图页面 let transferMap = result.plans[_this.activeIndex]; transferMap.origin = result.origin; transferMap.destination = result.destination; // 填数据 _this.transferMap = transferMap; // 地图渲染 _this.renderTransferMap(transferMap); }); }, deactivated: function () { // 清理地图之前的标记 this.map.clearMap(); }, }
6. document.title修改
这个不是 keep-alive 的问题,不过我也在这里分享下。
问题是,使用下面这段方法,可以修改Title,但是页面来回切换多次后就不生效了,我也不知道为啥,放到setTimeout中就直接不执行。
document.title = '页面名称';下面是使用2种环境的修复方法:
纯js实现
function setDocumentTitle(title) { "use strict"; //以下代码可以解决以上问题,不依赖jq setTimeout(function () { //利用iframe的onload事件刷新页面 document.title = title; var iframe = document.createElement('iframe'); iframe.src = '/favicon.ico'; // 必须 iframe.style.visibility = 'hidden'; iframe.style.width = '1px'; iframe.style.height = '1px'; iframe.onload = function () { setTimeout(function () { document.body.removeChild(iframe); }, 0); }; document.body.appendChild(iframe); }, 0); }
jQuery/Zepto实现
function setDocumentTitle(title) { //需要jQuery var $body = $('body'); document.title = title; // hack在微信等webview中无法修改document.title的情况 var $iframe = $('<iframe src="/favicon.ico"></iframe>'); $iframe.on('load', function () { setTimeout(function () { $iframe.off('load').remove(); }, 0); }).appendTo($body); }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of keep-alive controls the number of server requests. For more information, please follow other related articles on the PHP Chinese website!