【问题标题】:Why does my vue code not work as expected?为什么我的 vue 代码没有按预期工作?
【发布时间】:2020-11-10 13:24:23
【问题描述】:

div中有两个components,当两个components一起渲染时,我点击button可以正常切换,但是在只渲染一个组件的情况下,切换变得异常。

这是我的代码

Base.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(无模板)

<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(显示这些组件)

<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>

然后点击button结果是

这些结果是预期的。但如果应用程序中的所有v-show。上面的vue改成v-if,结果比较混乱

然后点击button结果是

在我们的预期中,它应该在此处显示 child2。那么为什么会这样呢?

【问题讨论】:

    标签: javascript typescript vue.js


    【解决方案1】:

    您的第一次点击会创建不存在的 show-property,因为您没有正确创建 data()

    我不会确切地推测原因,但我认为可能存在一些有趣的布尔转换,并且该属性可能不是反应性的,因为它不在数据中。无论哪种方式,只需创建它,它就会按您的预期工作:

    export default class App extends Vue {
      data(){ 
         return {
           show: false
         }
      },
      click() {
        this.show = !this.show;
      }
    }
    

    【讨论】:

      【解决方案2】:

      谢谢!!

      当我向两个子组件添加不同的键时,我解决了这个问题

      <Child v-if="!show" childId="child1" key="hello1" style="color:#f00;" />
      <Child v-if="show" childId="child2" key="hello2" style="color:#f0f;" />
      

      我认为原因是Vue的diff算法,Vue认为这两个组件是同一个组件

      【讨论】:

        【解决方案3】:

        因为当您使用v-if 时,它将使用单个相同的Child 组件。 this.msg 只会在 constructor 中更改一次。 childId props 更改时msg 不会更改,因此您需要Watch。当childId改变时,再更新msg

        Child.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>
        
        

        【讨论】:

          猜你喜欢
          • 2021-12-11
          • 1970-01-01
          • 2018-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-29
          • 1970-01-01
          相关资源
          最近更新 更多