[英]Why does my vue code not work as expected?
there are two components
in div,When the two components
were rendered together, I clicked the button
to switch properly, but in the case of rendering only one component, the switch becomes abnormal. div中有两个
components
,当两个components
一起渲染时,我点击button
可以正常切换,但是在只渲染一个组件的情况下,切换变得异常。
this is my code这是我的代码
Base.vue基础.vue
<template>
<div :id="id">{{msg}}</div>
</template>
<script lang='ts'>
import { Component, Prop } from "vue-property-decorator";
import Vue from "vue";
@Component
export default class Base extends Vue {
id!: string;
msg = "this is Base";
}
</script>
child.vue(no template) child.vue(无模板)
<script lang='ts'>
import Base from "@/components/Base.vue";
import { Prop, Component } from "vue-property-decorator";
@Component
export default class extends Base {
@Prop({ default: "helloWorld" })
childId!: string;
constructor() {
super();
this.id = this.childId;
this.msg = "this is Child " + this.childId;
}
}
</script>
App.vue(display these components) App.vue(显示这些组件)
<template>
<div id="app">
<Child v-show="!show" childId="child1" style="color:#f00;"/>
<button @click="click">change</button>
<Child v-show="show" childId="child2" style="color:#f0f;"/>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Child from "@/components/Child.vue";
import Component from "vue-class-component";
@Component({
components:{
Child,
}
})
export default class App extends Vue {
show= false;
click() {
this.show = !this.show;
}
}
</script>
and click the button
the result is然后单击
button
结果是
These results are expected.这些结果是预期的。 But if all the
v-show
in the app.但是,如果应用程序中的所有
v-show
。 vue above are changed to v-if
, the result is confusing上面的 vue 改成
v-if
,结果比较混乱
then click the button
the result is然后点击
button
结果是
In our expectation it should display child2 here.在我们的预期中,它应该在这里显示 child2。 So why does this happen?
那么为什么会这样呢?
Your first click creates the the show-property which didn't exist because you didn't create your data()
properly.您的第一次单击会创建不存在的 show-property,因为您没有正确创建
data()
。
I'll not speculate exactly in the reasons why, but I assume there might be some funny boolean casts, and the property might not be reactive since it's not in data.我不会确切地推测原因,但我认为可能有一些有趣的 boolean 演员表,并且该属性可能不是反应性的,因为它不在数据中。 Either way, just create it and it'll work as you intended:
无论哪种方式,只需创建它,它就会按您的预期工作:
export default class App extends Vue {
data(){
return {
show: false
}
},
click() {
this.show = !this.show;
}
}
Thanks!!谢谢!!
I solved this problem when I added different keys to the two Child components当我向两个子组件添加不同的键时,我解决了这个问题
<Child v-if="!show" childId="child1" key="hello1" style="color:#f00;" />
<Child v-if="show" childId="child2" key="hello2" style="color:#f0f;" />
I think the reason is Vue's diff
algorithm, Vue considers these two components to be the same component我认为原因是Vue的
diff
算法,Vue认为这两个组件是同一个组件
Because when you use v-if
, it will use the single same Child
component.因为当您使用
v-if
,它将使用单个相同的Child
组件。 The this.msg
will only change once in the constructor
. this.msg
只会在constructor
中更改一次。 The msg
will not change when the childId props
changed, so you need the Watch
.当
childId props
改变时, msg
不会改变,所以你需要Watch
。 When the childId
changed, then to update the msg
当
childId
改变时,则更新msg
Child.vue孩子.vue
<script lang='ts'>
import Base from "@/components/Base.vue";
import { Prop, Component, Watch } from "vue-property-decorator";
@Component
export default class extends Base {
@Prop({ default: "helloWorld" })
childId!: string;
@Watch('childId')
onChildIdChanged(val: any) {this.msg = "this is Child " + val}
constructor() {
super();
this.id = this.childId;
this.msg = "this is Child " + this.childId;
}
}
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.