简体   繁体   English

为什么我的 vue 代码没有按预期工作?

[英]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 msgchildId改变时,则更新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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM