gpt4 book ai didi

javascript - Vue.js - Prop 同步不是即时的

转载 作者:搜寻专家 更新时间:2023-10-30 22:47:02 24 4
gpt4 key购买 nike

使用 vue.js 在父子之间同步 Prop 。问题是同步使用事件,每次我更改值时,我都必须在值更新之前等待 $nextTick。这并不理想,因为我不想在每次更改值时都输入 $nextTick。有没有办法让事件/ Prop 更新立即发生?

HTML:

<div id="app">
<foo inline-template v-bind:bar.sync="bar">
<div>
<button v-on:click="handler_button_click">Set to 5</button>
</div>
</foo>
<span>bar: {{bar}}</span>
</div>

JS:

const EVENT_UPDATE_BAR = "update:bar";

Vue.component("foo", {
props:["bar"],
computed:{
_bar:{
get:function(){
return this.bar;
},
set:function(value){
//Mutating the prop here solves the problem, but then I get a warning about mutating the prop...
//this.bar = value;
this.$emit(EVENT_UPDATE_BAR, value);
}
}
},
methods:{
handler_button_click:function(){
//It seems that $nextTick must run before value is updated
this._bar = 5;
//This shows old value - event / prop has not fully propagated back down to child
alert("bar: " + this._bar);
}
}
});

new Vue({
el:"#app",

data:{
bar:1
}
});

参见 CodePen 上的工作示例:https://codepen.io/koga73/pen/MqLBXg

最佳答案

让我们看一下您的示例。我为父组件和子组件的 bar 属性的值添加了观察者,并添加了 console.log 语句以记录两者之间数据传输的不同点组件:

const EVENT_UPDATE_BAR = "update:bar";

Vue.component("foo", {
props:["bar"],
computed:{
_bar:{
get:function(){
console.log('_bar getter is called')
return this.bar;
},
set:function(value){
console.log('_bar setter is called')
this.$emit(EVENT_UPDATE_BAR, value);
}
}
},
methods:{
handler_button_click:function(){
console.log('handler_button_click is called')
this._bar = 5;
console.log('this._bar is accessed with value: ', this._bar);
this.$nextTick(() => {
console.log('next tick handler is called')
})
console.log('handler_button_click finishes')
}
},
watch: {
bar() {
console.log('child bar watcher is called')
}
}
});

new Vue({
el:"#app",

data:{
bar:1
},
watch: {
bar() {
console.log('parent bar watcher is called')
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<foo inline-template v-bind:bar.sync="bar">
<div>
<button v-on:click="handler_button_click">Set to 5</button>
</div>
</foo>
<span>bar: {{bar}}</span>
</div>

您会注意到 handler_button_click 首先触发,然后是 _bargetset 方法计算。但是,在 handler_button_click 函数完成之前,bar 的两个观察者不会触发。这表明在 handler_button_click 函数完成执行之前,子组件的 $emit 调用传递的值不会被父组件处理。

Vue 提供的等待父子属性在 handler_button_click 函数内同步的唯一方法是调用 $nextTick,如您所述. $nextTick 函数将等待执行其处理程序,直到 DOM 完成更新。由于在解析父组件和子组件中的所有数据更改之前,DOM 不会完成渲染,因此您可以确定此时一切都会同步。


综上所述,您似乎只是希望子项的 _bar 属性在设置后立即更新,而您不一定需要立即在父范围中更新该值.

在这种情况下,您可以使用观察者而不是计算的 getter 和 setter。这样,由于未计算子属性,它将立即更新,而父属性将在下一次更新后更新。

这是一个例子:

const EVENT_UPDATE_BAR = "update:bar";

Vue.component("foo", {
props: ["bar"],
data() {
return {
value: this.bar,
};
},
methods: {
handler_button_click() {
this.value = 5;
alert("bar: " + this.value);
}
},
watch: {
value(val) {
this.$emit(EVENT_UPDATE_BAR, val);
},
bar(val) {
this.value = val;
}
}
});

new Vue({
el: "#app",
data() {
return {
bar: 1
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<foo inline-template v-bind:bar.sync="bar">
<div>
<button v-on:click="handler_button_click">Set to 5</button>
</div>
</foo>
<span>bar: {{bar}}</span>
</div>

请注意,我已将 _bar 属性的名称更改为 value,因为不能将带有下划线的属性视为 they are not proxied to the Vue instance。 .

关于javascript - Vue.js - Prop 同步不是即时的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52429857/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com