长话短说,我正在使用vue3和chartjs创建一个相当简单的折线图。
Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
at Object.get2 [as get] (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:467:23)
at toRaw (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:920:35)
at Proxy.instrumentations.<computed> (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:454:19)
at Proxy.value (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:667:26)
at Proxy.instrumentations.<computed> (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:454:36)
at Proxy.value (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:667:26)
at Proxy.instrumentations.<computed> (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:454:36)
at Proxy.value (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:667:26)
at Proxy.instrumentations.<computed> (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:454:36)
at Proxy.value (webpack-internal:///./node_modules/chart.js/dist/chunks/helpers.segment.js:667:26)
字符串
我已经看过this,this,this,和this类似的问题,但他们没有帮助。
这里是组件。注意我也尝试了vue-chartjs
,但没有帮助
<template>
<canvas id="passwordStrengthProgressChart" ref="passwordStrengthProgressChart">
</canvas>
<!-- <Line :data="data" :options="options">
</Line> -->
</template>
<script lang="ts">
import useEncryptedDataStore, { EncryptedDataStore } from '@/Objects/Stores/EncryptedDataStore';
import { ComputedRef, Ref, ShallowRef, computed, defineComponent, onMounted, readonly, ref, shallowReactive, shallowRef, watch } from 'vue';
import { PasswordsColor, ValuesColor } from '@/Types/Colors';
import { Chart, ChartData, LineController, LineElement, PointElement, LinearScale, Title, CategoryScale } from "chart.js"
import { Line } from "vue-chartjs"
import createTestData from '@/Utilities/TestUtility';
Chart.register(LineController, LineElement, PointElement, LinearScale, Title, CategoryScale)
export default defineComponent({
name: 'PasswordStrengthProgressChart',
components: {
// Line
},
setup() {
const encryptedDataStore: EncryptedDataStore = useEncryptedDataStore()
const passwordColor: string = PasswordsColor.primaryColor
const valuesColor: string = ValuesColor.primaryColor
const safePasswordCounts: number[] =
encryptedDataStore.currentAndSafePasswords.safe
const safeValueCounts: number[] =
encryptedDataStore.currentAndSafeValues.safe
const passwordStrengthProgressChart: Ref<HTMLElement | null> = ref(null)
const options: any = {
responsive: true,
elements: {
point: {
radius: 1
}
}
}
const data: Ref<any> = ref({
labels: encryptedDataStore.currentAndSafePasswords.current,
datasets: [
{
label: 'Secure Passwords',
data: [...safePasswordCounts],
borderColor: passwordColor,
cubicInterpolationMode: 'monotone',
tension: 0.4
},
{
label: 'Secure Values',
data: [...safeValueCounts],
borderColor: valuesColor,
cubicInterpolationMode: 'monotone'
}
]
})
onMounted(() => {
new Chart(
document.getElementById(
'passwordStrengthProgressChart'
) as HTMLCanvasElement,
{
type: 'line',
data: {
labels: encryptedDataStore.currentAndSafePasswords.current,
datasets: [
{
label: 'Secure Passwords',
data: safePasswordCounts,
borderColor: passwordColor,
cubicInterpolationMode: 'monotone',
tension: 0.4
},
{
label: 'Secure Values',
data: [1, 2],
borderColor: valuesColor,
cubicInterpolationMode: 'monotone'
}
]
},
options: {
responsive: false,
elements: {
point: {
radius: 0
}
}
}
}
)
// test updating the chart data. Causes the error
const interval = setInterval(() => {
createTestData()
clearInterval(interval)
}, 5000)
})
return {
options,
data
}
},
data() {
return {
chart: null
}
}
})
</script>
的数据
我猜这是因为vue和chartjs都在跟踪dom的变化,而且只是返回和第四次。我希望我能让vue停止跟踪更新,但我找不到任何方法。任何帮助都将不胜感激。
更新:这是只使用vue-chartjs
的代码,但问题相同。
<template>
<!-- <canvas id="passwordStrengthProgressChart" ref="passwordStrengthProgressChart">
</canvas> -->
<Line :data="data" :options="options">
</Line>
</template>
<script lang="ts">
import useEncryptedDataStore, { EncryptedDataStore } from '@/Objects/Stores/EncryptedDataStore';
import { ComputedRef, Ref, ShallowRef, computed, defineComponent, onMounted, readonly, ref, shallowReactive, shallowRef, watch } from 'vue';
import { PasswordsColor, ValuesColor } from '@/Types/Colors';
import { Chart, ChartData, LineController, LineElement, PointElement, LinearScale, Title, CategoryScale } from "chart.js"
import { Line } from "vue-chartjs"
import createTestData from '@/Utilities/TestUtility';
Chart.register(LineController, LineElement, PointElement, LinearScale, Title, CategoryScale)
export default defineComponent({
name: "PasswordStrengthProgressChart",
components:
{
Line
},
data()
{
return {
chart: null
}
},
setup()
{
const encryptedDataStore: EncryptedDataStore = useEncryptedDataStore();
const passwordColor: string = PasswordsColor.primaryColor;
const valuesColor: string = ValuesColor.primaryColor;
const safePasswordCounts: Ref<number[]> = ref(encryptedDataStore.currentAndSafePasswords.safe);
const safeValueCounts: Ref<number[]> = ref(encryptedDataStore.currentAndSafeValues.safe);
const passwordStrengthProgressChart: Ref<HTMLElement | null> = ref(null);
const options: any = {
responsive: true,
elements:
{
point:
{
radius: 1
}
}
};
const data: Ref<any> = ref({
labels: encryptedDataStore.currentAndSafePasswords.current,
datasets: [
{
label: 'Secure Passwords',
data: safePasswordCounts,
borderColor: passwordColor,
cubicInterpolationMode: 'monotone',
tension: 0.4
},
{
label: 'Secure Values',
data: safeValueCounts,
borderColor: valuesColor,
cubicInterpolationMode: 'monotone',
}
]
});
onMounted(() =>
{
// new Chart(document.getElementById('passwordStrengthProgressChart') as HTMLCanvasElement,
// {
// type: 'line',
// data: {
// labels: encryptedDataStore.currentAndSafePasswords.current,
// datasets: [
// {
// label: 'Secure Passwords',
// data: safePasswordCounts,
// borderColor: passwordColor,
// cubicInterpolationMode: 'monotone',
// tension: 0.4
// },
// {
// label: 'Secure Values',
// data: [1, 2],
// borderColor: valuesColor,
// cubicInterpolationMode: 'monotone',
// }
// ]
// },
// options:
// {
// responsive: false,
// elements:
// {
// point:
// {
// radius: 0
// }
// }
// }
// });
// test updating the chart data
const interval = setInterval(() =>
{
createTestData();
clearInterval(interval);
}, 5000);
});
return {
options,
data
}
}
})
</script>
<style></style>
型
这只是在使用encryptedDataStore
与chartjs时的问题,而不是其他任何地方。
1条答案
按热度按时间2w2cym1i1#
我设法解决了这个问题,将React数据解构成一个新的
ref
,观察原始数据结构的变化,然后更新解构的值,并强制vue重新渲染组件。下面是最终代码
字符串