记vue+leaflet的一次canvas渲染爆栈

背景:

在地图上绘制大量的circleMarker,leaflet能选择使用canvas来渲染,比起默认的svg渲染来说在大量绘制的情况下会更加流畅。但当触发其中某一个circleMarker的tooltip或popup时,浏览器报错“Uncaught RangeError: Maximum call stack size exceeded”:

解决过程:

1、写了个测试代码来复现问题:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset=‘utf-8‘ />
 5     <title>Add a raster tile source</title>
 6     <meta name=‘viewport‘ content=‘initial-scale=1,maximum-scale=1,user-scalable=no‘ />
 7     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
 8     <script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>
 9     <!--<script src="./vue.js"></script>-->
10     <!--<script src="./leaflet.js"></script>-->
11     <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
12           integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
13           crossorigin=""/>
14     <style>
15         * { margin:0; padding:0; }
16         html,body,#vue-wrap,#map { height: 100%; }
17     </style>
18 </head>
19 <body>
20     <div id="vue-wrap">
21         <div id="map">test</div>
22     </div>
23 <script>
24     new Vue({
25         el: ‘#vue-wrap‘,
26         data: function () {
27             return {
28                 map: ‘‘,
29                 canvas: L.canvas()
30             };
31         },
32         mounted: function () {
33             this.init();
34         },
35         methods: {
36             init () {
37                 this.map = new L.Map(‘map‘, {
38                     center: [39.928953, 116.389129],
39                     zoom: 11,
40                     maxZoom: 18,
41                     attributionControl: false,
42                     zoomControl: true
43                 });
44
45                 this.paintMarkers();
46             },
47             paintMarkers () {
48                 console.log(‘start paint‘);
49                 console.time(‘paint‘);
50                 for (let i = 0; i < 50000; i++) {
51                     let marker = L.circleMarker(this.generateLatlng(), {
52                         color: ‘#000‘,
53                         weight: 1,
54                         opacity: 1,
55                         fillOpacity: 0.8,
56                         radius: 6,
57                         fillColor: ‘orange‘,
58
59                         renderer: this.canvas
60                     });
61                     marker.bindTooltip(i + ‘‘);
62                     marker.bindPopup(`i: ${i}`);
63                     this.map.addLayer(marker);
64                 }
65                 console.timeEnd(‘paint‘);
66             },
67             generateLatlng () {
68                 let lat_min = 39.70111,
69                     lat_max = 40.14660,
70                     lng_min = 116.05843,
71                     lng_max = 116.63521;
72
73                 let lat = this.getRandomNum(lat_min, lat_max),
74                     lng = this.getRandomNum(lng_min, lng_max);
75
76                 return [lat, lng];
77             },
78             getRandomNum (min, max) {
79                 max = Math.max(min, max);
80                 min = Math.min(min, max);
81                 return Math.random() * (max - min) + min;
82             }
83         }
84     });
85 </script>
86
87 </body>
88 </html>

原文地址:https://www.cnblogs.com/cqq626/p/9434040.html

时间: 2024-11-26 15:41:29

记vue+leaflet的一次canvas渲染爆栈的相关文章

使用 Vue 2.0 实现服务端渲染的 HackerNews

Vue 2.0 支持服务端渲染 (SSR),并且是流式的,可以做组件级的缓存,这使得极速渲染成为可能.同时, 和 2.0 也都能够配合 SSR 提供同构路由和客户端 state hydration.vue-hackernews-2.0 是 Vue 作者在GitHub上面放的 Vue 2.0 的一个示例项目,结合 Express.vue-router & vuex 来构建,是很好的学习案例. Features Server Side Rendering Vue + vue-router + vue

Vue.js 系列教程 1:渲染,指令,事件

原文:intro-to-vue-1-rendering-directives-events 译者:nzbin 如果要我用一句话描述使用 Vue 的经历,我可能会说"它如此合乎常理"或者"它提供给我需要的工具,而且没有妨碍我的工作".每当学习 Vue 的时候,我都很高兴,因为很有意义,而且很优雅. 以上是我对 Vue 的介绍.在我第一次学习 Vue 的时候,我就想要这样的文章.如果你倾向于无党派的方法,请查阅 Vue 简单易懂的 用户指南. 系列文章: 渲染, 指令,

Vue.js(五)列表渲染 v-for

v-for="item in items "  //  数组更新检测  //  对象更改检测注意事项  //  显示过滤 / 排序结果  //  一段取值范围的 v-for  //   v-for 数组:我们用 v-for 指令根据一组数组的选项列表进行渲染.v-for 指令需要使用 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名. <ul id="example-1"> <li v-for

vue checkbox 双向绑定及初始化渲染

双向绑定可以绑定到同一个数组 <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="Joh

Vue源码后记-vFor列表渲染(2)

这一节争取搞完! 回头来看看那个render代码,为了便于分析,做了更细致的注释: (function() { // 这里this指向vue对象 下面的所有方法默认调用Vue$3.prototype上的方法 with(this){ return _c/*方法调用 => has拦截器过滤*/ ('div',{attrs:{"id":"app"}}, _l/*方法调用 => has拦截器过滤*/( (items/*_data属性访问 => 自定义pro

Vue源码后记-vFor列表渲染(3)

这一节肯定能完! 经过DOM字符串的AST转化,再通过render变成vnode,最后就剩下patch到页面上了. render函数跑完应该是在这里: function mountComponent(vm, el, hydrating) { vm.$el = el; if (!vm.$options.render) { vm.$options.render = createEmptyVNode; { // warning } } // beforeMount var updateComponen

使用 PHP 来做 Vue.js 的 SSR 服务端渲染

对于客户端应用来说,服务端渲染是一个热门话题.然而不幸的是,这并不是一件容易的事,尤其是对于不用 Node.js 环境开发的人来说. 我发布了两个库让 PHP 从服务端渲染成为可能.spatie/server-side-rendering 和 spatie/laravel-server-side-rendering适配 laravel 应用. 让我们一起来仔细研究一些服务端渲染的概念,权衡优缺点,然后遵循第一法则用 PHP 建立一个服务端渲染. 什么是服务端渲染 一个单页应用(通常也叫做 SPA

在vue中让某个组件重新渲染的笨方法

在vue中,推崇的是数据驱动也就是数据更新进而使组件得以重新渲染:在某些情况下,我们想要在数据不改变的情况下,重新渲染组件:我遇到的一个情况是:同一个页面,两个tab页分别为tab1和tab2,公用了一个组件,在tab1页修改了数据,再去tab2页查看的时候,发现tab1修改的数据会在tab2中的组件中显示,为了能够使得公用的组件重新渲染,可以使用v-if指令进行合理处理. 原文地址:https://www.cnblogs.com/llcdxh/p/9357661.html

vue 路由的作用,视图渲染

视图渲染 路由出了页面跳转这个功能以外,还有一个功能,那就是视图渲染. 简单点说,就是在页面加载的时候,通过配置好的路由路径,将对应好的模块渲染到页面. 我们通过router-view标签,来指定渲染的位置. 举例说明. 在router目录下的index.js文件配置路由. // 导入模块 import apple from '@/components/apple' // 配置路由 export default new Router({ routes: [{ path: '/', name: '