Javascript Vue.js-反应性组件,不总是重新渲染
我面临两个组件的反应性问题Javascript Vue.js-反应性组件,不总是重新渲染,javascript,charts,vue.js,vuejs2,Javascript,Charts,Vue.js,Vuejs2,我面临两个组件的反应性问题折线图和条形图 当我将复选框值链接更改为v-model=“formChart.type时,组件折线图和条形图将自动重新呈现 但是当我点击触发函数submitForm的按钮时,然后generateChart()和resetTypeChart()这些组件不会被重新渲染 未触发mounted()功能 我真的不明白为什么会发生这种情况,因为我正在重置类型和显示…我尝试使用或不使用Vue.set没有任何更改 代码进入resetTypeChart()函数 组件不总是重新渲染 JS
折线图
和条形图
当我将复选框值链接更改为v-model=“formChart.type
时,组件折线图
和条形图
将自动重新呈现
但是当我点击触发函数submitForm
的按钮时,然后generateChart()
和resetTypeChart()
这些组件不会被重新渲染
未触发mounted()
功能
我真的不明白为什么会发生这种情况,因为我正在重置类型
和显示
…我尝试使用或不使用Vue.set
没有任何更改
代码进入resetTypeChart()
函数
组件不总是重新渲染
JSFIDLE
- 切换到
条形图
,生成组件
- 单击
Generate
,同时仍在同一个单选按钮上。不显示任何内容
单击“生成”按钮时未看到警报的原因是,Vue已确定没有任何更改,因此不需要更新DOM。正如我在上面的评论中所说,Vue DOM更新是异步进行的,这意味着Vue在您单击“生成”按钮之前不会检查是否有任何更改thod已完成。当您的方法完成时,您的状态中没有任何更改;您将其设置为某个值,然后将其设置回原始值
要演示并引入从清除值到设置值之间的时间延迟。您可以看到,在本例中,Vue有时间检查值是否已更改,然后又重新更改,您将收到消息
generateChart : function () {
alert('generate')
const saveType = this.formChart.type;
this.formChart.type = '';
this.formChart.show = false;
setTimeout(()=>{
this.formChart.type = saveType;
this.formChart.show = true;
}, 1000)
}
我认为在您的情况下,应该触发更新的是对dataChart
的一些更改。当该值更改时,您的Vue应该重新渲染。但是,您不会显示它曾经更改过。现在,如果数据没有更改,并且您不希望用户看到不同的图表(因为您正在将其设置回相同的值),为什么要重新渲染
为了使图表在chartData更改时重新呈现,您应该查看组件中的chartData属性
const ChartBase = {
props: ["chartData"],
methods:{
showChart(){
this.renderChart({
labels: this.chartData.labels,
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: this.chartData.data
}
]
}, {responsive: true, maintainAspectRatio: false})
}
},
mounted : function () {
this.showChart()
this.$watch("chartData.data", this.showChart)
},
}
Vue.component('bar-chart', {
extends: VueChartJs.Bar,
mixins: [ChartBase]
});
Vue.component('line-chart', {
extends: VueChartJs.Line,
mixins:[ChartBase]
});
var Main = {
data () {
return {
formChart : {
type : 'line_chart',
show : false,
},
chartData:{
labels:['January', 'February', 'March', 'April', 'May', 'June', 'July'],
data: [40, 39, 10, 40, 39, 80, 40]
}
};
},
methods : {
generateChart : function () {
const newChartData = [...this.chartData.data.reverse()]
this.chartData.data = newChartData
}
},
}
单击“生成”
按钮时显示图表的更改。您在“重置类型图表”中并没有真正更改任何内容。这并不是说Vue在设置“显示为false”和“返回为true”之间运行并执行任何操作。函数完成后,它将查看是否需要执行某些操作,在这种情况下案例,我不认为它会改变。你能做一个工作示例,让我们看到你试图解决的问题吗?我会尝试做一个示例,但这并不容易…你如何解释更改复选框以便formChart.type
在组件链接到v-model
时重新渲染组件,而不是在我执行this.formChart.type='
然后执行`this.formChart.type=''bar\u chart',因为DOM会更新。如果您只需单击单选按钮,那么Vue就有时间运行下一个异步DOM更新。但是更新并不会在执行方法的中间运行。我创建了一个<代码> jsFoDeld比我预期的要简单。如果您切换单选按钮
,它将显示生成的条形图
,如果您单击“生成”,它将不会显示它依靠设置超时
?那么,$nextTick
呢?@Leo我不是建议用它来解决你的问题;我试图证明你为什么会看到你所看到的行为。我认为真正触发重新渲染的应该是对dataChart
的更改dataChart
在generateChart()中被修改你的方法是什么?考虑到我也需要考虑图表的<代码>类型>代码>来显示一个或另一个。这里是一个演示我将如何做它。如果你只是想看到一个图表,当你第一次点击<代码>生成< /代码>你不需要别的东西在<代码> V-IF <代码>吗?
<el-button type="primary" size="large"@click="submitForm('formChart')">Generate</el-button>
submitForm(formName) {
this.$refs[formName].validate((valid) => {
this.generateChart();
this.resetTypeChart();
}
});
resetTypeChart () {
const saveType = this.formChart.type;
this.formChart.type = '';
this.formChart.show = false;
Vue.set(this.formChart, 'type', saveType);
this.formChart.type = saveType;
this.formChart.show = true;
}
generateChart : function () {
alert('generate')
const saveType = this.formChart.type;
this.formChart.type = '';
this.formChart.show = false;
setTimeout(()=>{
this.formChart.type = saveType;
this.formChart.show = true;
}, 1000)
}
const ChartBase = {
props: ["chartData"],
methods:{
showChart(){
this.renderChart({
labels: this.chartData.labels,
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: this.chartData.data
}
]
}, {responsive: true, maintainAspectRatio: false})
}
},
mounted : function () {
this.showChart()
this.$watch("chartData.data", this.showChart)
},
}
Vue.component('bar-chart', {
extends: VueChartJs.Bar,
mixins: [ChartBase]
});
Vue.component('line-chart', {
extends: VueChartJs.Line,
mixins:[ChartBase]
});
var Main = {
data () {
return {
formChart : {
type : 'line_chart',
show : false,
},
chartData:{
labels:['January', 'February', 'March', 'April', 'May', 'June', 'July'],
data: [40, 39, 10, 40, 39, 80, 40]
}
};
},
methods : {
generateChart : function () {
const newChartData = [...this.chartData.data.reverse()]
this.chartData.data = newChartData
}
},
}