SignalR事件中调用Plotly.restyle抛出TypeError问题求助
问题根本原因
Vue的响应式代理机制会对其管理范围内DOM元素附加的自定义属性进行劫持销毁,Plotly初始化后会在目标DOM上挂载_plotly开头的私有属性存储图表配置和数据,这些属性被Vue破坏后,调用restyle时就会找不到对应trace数据,触发map方法调用报错。你在纯前端Pen环境运行正常是因为没有Vue的响应式劫持逻辑干扰。
修复步骤
- 调整Plotly初始化时机与存储方式
不要在Vue实例化前初始化图表,也不要把Plotly相关对象放到data配置中(data内的所有变量都会被做响应式代理),放到Vue的实例自定义属性上即可:
const app = new Vue({ el: '#app', data: { username: '', // 仅放业务需要的响应式数据,不要放Plotly相关内容 }, mounted() { // Vue挂载完成、DOM渲染后再初始化图表 const plotData = [ { x: ['giraffes', 'orangutans', 'monkeys'], y: [1, 1, 1], type: 'bar' } ]; // 存原生DOM对象到实例非响应式属性 this.$plotEl = document.getElementById('testplot'); Plotly.newPlot(this.$plotEl, plotData); }, methods: { onNewMessage(message) { const rawData = message.Text.replace(/"/g, ""); // 拆分后转数字,避免字符串数值的兼容问题 const yValues = rawData.split(',').map(Number); const result = [yValues]; // 直接用存储的原生DOM调用restyle,不要传选择器字符串 Plotly.restyle(this.$plotEl, 'y', result); } } });
- 修改SignalR回调绑定
不要用全局函数做回调,绑定Vue实例内的方法即可:
const connection = new signalR.HubConnectionBuilder() .withUrl(apiBaseUrl + '/api', { accessTokenFactory: () => { return generateAccessToken(app.username) } }) .configureLogging(signalR.LogLevel.Information) .build(); connection.on('newMessage', (msg) => app.onNewMessage(msg));
- 额外确认
testplotDOM元素写在#app的内部,避免选择器找不到元素。
内容的提问来源于stack exchange,提问作者Camilo Terevinto
相关产品推荐
相关产品推荐

